2009-08-06 10 views
9

Fondamentalement, j'ai besoin de définir un nom de noeud et son contenu CDATA en utilisant des variables.E4X Ajouter contenu CDATA

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

Naïvement je pensais que cela fonctionnerait:

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

Sorties:

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

Dans une version précédente du script conçu pour FP9 j'ai contourné le problème en utilisant :

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

mais cela ne semble pas fonctionner dans FP10, et j'ai le sentiment que la méthode est en quelque sorte dépréciée.

Quelqu'un d'une solution élégante pour cela?

+0

réponse mise à jour ... greetz – back2dos

Répondre

6

que diriez-vous:

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

sorties:

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

je l'avoue, ce n'est pas CDATA, mais je ne vois pas de problème ... l'analyse syntaxique nécessite un peu plus de temps, mais OTOH, l'échappement correct beaucoup plus robuste que CDATA ...

la version avec XMLNode utilise le paquet flash.xml, qui est pour rétrocompatibilité avec AS2 ... n'a même pas remarqué, il avait disparu sous FP10 ... Cependant, vous pouvez utiliser cette

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

en remplacement, puis utiliser appendChild comme vous le feriez avec flash.xml .. .

Sinon, vous pouvez utiliser le style e4x, si vous l'envelopper dans une fonction

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

puis

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

mais personnellement, je pense que les chaînes, qui sont à la fois mode texte et relativement court, devraient être échappés, plutôt enveloppé dans CDATA ...


mise à jour: Je ne comprends pas votre point ici

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

qui est ce que la chose est sur ...: D ... "<" serait interprété lors de l'analyse syntaxique, alors que "&lt;" est juste r converti en "<", donc après avoir analysé le XML, vous aurez exactement la même chaîne que précédemment ...

ceci est mon code:

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

fonctionne parfaitement pour moi sur flash player 10, compilé avec sdk flex 4 ... ne disposent pas d'un IDE flash à portée de main, mais quand il s'agit de pur ActionScript les résultats sont presque certainement les mêmes, donc cela devrait fonctionner (vous pouvez l'utiliser comme votre classe de document, si vous voulez, ou simplement l'instancier) ...

btw. la première trace montre que le second exemple fonctionne, ce qui est tout à fait évident, puisque new XML(<String>) utilise l'analyseur XML natif pour créer une XML de la chaîne donnée ...

ici est ce que le ci-dessus génère:

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

fonctionne très bien pour moi ... :)


greetz

retour 2dos

+0

Hey, merci. La raison pour laquelle je veux CDATA est que la méthode est utilisée pour enregistrer des chaînes incluant XML, où un "<" est très différent d'un "<" bien sûr ... Malheureusement la deuxième solution va convertir les tags du CDATA en "< [CDATA []] > "ignorer toute la signification du CDATA() :(Avez-vous réellement fait fonctionner la 3ème solution? Cela fonctionnait dans le FP9 mais me donnait une erreur d'exécution dans FP10? –

+0

Je ne reçois pas la cdata fonction auxiliaire à compiler dans Flex SDK 3.X quoi que ce soit – taudep

+0

@taudep: quelles erreurs obtenez-vous? – back2dos

7

La fonction cdata ci-dessus doit ressembler à ceci, notez que le dernier ">" est échappé dans le code. Sinon, il y a des erreurs de compilation.

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

cette méthode fonctionne bien pour tous les cas, mais que faire si mon data est ']]>' Je reçois une erreur "Le balisage dans le document qui suit l'élément racine doit être bien formé." lors de la conversion en xml. Y a-t-il un autre moyen de le réparer? –

2

Merci, la fonction cdata est très utile. J'ai écrit juste un nouveau.

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

beau travail :)

1

Voici une autre solution

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

Voici ma solution sans l'aide de fonctions:

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

Si vous devez remplacer les noeuds existants contenu et garder noeud attri Butes que vous pouvez utiliser:

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