views:

739

answers:

3

I am trying to get the child XML tag names in my AS3 program. For example, I have a file with information like this:

<LocationInfo>
   <City>New York City</City>
   <State>NY</State>
   <Zip>10098</Zip>
</LocationInfo>

I load the file into an ArrayCollection and can access each item I need by name such as ["City"] // Returns New York

Instead of getting the value, what I am trying to do is get the tag name such as State or Zip instead of NY or 10098.

A: 

Each LocationInfo tag becomes an entry in your ArrayCollection. Each entry is a dynamic object, so what you're really asking is how to get the property names from a dynamic object. This has already been answered, although they asked it a different way. Here's a link to the original page:

http://stackoverflow.com/questions/372317/how-can-i-get-list-of-properties-in-an-object-in-actionscript

And here's the answer that seemed the most straightforward:

var obj:Object; // I'm assuming this is your object

for(var id:String in obj) {
  var value:Object = obj[id];

  trace(id + " = " + value);
}
Phil Hayward
+1  A: 

You can use the localName property to get the element name of an XMLNode.

Something like:

var xml : XML = <LocationInfo>...</LocationInfo>;

foreach(var child : XMLNode in xml.LocationInfo.childNodes)
{
    trace(child.localName + " = " + child.nodeValue);
}
Richard Szalay
A: 

When dealing with XML, you're almost always better off using an XMLListCollection. For the most part, you wont's ACTUALLY need the additional functionality of an ArrayCollection and the XMLListCollection will certainly make things a lot easier. Further, ArrayCollections don't always serialize things correctly. I can't give you a specific circumstance, but I do know that I have had to refactor because the XML wasn't properly stored. Finally, XMLListCollection.toXMLString() will give you a far better view of the data's state than ArrayCollection.toString ever could.

With an XMLListCollection, what you're looking for would be done in one of the following:

var coll:XMLListCollection = <xml-here/>

// Iterate through all of the children nodes
for( var i:int = 0; i < coll.children().length(); i++ )
{
    var currentNode:XML = coll.children()[ i ];
    // Notice the QName class?  It is used with XML.
    // It IS NOT a String, and if you forget to cast them, then
    // currentNode.localName() will NEVER be "city", even though it may
    // trace that way.
    var name:QName      = currentNode.name(); // url.to.namespace::city
    var locName:QName   = currentNode.localName() // City
}

// get all city nodes in the current parent element
var currCities:XMLList = currentParentNode.cities; // currentParentNode can be 
// an XMLList, an XML object, an XMLListAdapter, or an XMLListCollection.
// This means that you can do something like coll.cities.cities, if there are
// children nodes like that.
for( i = 0; i < cities.length(); i++ )
{
    var currentCity:XML = cities[ i ];
}

// get all city nodes in all descendant nodes.
var cities:XMLList = currentParentNode.descendants( 
                         new QName( "url.to.namespace", "City" ) 
                     );
for( i = 0; i < cities.length(); i++ )
{
    var currentCity:XML = cities[ i ];
}

If you really MUST use ArrayCollection, then you can use the for... in syntax to achieve what you want:

// This is one of the few times I recommend anonymous typing.  When dealing with
// XML (which likely has already been turned into a String anyway, but be safe )
// anonymous syntax can give you better results.

// it = iterant, I use this to contrast with i for my sanity.
for(var it:* in coll) 
{
    trace(it,"=",coll[ it ]);
}
Christopher W. Allen-Poole