2009-08-06 4 views
9

В основном мне нужно определить имя узла и его содержимое CDATA с использованием переменных.E4X Добавить содержимое 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, и у меня такое чувство, что метод каким-то образом обесценился.

Любое элегантное решение для этого?

+0

ответить обновлено ... greetz – back2dos

ответ

6

как об этом:

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;" is very different than a "<"

это то, что все это о ...: D ... "<" будет интерпретироваться во время синтаксического анализа, в то время как "&lt;" только г econverted до "<", поэтому после разбора 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 + "]]>"); 
     } 
    } 
} 

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

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

вот что Вышеприведенное:

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

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


Greetz

назад 2dos

+0

Эй, спасибо. Причина, по которой я хочу CDATA, заключается в том, что метод используется для записи строк, включая XML, где «<» сильно отличается от «<», конечно ... К сожалению, второе решение преобразует теги CDATA в «< [CDATA []] > «игнорируя все значение CDATA() :(Вы действительно сделали третье решение? Это использовалось для работы в FP9, но дает мне ошибку времени выполнения в FP10? –

+0

Я не получаю cdata вспомогательная функция для компиляции в Flex SDK 3.X. – taudep

+0

@taudep: какие ошибки вы получаете? – back2dos

7

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

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

этот метод работает хорошо для всех случаев, но что, если мой data is ']]> «Я получаю ошибку». Разметка в документе, следующей за корневым элементом, должна быть хорошо сформирована. »при преобразовании в xml. есть ли другой способ его исправить? –

2

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

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

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

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

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

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

Если вам нужно заменить существующие узлы содержимого и сохранить узел attri butes Вы можете использовать:

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 + "]]>")); 
Смежные вопросы