2009-08-06 33 views
9

Básicamente, necesito definir un nombre de nodo y su contenido CDATA usando variables.E4X Agregar contenido CDATA

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

Ingenuamente pensé que esto funcionaría:

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

Salidas:

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

En una versión anterior de la secuencia de comandos diseñado para FP9 que evitaron los problemas mediante el uso de :

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

pero esto no parece funcionar en FP10, y tengo la sensación de que el método de alguna manera se depreció de todos modos.

¿Alguien una solución elegante para esto?

+0

respuesta actualizada ... greetz – back2dos

Respuesta

6

¿qué tal esto:

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

salidas:

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

admito, esto no es CDATA, pero yo no veo un problema ... el análisis requiere un poco más de tiempo, pero OTOH, escape correcto mucho más robusto que CDATA ...

la versión con XMLNode usa el paquete flash.xml, que es para compatibilidad hacia atrás con AS2 ... ni se dio cuenta, ya no estaba bajo FP10 ... sin embargo, usted podría utilizar este

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

como un reemplazo y luego usar appendChild como lo haría con flash.xml .. .

otra posibilidad es utilizar el estilo que e4x, si lo envuelve en una función

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

y luego

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

pero personalmente, creo que las cadenas, que son texto basado y relativamente corto, deben ser escapados, en lugar envuelto en CDATA ...


actualización: no consigo su punto aquí

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

eso es lo que todo el asunto se trata de ...: D ... "<" sería interpretado durante el análisis, mientras que "&lt;" es sólo r econverted a "<", entonces después de analizar el XML, tendrá exactamente la misma cadena que antes ...

este es mi código:

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

funciona perfectamente para mí en el reproductor de flash de 10, compilado con SDK de Flex 4 ... no tienen un flash IDE a la mano, pero cuando se trata de pura ActionScript los resultados son casi definitivamente los mismos, por lo que debería funcionar (puede usar eso como su clase de documento, si lo desea, o simplemente crear una instancia) ...

btw. la primera traza muestra, que el segundo ejemplo funciona, que también es bastante obvio, ya que new XML(<String>) utiliza el analizador XML nativa para crear un XML de la cadena dada ...

aquí es lo que lo anterior genera:

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

funciona bastante bien para mí ... :)


Greetz

vuelta 2dos

+0

Hola, gracias. La razón por la que deseo CDATA es que el método se usa para registrar cadenas, incluido XML, donde "<" es muy diferente de "<", por supuesto ... Desafortunadamente, la segunda solución convertirá las etiquetas de CDATA en "< [CDATA []] > "ignorando todo el significado del CDATA() :(¿Hiciste realmente que funcionara la tercera solución? Esto solía funcionar en el FP9 pero me da un error de tiempo de ejecución en el FP10? –

+0

No obtengo el cdata función auxiliar para compilar en Flex SDK 3.X cualquier cosa. – taudep

+0

@taudep: ¿qué errores está obteniendo? – back2dos

7

La función cdata anterior debe tener el siguiente aspecto, observe que el último ">" está escapado en el código. De lo contrario, hay errores de compilación.

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

este método funciona bien para todos los casos, pero ¿y si mi data is ']]>' Estoy obteniendo un error "El marcado en el documento que sigue al elemento raíz debe estar bien formado" mientras convierte a xml. ¿Hay alguna otra forma de arreglarlo? –

2

Gracias, la función cdata es muy útil. Escribí uno nuevo.

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

trabajo bien :)

1

Aquí hay otra solución

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

Aquí está mi solución sin utilizar funciones:

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

Si es necesario sustituir los nodos existentes contenido y mantener nodo attri butes puede usar:

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