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[<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>
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;
|