2009-08-06 17 views
9

Zasadniczo potrzebuję zdefiniować nazwę węzła i jego zawartość CDATA przy użyciu zmiennych.E4X Dodaj zawartość CDATA

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

Naiwnie myślałem, że to będzie działać:

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

Wyjścia:

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

w poprzedniej wersji skryptu przeznaczonego do FP9 mogę ominąć ten problem za pomocą :

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

ale to nie działa w FP10, i mam wrażenie, że metoda jest w jakiś sposób amortyzowana.

Ktoś elegancki rozwiązanie dla tego?

+0

odpowiedź zaktualizowana ... greetz – back2dos

Odpowiedz

6

jak o tym:

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

wyjść:

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

Przyznaję, nie jest to CDATA, ale nie widzę problemu ... parsowanie wymaga trochę więcej czasu, ale OTOH, poprawne wydostanie się znacznie bardziej niezawodne niż CDATA ...

wersja z XMLNode używa pakietu flash.xml, który jest dla wsteczną kompatybilność z AS2 ... nawet nie zauważy, że zniknął pod FP10 ... jednak, można użyć tego

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

jako zamiennik a następnie użyć appendChild jak przy flash.xml .. .

alternatywnie można użyć go e4x styl, jeśli zawinąć go w funkcji

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

a następnie

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

ale osobiście uważam, że ciągi znaków, które są zarówno tekstowych i stosunkowo krótki, należy uciec, a następnie zawijane w CDATA ...


zmiana: ja nie rozumiem twój punkt widzenia tutaj

"&lt;" is very different than a "<"

to właśnie cała rzecz jest o ...: D ... "<" byłyby interpretowane podczas parsowania, natomiast "&lt;" tylko r econverted do "<", więc po analizie XML, będziesz mieć dokładnie taki sam ciąg jak wcześniej ...

to mój kod:

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

działa idealnie dla mnie na flash player 10, sporządzoną z Flex SDK 4 ... nie masz pod ręką lampy błyskowej IDE, ale jeśli chodzi o czystej ActionScript wyniki są prawie na pewno takie same, więc powinno działać (możesz użyć tego jako klasy dokumentu, jeśli chcesz, lub po prostu utworzyć instancję) ...

btw. Pierwszy ślad wskazuje, że drugi przykład działa, co jest dość oczywiste, ponieważ new XML(<String>) wykorzystuje natywne XML parser do stworzenia XML z danym ciągiem ...

tutaj jest to, co powyżej generuje:

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

działa całkiem dobre dla mnie ... :)


Greetz

powrotem 2dos

+0

Hej, dzięki. Powodem, dla którego chcę CDATA jest to, że metoda jest używana do rejestrowania ciągów, w tym XML, gdzie "<" różni się znacznie od "<" oczywiście ... Niestety drugie rozwiązanie zamieni tagi CDATA na "< [CDATA []] > "ignorowanie całego znaczenia CDATA() :(Czy rzeczywiście sprawdziło się trzecie rozwiązanie? To działało w FP9, ale powodowało błąd runtime w FP10? –

+0

Nie otrzymuję cdata funkcja pomocnika do kompilacji w programie Flex SDK 3.X.Wszystko: – taudep

+0

@taudep: jakie błędy otrzymujesz? – back2dos

7

Powyższa funkcja cdata musi wyglądać następująco, zauważ, że ostatnie ">" jest ukryte w kodzie. W przeciwnym razie wystąpią błędy kompilacji.

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

ta metoda działa dobrze dla wszystkich przypadków, ale co jeśli mój dane to "]]>" Pojawia się błąd "Znaczniki w dokumencie po elemencie głównym muszą być dobrze sformułowane." podczas konwersji do xml. czy jest jakiś inny sposób, aby to naprawić? –

2

Dzięki, funkcja cdata jest bardzo przydatna. Napisałem właśnie nowy.

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

praca w porządku :)

1

Oto kolejny rozwiązanie

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

Oto moje rozwiązanie bez użycia funkcji:

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

Jeśli trzeba zastąpić istniejące węzły zawartość i zachować węzeł attri buty, których możesz użyć:

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