1

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)

Jad
  • 76
  • 8

1 Answers1

2

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
Dave Newton
  • 158,873
  • 26
  • 254
  • 302
  • how could I call the action attribute then? – Jad Apr 14 '15 at 16:09
  • @Jad ... How I told you to in the answer? – Dave Newton Apr 14 '15 at 16:21
  • oh okay sorry. This still gives undefined local variable or method 'action' for #{classname} (NameError) – Jad Apr 14 '15 at 16:26
  • @Jad That is not possible; `action` is an immediate string in the code in my answer. – Dave Newton Apr 14 '15 at 16:27
  • How is that not possible? Maybe I am not accessing the attribute properly? – Jad Apr 14 '15 at 16:30
  • Nevermind. It seems I had a problem elsewhere. Now, this doesn't even give the value of action. It gives nothing. No errors show. – Jad Apr 14 '15 at 16:33
  • @Jad Because there's no `action` attribute at the root of the document. I'm not sure if you're being serious here or not; I'm amending my answer to pretend like it's a tutorial. I'd seriously consider actually doing a REXML tutorial, though, it seems like you're trying to skip a few steps. – Dave Newton Apr 14 '15 at 16:45