4

The following is example of reading XML with ActionScript 3

var xml:XML = 
    <content>
        <a>Hello A</a>
        <b>Hello B</b>
        <c>
            <c1>Child C1</c1>
            <c2>Child C2</c2>
        </c>
    </content>;


trace(xml.a); // OP: Hello A
trace(xml.c.c1); // OP: Child C1
trace(xml.d); // OP: (nothing)
trace(xml.b);; // OP: Hello B

I don't see the xml.d outputting an empty string as expected behavior? Is this normal? What is the reasoning for this?

To me, I 'feel' like I should be doing this:

if(xml.d) trace(xml.d);

Is it ok to rely on the empty string behavior? IE do I need to check for a node's existence??

Chris
  • 54,599
  • 30
  • 149
  • 186

3 Answers3

4

xml.d is XMLList. Since node doesn't exist, this list will be empty.
You can test node existence with xml.d.length() (gives count of nodes d) or xml.d[0] (gives first node d, will be null in this case).

alxx
  • 9,897
  • 4
  • 26
  • 41
  • Now this is the answer I was looking for. I wasn't clicking that xml.d (or any variation on this, such as xml.d.d.d.) will return an XMLList. In saying this, XML must be a dynamic class as because otherwise it would throw an error 'd is not a property or method of xml' but I still don't see how it's 'typing' it's dynamic variables. For example if I created a class, there is no way I know of that I could make it so someone could write the following: var myClass:MyClass = new MyClass(); myClass.a.f.g and g is typed as an xml list. – Chris May 05 '11 at 07:46
  • XML (and XMLList) is not only dynamic class, it is even *magical* in some way. `xml.d` is in fact *xml selector* in simple form. Selectors always return XMLList, and xml.d.d.d is just a chain of calls. You can even make something similar by inheriting from Proxy class, but this is out of scope of question. – alxx May 05 '11 at 08:31
  • I was actually going to say that it must be 'special' in someway, because it is far from standard behavior. Excellent answer overall though, and great follow up. Thanks – Chris May 05 '11 at 08:38
0

the only Time I have ever had issues with empty child nodes is if i was trying to assess children of the empty node. So yeah in that case you need to test for empty string.

if(xml.d != "" ) trace(xml.d);

You might want to also read up on e4x

The_asMan
  • 6,364
  • 4
  • 23
  • 34
  • IMO, `xml.d != ""` is always true, since XMLList is never equal to String. If you cast xml.d to String, that would be different case. – alxx May 05 '11 at 17:38
  • Did you even test what I posted? If the node does not exist xml.d will return an empty string which will make it false. If the node exists it will return the xml node making it true. – The_asMan May 05 '11 at 18:59
  • fyi xml.c will convert to a string. so var str:String = xml.c is acceptable. – The_asMan May 05 '11 at 19:19
  • I did test. `xml.d != ""` is always true, whether node exists or not. XMLList can be compared with String only after converted/casted to String. – alxx May 06 '11 at 13:12
  • Then you need to retest because it is NOT always true – The_asMan May 06 '11 at 17:10
  • And the string conversion is automatic – The_asMan May 06 '11 at 17:11
0

If you try to access properties or methods of a non existent node, the AVM will throw an error. You should wrap any code that might fail for a known reason in a try{} catch(){}.

here's a good explanation: http://www.kirupa.com/forum/showthread.php?p=1957523

greggreg
  • 11,945
  • 6
  • 37
  • 52
  • Thanks for the answer, try/catch blocks aren't appropriate in this case as the AVM doesn't throw an error. This is the documented behavior of the XML class – Chris May 05 '11 at 07:40