0

I have a problem with retrieving attribute values via E4x in javascript.

Suppose a list of XML nodes like the following as the XMLObject:

<node att1="value1" att2="value2" att3="value3" att4="value4">
    <nodeChild><!CDATA[/* ... */]></nodeChild>
    /* more node childs */
</node>

I properly accessed the nodes (in a loop) and its attribute nodes using the attributes() method:

var attributes = node[n].attributes() ;
    for(var n = 0 ; n < attributes.length() ; n++) {
        var name = attributes[n].name() ;
        var value = attributes[n].toString() ;
        //.. handle the values
    }

Now, for one, names and values are not adequately returned value(n) returns the value of name(n+1), i.e. the value of att1 will be value2 ; if I set var value = attributes[ (n+1) ].toString() the values are returned correctly but the first value will return undefined.

Possible I'm just dense on this one. So, does anyone have any pointers to what I am missing?

TIA,

FK

FK82
  • 4,907
  • 4
  • 29
  • 42
  • I'm not sure about what's going on here, but is "name" really a function, and not just a simple string? – Pointy Jun 23 '10 at 13:46
  • Yes, it is—E4X is weird and behaves differently to how you'd expect a normal DOM or JS object to. The example works fine for me, except for it not being clear where the `n` comes from in `node[n].attributes()`. Of course if `//.. handle the values` alters the attributes there's potentially a destructive iteration problem. – bobince Jun 23 '10 at 15:03
  • The above is pseudo-code. My use case (JS xml parsing function in Rhino used in a Java class) is far more complex, so I abstracted the problem. I should have stated that. Sorry. – FK82 Jun 24 '10 at 04:13
  • @ Pointy: `name()` is a method of the XMLObject in E4X that yields the node name. In this case the attribute name. – FK82 Jun 24 '10 at 04:15
  • @ bobince: I'm not changing the values. If there is no obvious error in the loop syntax, the error must be somewhere else in the code. I'll go through it and---in case---will post additional code. Thanks. – FK82 Jun 24 '10 at 04:25

1 Answers1

4

Your code works for me, apart from these gotchas which I'm sure don't exist in your actual XML since you are able to parse and iterate through them:

  1. CDATA declaration wasn't valid. Changed to <![CDATA[..]]>
  2. /* more node childs */ makes the XML invalid
  3. Replaced n with 0, or could do without it altogether

Here's the exact code I used to iterate the node attributes.

var node = <node att1="value1" att2="value2" att3="value3" att4="value4">
    <nodeChild><![CDATA[/* ... */]]></nodeChild>
</node>;

var attributes = node[0].attributes() ;
for(var n = 0 ; n < attributes.length() ; n++) {
    var name = attributes[n].name() ;
    var value = attributes[n].toString() ;
    console.log("%s = %s", name, value);    
}

// log output
// att1 = value1
// att2 = value2
// att3 = value3
// att4 = value4

Note that E4X provides a more succinct way of writing the above (combined with for each in introduced in JavaScript 1.6):

for each(var attribute in node.@*) {
    var name = attribute.name();
    var value = attribute.toString();
}

Since you are referring to an XML object, there is no need to reference the root element by index as in node[0]. You can simply write node.

Anurag
  • 140,337
  • 36
  • 221
  • 257
  • Thanks for your answer. It's pseudo code, my actual xml is valid. I believe the `for each in` syntax isn't available in `Rhino` (as it does not yet include JavaScript 1.6). I'm using E4X in a JS function called from a Rhino context. Did you use my `for loop` in your test? – FK82 Jun 24 '10 at 04:20
  • I didn't test it on Rhino, but I did test your for loop version with the changes I mentioned - basically the exact same code I've pasted above, on Firefox. – Anurag Jun 24 '10 at 04:32
  • Alright, the error must be somewhere else then. Good thing to know that I don't fail at writing basic syntax. :-) Thanks. – FK82 Jun 24 '10 at 05:33