actionscript-3e4xcdata

E4X Add CDATA content


Basically I need to define a node name and its CDATA content using variables.

var nodeName:String = "tag";
var nodeValue:String = "<non-escaped-content>";

Naively I thought this would work :

var xml:XML = <doc><{nodeName}><![CDATA[{nodeValue}]]></{nodeName}>

Outputs :

<doc><tag><![CDATA[{nodeValue}]]></tag></doc>

In a previous version of the script designed for FP9 I bypassed the problem by using :

new XMLNode( XMLNodeType.XMLNodeType.CDATA_NODE, nodeValue ); // ...

but this doesn't seem to work in FP10, and I have the feeling the method is somehow depreciated anyway.

Anyone an elegant solution for this ?


Solution

  • how about this:

    var xml:XML = <doc><{nodeName}>{nodeValue}</{nodeName}></doc>
    trace(xml.toXMLString());
    

    outputs:

    <doc>
      <tag>&lt;non-escaped-content&gt;</tag>
    </doc>
    

    i admit, this is not CDATA, but i don't see a problem ... parsing requires a little more time, but OTOH, correct escaping much more robust than CDATA ...

    the version with XMLNode uses the flash.xml package, which is for backwards compatibility with AS2 ... didn't even notice, it was gone under FP10 ... however, you could use this

    var x:XML = new XML("<![CDATA[" + nodeValue + "]]>");
    

    as a replacement and then use appendChild as you would with flash.xml ...

    alternatively you could use it e4x style, if you wrap it in a function

    function cdata(data:String):XML {
        return = new XML("<![CDATA[" + data + "]]>");
    }
    

    and then

    var xml:XML = <doc><{nodeName}>{cdata(nodeValue)}</{nodeName}></doc>
    

    but personally, i think that strings, that are both text based and relatively short, should be escaped, rather then wrapped in CDATA ...


    update: i don't get your point here

    "&lt;" is very different than a "<"

    that's what the whole thing is about ... :D ... "<" would be interpreted during parsing, whereas "&lt;" is just reconverted to "<", so after parsing the XML, you will have exactly the same string as before ...

    this is my code:

    package {
        import flash.display.MovieClip;
        public class Main extends MovieClip {       
            public function Main():void {
                var nodeName:String = "tag";
                var nodeValue:String = "<non-escaped-content>";
                var xml:XML = <doc><{nodeName}>{cdata(nodeValue)}</{nodeName}></doc>;
                trace(cdata("test").toXMLString());
                trace(xml.toXMLString());
            }
            private function cdata(data:String):XML {
                return new XML("<![CDATA[" + data + "]]>");
            }
        }
    }
    

    works perfectly for me on flash player 10, compiled with flex sdk 4 ... don't have a flash IDE at hand, but when it comes to pure ActionScript results are almost definitely the same, so it should work (you can use that as your document class, if you want to, or simply instantiate it) ...

    btw. the first trace shows, that the second example works, which is also quite obvious, since new XML(<String>) uses the native XML parser to create an XML from the given string ...

    here is what the above generates:

    <![CDATA[test]]>
    <doc>
      <tag><![CDATA[<non-escaped-content>]]></tag>
    </doc>
    

    works quite good for me ... :)


    greetz

    back2dos