Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 ?

like image 796
Theo.T Avatar asked Aug 06 '09 14:08

Theo.T


5 Answers

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

like image 64
back2dos Avatar answered Nov 18 '22 11:11

back2dos


The above cdata function needs to look like the following, notice the last ">" is escaped in code. Otherwise there's compile errors.

private function cdata(data:String):XML
{
    return new XML("<![CDATA[" + data + "]]\>");                
}
like image 27
taudep Avatar answered Nov 18 '22 11:11

taudep


Thanks, cdata function is very useful. I wrote just new one.

function newNode(nodeName:String,nodeValue:String):XML{
    return new XML(<{nodeName}>{cdata(nodeValue)}</{nodeName}>);
}
like image 38
emrahsifoglu Avatar answered Nov 18 '22 12:11

emrahsifoglu


private function cdata(data:String, nodeName:String):XML{
    return new XML( "<"+nodeName+"><![CDATA[" + data + "]]\></"+nodeName+">");
}

work fine :)

like image 36
eldervaz Avatar answered Nov 18 '22 12:11

eldervaz


Here is another solution

public static function getCDATANode(data:String, tagName:String):void
{
        var node:XML  = new XML(  "<" + tagName + "/>" );
        var cdata:XML = new XML("<![CDATA[" + data + " ]]>");
        node.appendChild(cdata);

        trace("getCDATANode: ", node.toXMLString() );
}
like image 1
Tahir Alvi Avatar answered Nov 18 '22 11:11

Tahir Alvi