E4X : Retrieving a sibling of a node

One of the advantages of XML is that you can easily represent related information with a parent / child relationship. This makes it easy to parse, and understand. However, some XML formats (such as Apple’s plist format), represent relationships via proximity on the same level.

For example, one way to represent name / value pairs in XML could be:

[code]Interpol[/code]However, the plist format does this with key / value structure, so the above would be represented in XML as:[code]ArtistInterpol[/code]The relationship between key / value is dependent on proximity, and not hierarchy as in the first example. I won’t go into why Apple did this (I don’t know) or whether it is good or bad, but it does present some difficulties in parsing.In order to reliably parse this, you must first retrieve the key node with the appropriate value, and then get the next node, which will contain the value for the preceding key. Thus, you must be able to retrieve the key node’s next sibling, in relation to its parent.Here is an example:[code]package {import flash.display.Sprite;public class XMLTest extends Sprite{public function XMLTest(){var xml:XML =ArtistInterpolTrack Number7ArtistBloc PartyTrack Number3var temp:XML;var artistName:String;//loop through all of the songsfor each (var song:XML in xml.songs.song){//get the node for key in the first song that has the Artist valuetemp = song.key.(text() == “Artist”)[0];//get the next node (i.e. the key nodes next sibling). and save it as a StirngartistName = String(temp.parent().children()[temp.childIndex() + 1]);trace(artistName);}}}}[/code]The important part is this line:[code]temp.parent().children()[temp.childIndex() + 1][/code]Basically, this gets the temp node’s next sibling. To get the previous sibling, just subtract 1 like so:[code]temp.parent().children()[temp.childIndex() – 1][/code]Anyways, took me some trial and error to figure out. I added some APIs to the XMLUtil class in corelib, that encapsulate this. They are already included in source, and will be compiled into the SWC at the next release. You can view the class and APIs here. You can find more information on the corelib API here.

One Response to E4X : Retrieving a sibling of a node

  1. Maybe Apple was trying to implement a generic parser so that they can add key/value pairs to the XML file at a later date that were not yet known. I agree that their method does pose some parsing difficulties. A method I’ve used in the past when I had XML that was not yet known was to make the key and value attributes of the same node. This way I could keep a strict relationship between the two. A third attribute was for type casting. This is what my XML file might have looked like:[code][/code]My generic parser would go through all of the default nodes and add each one as a key/value pair to a LoadVars variable using the type attribute to properly cast the value. I was using Flash 7 so LoadVars worked nicely as a Dictionary. Then, as I started to tweak the XML file with additional defaults, I never had to go back to change the parser.