E4X Добавить CDATA контент - PullRequest
       15

E4X Добавить CDATA контент

9 голосов
/ 06 августа 2009

В основном мне нужно определить имя узла и его содержимое 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 ]

7 голосов
/ 28 апреля 2010

Вышеприведенная функция cdata должна выглядеть следующим образом, обратите внимание, что последний «>» экранирован в коде. В противном случае есть ошибки компиляции.

private function cdata(data:String):XML
{
    return new XML("<![CDATA[" + data + "]]\>");                
}
7 голосов
/ 06 августа 2009

как насчет этого:

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

отлично работает для меня на Flash Player 10, скомпилированном с Flex SDK 4 ... У меня нет Flash IDE под рукой, но когда дело доходит до чистого ActionScript, результаты почти наверняка совпадают, поэтому он должен работать (вы можете использовать его в качестве класса документа, если хотите, или просто создать его экземпляр) ...

кстати. первая трассировка показывает, что работает второй пример, что также вполне очевидно, поскольку new XML(<String>) использует собственный синтаксический анализатор XML для создания XML из заданной строки ...

вот что генерирует вышесказанное:

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

работает довольно хорошо для меня ...:)


Greetz

back2dos

2 голосов
/ 28 ноября 2011
private function cdata(data:String, nodeName:String):XML{
    return new XML( "<"+nodeName+"><![CDATA[" + data + "]]\></"+nodeName+">");
}

отлично работает:)

2 голосов
/ 28 апреля 2011

Спасибо, функция cdata очень полезна. Я написал только новый.

function newNode(nodeName:String,nodeValue:String):XML{
    return new XML(<{nodeName}>{cdata(nodeValue)}</{nodeName}>);
}
1 голос
/ 17 июня 2015

Вот мое решение без использования функций:

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 + "]]>"));
1 голос
/ 13 декабря 2012

Вот еще одно решение

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