E4X CDATA コンテンツの追加
-
11-09-2019 - |
質問
基本的に、変数を使用してノード名とその 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 では機能しないようです。いずれにしても、この方法はどういうわけか価値がなくなっているような気がします。
これに対するエレガントな解決策を知っている人はいますか?
解決
これはどう:
var xml:XML = <doc><{nodeName}>{nodeValue}</{nodeName}></doc>
trace(xml.toXMLString());
出力:
<doc>
<tag><non-escaped-content></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
...
アップデート:ここではあなたの言い分がわかりません
"<"
とは大きく異なります"<"
それがすべてのことなのです ...:D ... "<"
は解析中に解釈されますが、 "<"
に再変換されるだけです "<"
, したがって、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 に関して言えば、結果はほぼ間違いなく同じなので、動作するはずです (必要に応じて、それをドキュメント クラスとして使用することも、単にインスタンス化することもできます)。 。
ところで。最初のトレースは、2 番目の例が機能することを示しています。これも非常に明白です。 new XML(<String>)
ネイティブを使用します XML
を作成するパーサー XML
指定された文字列から ...
上記で生成されるものは次のとおりです。
<![CDATA[test]]>
<doc>
<tag><![CDATA[<non-escaped-content>]]></tag>
</doc>
私にとってはかなりうまくいきます...:)
挨拶します
バックツードス
他のヒント
上記の cdata 関数は次のようにする必要があります。コードでは最後の ">" がエスケープされていることに注意してください。そうしないとコンパイルエラーが発生します。
private function cdata(data:String):XML
{
return new XML("<![CDATA[" + data + "]]\>");
}
ありがとう、cdata関数はとても便利です。新しく書きました。
function newNode(nodeName:String,nodeValue:String):XML{
return new XML(<{nodeName}>{cdata(nodeValue)}</{nodeName}>);
}
private function cdata(data:String, nodeName:String):XML{
return new XML( "<"+nodeName+"><![CDATA[" + data + "]]\></"+nodeName+">");
}
正常に動作します:)
ここに別の解決策があります
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() );
}
関数を使用しない私の解決策は次のとおりです。
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 + "]]>"));