views:

1240

answers:

2

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 ?

A: 

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 ... :)


back2dos
Hey, thanks. The reason why I want CDATA is that the method is used to log strings including XML, where a "<" is very different than a "<" of course ... Unfortunately the second solution will convert the tags of the CDATA to "<[CDATA[ ]]>" ignoring the whole signification of the CDATA () :( Did you actually make the 3rd solution work ? This used to work in FP9 but gives me a runtime error in FP10 ?
Theo.T
I'm not getting the cdata helper function to compile in Flex SDK 3.X anything.
taudep
@taudep: what errors are you getting?
back2dos
@back2dos. I'm getting mxml compiler error: "Parse error at '\");\n\t\t}\n\n\n\t\....return new XML("<![CDATA[" + data + "]]>");"I added a compilable implementation of the cdata function below.
taudep
+1  A: 

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 + "]]\>");                
}
taudep
O.O ... that's crazy! but ok, if it works, it works :)
back2dos