E4X添加CDATA内容

时间:2009-08-06 14:57:52

标签: actionscript-3 e4x cdata

基本上我需要使用变量定义节点名称及其CDATA内容。

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

天真地认为这样可行:

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

输出:

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

在为FP9设计的以前版本的脚本中,我使用以下方法绕过了问题:

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

但这在FP10中似乎不起作用,我觉得这种方法无论如何都会以某种方式折旧。

任何一个优雅的解决方案吗?

6 个答案:

答案 0 :(得分:7)

怎么样:

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

输出:

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

我承认,这不是CDATA,但我没有看到问题......解析需要更多时间,但OTOH,正确逃避比CDATA更强大......

XMLNode的版本使用flash.xml包,这是为了向后兼容AS2 ...甚至没有注意到,它在FP10下消失了...但是,你可以使用它

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

作为替代,然后像使用flash.xml一样使用appendChild ...

或者你可以使用e4x风格,如果你把它包装在一个函数

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

然后

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

但就个人而言,我认为基于文本和相对较短的字符串应该被转义,而不是包裹在CDATA ...


<强>更新 我不明白你的观点

  

"&lt;""<"

非常不同

这就是整个事情 ......:D ... "<"将在解析过程中被解释,而"&lt;"只会被重新转换为"<"在解析XML之后,你将完全与之前相同的字符串...

这是我的代码:

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 + "]]>");
        }
    }
}

在flash player 10上完美适合我,使用flex sdk 4编译...手头没有flash IDE,但是当涉及到纯ActionScript结果几乎绝对相同时,它应该可以工作(你可以使用它作为你的文档类,如果你想,或只是实例化它... ...

顺便说一句。第一个跟踪显示,第二个示例有效,这也很明显,因为new XML(<String>)使用本地XML解析器从给定字符串创建XML ...

以上是上面生成的内容:

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

对我来说非常好......:)


格尔茨

back2dos

答案 1 :(得分:7)

上面的cdata函数需要如下所示,注意最后一个“&gt;”在代码中转义。否则会出现编译错误。

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

答案 2 :(得分:2)

谢谢,cdata函数非常有用。我写了一个新的。

function newNode(nodeName:String,nodeValue:String):XML{
    return new XML(<{nodeName}>{cdata(nodeValue)}</{nodeName}>);
}

答案 3 :(得分:2)

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

工作正常:))

答案 4 :(得分:1)

这是另一种解决方案

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() );
}

答案 5 :(得分:1)

这是我的解决方案,不使用功能:

var nodeName:String = "tag";
var nodeValue:String = "<non-escaped-content>";
var xml:XML = <doc><{nodeName}>{new XML("<![CDATA[" + nodeValue + "]]>")}</{nodeName}></doc>;

如果您需要替换现有节点内容并保留节点属性,可以使用:

var newNodeValue:String = "<non-escaped-content>";
var xml:XML = <doc><tag attribute="true">This is node content</tag></doc>;

xml.tag[0].setChildren(new XMLList());
xml.tag[0].appendChild(new XML("<![CDATA[" + newNodeValue + "]]>"));