June 26, 2009
E4x and as3 gotcha
I love E4X in AS3. It's powerful and fairly simple. If you haven't worked with it yet, check out Roger Braunstein's excellent tutorial. But I was recently annoyed by this gotcha when doing some xml combining. Let's say you have this:
-
<xml>
-
<people>
-
<person id="123">
-
<name>John</name>
-
</person>
-
<person>
-
<name>David</name>
-
</person>
-
</people>
-
</xml>
Let's parse with E4X:
-
// #1
-
trace( xml.people.person.length() );
-
// 2
-
-
// #2
-
// no animals, but e4x still returns an XMLList
-
trace( xml.people.animal.length() );
-
// 0
-
-
// #3
-
// no animals, so no further children, but still returns XMList
-
trace( xml.people.animal.fur.color.length() );
-
// 0
-
-
// #4
-
// gotcha
-
trace( xml.people.person.( "123" == @id ) );
-
// thows: ReferenceError: Error #1065: Variable @id is not defined.
The first 3 examples work great. Even though there are no <animal> nodes, E4X still returns an XMLList. Even looking for more siblings under nodes that don't exist works great - it always returns an empty (but valid) XMLList. Always returning an XMLList makes it easy to work with because you can always for-each over the result.
What I don't understand is the 4th example. It fails because not every <person> node has an id attribute. But so what? If you look at the 2nd and 3rd examples, not every <people> node has an <animal> node. So why don't we get the same result - an empty XMLList?
Turns out that there is an easy solution/work-around, that Roger mentions in his tutorial:
-
// will error if every person node does not have an id attribute
-
trace( xml.people.person.( "123" == @id ) );
-
-
// use this
-
trace( xml.people.person.( attribute( "id" ) == "123" ).length() );
-
// 1
A bit wtf, but at least it works like the other examples.
Comments
Leave a reply-
I part of it is common sense. I for one would never do
xml.people.person.( "123" == @id ), if anything the normal approach would have been xml.people.person.(@id == "123"). Nonetheless, it is worth mentioning. Thanks.