rubyrexml

Ruby 2.2 Using REXML


I have followed much tutorials about Ruby 2.2 and REXML. This is an example of my xml:

<msg user='Karim'><body action='ChkUsername' r='0'><ver v='153' /></body></msg>

And this is what I currently have as code:

        xml =    "<msg user='Karim'><body action='ChkUsername' r='0'><ver v='153' /></body></msg>"
        doc = Document.new xml
        puts doc.root.attributes[action]

That won't work. An error pops out. undefined local variable or method 'action' for #{classname} (NameError)


Solution

  • You can't randomly assume variables exist. The token action will be interpreted as a reference (e.g., a variable or method call) since it's not a string or symbol. You don't have that variable or method, so you get an error telling you precisely what's wrong.

    puts doc.root.attributes['action']
    

    The root of your document is the <msg> tag. The <msg> tag does not have an attribute action. It has a user attribute, accessible as you'd expect:

     > require 'rexml/document'
     > xml = "<msg user='Karim'><body action='ChkUsername' r='0'><ver v='153' /></body></msg>"
     > doc = REXML::Document.new(xml)
     > doc.root.attributes['user']
    => "Karim"
    

    The action attribute is nested further in the document, in the <body> element.

    There are a number of ways to interrogate a document (all covered in the tutorial, btw), e.g.,

     > doc.elements.each('//body') do |body|
     >   puts body.attributes['action']
     > end
    ChkUsername