Introduction to XML in Flash
       by senocular

Sending Formatted XML And/Or CDATA To The Server
In using ignoreWhite, Flash physically removes the extraneous white space between nodes from the XML document as its brought into Flash often ruining your formatting. If that XML is then sent back to the server, the white space remains removed and what you get is a long line of elements and text nodes that seem all to blend together.

Similarly, Flash converts CDATA sections in XML to simple text nodes within an XML instance. Flash reads CDATA fine when loaded but, like with the white space, in sending off the XML to the server, that CDATA is no longer CDATA and is instead a converted text node.

When Flash removes all your white space and converts CDATA to text nodes, you've just lost that readability. This is especially annoying when using other markup like HTML and more so when you want to look at that XML in some other context other than within Flash. After all, part of the advantage of having XML is that it's readable. What's more readable to you in the following examples?

<?xml version="1.0"?>
<gallery>
<title>Image Gallery A</title>
<author>senocular</author>
<page date="01/04/2005" name="photo05.html">
<![CDATA[<html>
<head>
<title>Photo #05</title>
</head>
<body>
<div align="center">
<p><b>Photograph 05 of 50</b></p>
<img src="images/photo05.jpg" alt="Photo #05" />
</div>
</body>
</html>]]>
</page>
<comments>Please add the date of posting.</comments>
</gallery>

or

<?xml version="1.0"?>
<gallery><title>Image Gallery A</title><author>senocular</author><page date="01/04/2005" name="photo05.html">
<![CDATA[&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Photo #05&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div align="center"&gt;
&lt;p&gt;&lt;b&gt;Photograph 05 of 50&lt;/b&gt;&lt;/p&gt;
&lt;img src="images/photo05.jpg" alt="Photo #05" /&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;]]>
</page><comments>Please add the date of posting.</comments></gallery>

You can get around this using the previously mentioned format function. The format function, in its original design, is used to create a multi-lined, indented string representation of XML despite it having been formatted otherwise (say, as a result of using ignoreWhite). Using this to generate XML that is to be sent to the server pretty much solves the ignoreWhite problem right there. You would most likely have to use a loadVars object to send the string, but that's not really a problem.

The CDATA still remains. But, similarly, this too can be solved using format. What format does is re-writes XML node for node so that it can be relayed in an alternative format, namely, a readable one. A small modification to this, and some manual editing of your XML instance, can make it so that format correctly converts text nodes back into CDATA sections.

Because all CDATA sections are initially converted into text nodes, there's no real way to identify a real text node from a previously defined-as-CDATA node. This is why the manual editing previously mentioned is required. Basically you'd just have to go through the XML and manually mark specific text nodes as being CDATA so that when format runs through all the nodes, it can check for this mark and appropriately change all the appropriate text nodes into CDATA. Here is the rewrite of format with the alteration in bold:

XMLNode.prototype.format = function(indent){
if (indent == undefined) indent = "";
var str = "";
var currNode = this.firstChild;
do{
if (currNode.hasChildNodes()){
str += indent + currNode.cloneNode(0).toString().slice(0,-2) + ">\n";
str += currNode.format(indent+"\t");
str += indent + "</" + currNode.nodeName + ">\n";
}else{
if (currNode.isCDATA) str += indent + "<![CDATA[" + currNode.nodeValue + "]]>\n";
else str += indent + currNode.toString() + "\n";
}
}while (currNode = currNode.nextSibling);
return str;
}

An additional if statement is added that checks for an isCDATA property within the current node in the iteration. If the value is true then a CDATA section is created using the node's nodeValue instead of it's toString() representation which gets rid of all the character entity references and uses the actual node's value which, being within the CDATA tag is acceptable.

Now its just a matter of going through and defining a true isCDATA property to all the text nodes you wish to formatted as CDATA sections.

my_xml.firstChild.firstChild.isCDATA = true;

 


 




SUPPORTERS:

kirupa.com's fast and reliable hosting provided by Media Temple.