10

基本上我需要使用变量定义节点名称及其 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 中不起作用,而且我觉得该方法无论如何都会贬值。

有人对此有一个优雅的解决方案吗?

4

6 回答 6

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

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

或者,如果将其包装在函数中,则可以使用 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 + "]]>");
        }
    }
}

在使用 flex sdk 4 编译的 flash player 10 上非常适合我……手头没有 flash IDE,但是对于纯 ActionScript 结果几乎肯定是相同的,所以它应该可以工作(你可以使用它作为您的文档类,如果您愿意,或者只是实例化它)...

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

这是上面生成的内容:

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

对我来说效果很好...... :)


问候

back2dos

于 2009-08-06T15:54:40.413 回答
7

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

private function cdata(data:String):XML
{
    return new XML("<![CDATA[" + data + "]]\>");                
}
于 2010-04-28T13:52:02.407 回答
2

谢谢,cdata 功能非常有用。我刚写了一个新的。

function newNode(nodeName:String,nodeValue:String):XML{
    return new XML(<{nodeName}>{cdata(nodeValue)}</{nodeName}>);
}
于 2011-04-28T08:30:51.853 回答
2
private function cdata(data:String, nodeName:String):XML{
    return new XML( "<"+nodeName+"><![CDATA[" + data + "]]\></"+nodeName+">");
}

工作正常:)

于 2011-11-28T02:47:00.337 回答
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() );
}
于 2012-12-13T08:03:43.417 回答
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 + "]]>"));
于 2015-06-17T13:22:19.013 回答