in

ASP.NET Weblogs

Tim Walters .NET Blog

Microsoft .NET, along with XML, XSL, XSD, SQL and other cool stuff

Accessing text in XML with Flash ActionScript - Why is it so hard?

Text content in XML

One of the more frequently asked questions regarding XML in Flash is related to the text content of XML nodes. Consider the following XML:

[xml]
<people>
 <person>
  <givenName>Timothy</givenName>
  <initial>J</initial>
  <surName>Walters</surName>
 </person>
</people>
[/xml]

To access the text in this XML, you will often see something like the following ActionScript:

[as]
// ... once XML has been loaded and parsed into xmlPeople:

// get reference to the person we want
xmlPerson = xmlPeople.firstChild.firstChild;

// assign text to our text boxes
txtGivenName.text = xmlPerson.childNodes[0].firstChild.nodeValue;
txtInitial.text = xmlPerson.childNodes[1].firstChild.nodeValue;
txtSurName.text = xmlPerson.childNodes[2].firstChild.nodeValue;
[/as]

NOTE: the above only works if you have used the "ignoreWhite" property with a value of true!

People often ask why they have to use ".firstChild.nodeValue", why can't they just use ".nodeValue" on the <givenName> node?

To answer this, first consider the following XML:

[xml]
<comments>
 <comment>
  <b>Tim says: </b>That's <i>interesting</i>...
 </comment>
</comments>
[/xml]

Although I wouldn't recommend using XML like that, it's entirely valid. It's referred to as "Mixed Content", where you've got XML tags (in this case the HTML <b> tag and <i> tag) mixed in with your text. It's most commonly used when you allow HTML in your data (although this too is something that must be done carefully, as the HTML has to be valid XML, but that's another topic).

The XML document has one child, the "<comments>" element. This element has one child, the "<comment>" element. This element has 4 child elements (or 5 if ignoreWhite isn't set to true). It's children are an element named "b" (which has a child node of type text), a text node (nodeType = 3), an element named "i" (which has a child node of type text), and another text node.

Lets draw a tree:

[tree]
node: name="comments", type=1
 node: name="comment", type=1
  node: name="b", type=1
   node: name=(null), type=3, value="Tim says: "
  node: name=(null), type=3, value="That's "
  node: name="i", type=1
   node: name=(null), type=3, value="interesting"
  node: name=(null), type=3, value="..."
[/tree]

In case you haven't worked it out yet, something that allowed you to get the text of the <comment> tag would return the string "That's ..." (it would take the two children and normalize them into a single string). You would lose the structure (and meaning) of your XML. Thus text is always created as a node of type text (nodeType=3) in the object heirarchy. This only seems odd when you have a single text node inside your element (like the first example).

To make life easier, I've written some extensions to the Flash MX XML object. One such extension is the ".innerText" method.

For those cases where you only want the text, you can use the ".innerText" method. If you examine the source you might notice that it actually checks all children and combines the innerText & nodeValue properties.

[as]
XMLNode.prototype.innerText = function()
{
 var strText = "";
 var xmlNode;
 for( var i=0; i<this.childNodes.length; i++ )
 {
  xmlNode = this.childNodes[i];
  switch(xmlNode.nodeType)
  {
   case 1: // elements
    strText += xmlNode.innerText();
    break;
   case 3: // text
    strText += xmlNode.nodeValue;
    break;
   default: // comments etc
    break;
  }
 }
 return strText;
};
[/as]

Published Jul 16 2003, 03:15 PM by XMLEvangelist
Filed under:

Comments

 

andreas said:

good stuff. helped me finally to get my head around how flash deals with xml. thanks a lot...

...andreas...
February 6, 2004 9:52 PM
 

Ruhre said:

XML in Flash is being like going to dentist for me, with its confusing syntax. This document helped me on a "childNodes[n].nodeValue" issue. Thanks.
February 16, 2004 9:05 AM
 

TrackBack said:

February 19, 2004 3:35 AM
 

TAZ said:

+++++WEB+++++
Longhorn flash mx pro
February 20, 2004 4:12 PM
 

Christian M. Cepel said:

Thank you.   You ended hours of frustration for me.

June 29, 2007 8:35 PM
 

Michael Weber said:

I would have never tried node.childNode.nodeValue if I hadn't found this site - thank you!

July 24, 2007 3:54 PM
 

Hamish said:

Thanks so much, this helped me heaps!!!!

April 13, 2008 7:34 PM
 

Justus said:

Thank you. Fixed my bug.

July 17, 2008 12:21 PM
 

Lama said:

Me helped it mouch, i have updated your code, becouse i needed to read nodeValue and write it in htmlText field with tags.

XMLNode.prototype.innerText = function() {

var strText = "";

var xmlNode;

for (var i = 0; i<this.childNodes.length; i++) {

xmlNode = this.childNodes[i];

if (xmlNode.nodeName) {

strText += "<"+xmlNode.nodeName;

for (attr in xmlNode.attributes) {

strText += " "+attr+" = '"+xmlNode.attributes[attr]+"'";

}

strText += " >";

}

//  

switch (xmlNode.nodeType) {

case 1 :// elements

strText += xmlNode.innerText();

break;

case 3 :// text

strText += xmlNode.nodeValue;

break;

default :// comments etc

break;

}

//

if (xmlNode.nodeName) {

strText += "</"+xmlNode.nodeName+">";

}

}

return strText;

};

thanx

August 5, 2008 12:31 PM

Leave a Comment

(required)  
(optional)
(required)  
Add