2010-06-03 50 views
6

Estoy tratando de obtener el contenido CDATA de un nodo XML usando XSL. El nodo Actualmente tiene este aspecto:¿Cómo obtener CDATA del nodo xml usando xsl?

<node id="1" text="Book Information" ><![CDATA[This is sample text]]></node> 

necesito la pieza This is sample text. ¿Alguien tiene alguna idea de esto?

Gracias de antemano.

+0

intentado con la plantilla. Pero no devuelve ningún valor. –

+0

¿Qué plantilla? –

+0

En realidad, de varios recursos encontré algo así como; y luego para recuperar CDATA; Devuelve nada. –

Respuesta

1

Algunos otros sencillos pasos para lograrlo;
Se usó el editor W3cschools para probar.
Ejemplo de archivo XML:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<!-- Edited by XMLSpy® --> 
<catalog> 
    <cd> 
     <disk id="title"><![CDATA[Sample xml]]></disk > 
     <disk id="artist"><![CDATA[Vijay]]></disk > 
    </cd> 
</catalog> 


Muestra archivo XSL:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<!-- Edited by XMLSpy® --> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="/"> 
    <html> 
    <body> 
    <h2>My CD Collection</h2> 
    <table border="1"> 
     <tr bgcolor="#9acd32"> 
     <th>Title</th> 
     <th>Artist</th> 
     </tr> 
<xsl:for-each select="catalog/cd"> 

     <tr> 
     <td><xsl:value-of select="/catalog/cd/disk[@id='title']"/></td> 
     <td><xsl:value-of select="/catalog/cd/disk[@id='artist']"/></td> 
     </tr> 
</xsl:for-each> 
    </table> 
    </body> 
    </html> 
</xsl:template> 
</xsl:stylesheet> 


resultado final es;
alt text

+0

antes de marcar algo -ve, les pido a todos que den una razón. Para que sea útil para mí. –

10

Bueno, si uso esta hoja de estilo:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:template match="node/text()"> 
    <xsl:copy/> 
    </xsl:template> 
</xsl:stylesheet> 

en este archivo XML:

<?xml version="1.0" encoding="utf-8"?> 
<node id=1 text="Book Information" ><![CDATA[This is sample text]]></node> 

me sale un error de análisis, porque id=1 es XML válido.

Poner entre comillas el valor del atributo (id="1") y volver a ejecutar la hoja de estilo, me sale como salida:

Este es el texto de ejemplo

Así que no es un comienzo. Básicamente, solo trata el CDATA como un nodo de texto y ya estás en camino.

Usted dijo:

me encontré con algo como:
<xsl:output cdata-section-elements="text"/>
y luego a buscar CDATA:
<xsl:value-of select="node" />

Este enfoque funciona bien si está usando value-of también. Aquí hay un ejemplo a lo largo de las líneas de su comentario, usando value-of en su lugar. Sin embargo, tenga en cuenta que cdata-section-elements solo funciona en el lado de salida, lo que indica salida Elementos XML que desea imprimir como secciones CDATA en lugar de datos simples de caracteres antiguos. No tiene nada que ver con obteniendo los datos.

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output cdata-section-elements="foo"/> 
    <xsl:template match="/"> 
    <foo> 
     <xsl:value-of select="node"/> 
    </foo> 
    </xsl:template> 
</xsl:stylesheet> 

imprime

<?xml version="1.0"?> 
<foo><![CDATA[This is sample text]]></foo> 
+0

Hola Owen, Bien, gracias por su respuesta. En realidad, quiero CDATA bajo condición if. Existen ciertas condiciones que dependen de ellos. Necesito asignar este valor CDATA a un control Label. –

+1

¿Qué le parece publicar un fragmento de lo que está tratando de hacer y dónde quiere que vaya su valor? –

-1

me trataron con varias combinaciones y consiguieron la solución para esto;

<xsl:value-of select="/node/."/> 
+0

antes de marcar algo -ve, les pido a todos que den una razón. Para que sea útil para mí. –

+2

Tiene dos respuestas a su pregunta. Esto es muy confuso, especialmente porque ya ha aceptado su otra respuesta mucho más larga (y distractora). Apreciaría si combinas ambos en uno, eliminando los bits que no contribuyen. – Alberto

0

Para secciones CDATA salida:

usted tiene que utilizar xsl:output/@cdata-section-elements. De http://www.w3.org/TR/xslt#output

la sección cdata-elementos atribuyen contiene una lista de espacio en blanco separado por de QNames. Cada QName se expande en un nombre expandido usando las declaraciones de espacio de nombres vigentes en el elemento de salida xsl: en el que se produce el QName ; si hay un espacio de nombre predeterminado , se utiliza para QNames que no tienen un prefijo. La expansión es realizada antes de la fusión de elementos de salida xsl múltiples en un elemento de salida xsl: eficaz único . Si el nombre expandido de la matriz de un nodo de texto es un miembro de la lista, , entonces el nodo de texto debe mostrarse como una sección CDATA.

Además de DOE, por supuesto.

No puede seleccionar secciones CDATA con XPath. De acuerdo con http://www.w3.org/TR/xpath/#data-model

Hay siete tipos de nodos:

  • nodos raíz

  • nodos del elemento

  • nodos de texto

  • nodos atributo

  • nodos espacio de nombres

  • nodos instrucción de procesamiento

  • nodos de comentario

Y desde http://www.w3.org/TR/xpath/#section-Text-Nodes

Cada personaje dentro de una sección CDATA se trata de una s datos de caracteres.Por lo tanto, <![CDATA[<]]> en el documento de origen se tratarán igual que <. Ambos darán como resultado un solo carácter < en un nodo de texto en el árbol. Por lo tanto, un sección CDATA se trata como si el <![CDATA[ y ]]> fueron retirados y cada ocurrencia de < y & fueron reemplazados por &lt; y &amp; respectivamente.

0

La única solución que he encontrado en la web que funciona es la siguiente -

{XSLT}  
<title> 
    <xsl:text disable-output-escaping="yes"><![CDATA[ <![CDATA[ ]]></xsl:text> 
    <xsl:value-of select="label" disable-output-escaping="yes"/> 
    <xsl:text disable-output-escaping="yes"><![CDATA[]]]]><![CDATA[>]]></xsl:text> 
</title> 

Sin embargo, este no es el más limpio de soluciones especialmente si es necesario implementar esto en varias partes de su XSLT. Además, si su entrada XML ya tiene el CDATA (es decir, está intentando preservar CDATA) el uso de disable-output-escaping no funcionará porque para entonces el CDATA ya ha sido analizado por el motor XSLT y todo lo que quedará es el contenido que puede terminar rompiendo el xml.

aquí está mi solución-

Dependiendo de cómo se está utilizando XSLT, es posible utilizar las funciones externas/inyectados. Al hacerlo, puede minimizar fácilmente la cantidad de código que está escribiendo y terminar con una plantilla mucho más limpia:

{C#} 
public string CDATAWrap(string data) 
{ 
    return "<![CDATA[" + data + "]]>"; 
} 

{XSLT}  
<title> 
    <xsl:value-of select="CDataType:CDATAWrap(label)" disable-output-escaping="yes" /> 
</title>