2011-06-01 26 views
10

Estoy transformando XML en HTML usando XSLT.Cómo copiar todos los nodos secundarios de cualquier tipo de un elemento de contexto de plantilla

que tienen la siguiente estructura XML:

<root> 
    <element> 
     <subelement> 
      This is some html text which should be <span class="highlight">displayed highlighted</span>. 
     </subelement> 
    </element> 
</root> 

utilizo la siguiente plantilla para la transformación:

<xsl:template name="subelement"> 
    <xsl:value-of select="." /> 
</xsl:template> 

Por desgracia, yo no pierda las <span> creada.

¿Hay alguna manera de conservarlos para que el HTML se muestre correctamente (resaltado)?

Respuesta

27

La forma correcta para obtener los todos los contenidos del nodo actual encaja con el (los nodos de texto incluido) es:

<xsl:template match="subelement"> 
     <xsl:copy-of select="node()"/> 
    </xsl:template> 

Esto copiará todo descendiente.

+1

+1 para la respuesta correcta. Tenga en cuenta que esto no copiará los * atributos * del nodo de contexto ... que requerirían 'select =" node() | @ * "'. Pero no creo que @idefix los necesitara. – LarsH

+1

@LarsH: esto no es cierto en este caso. Va a ser cierto en 'xsl: apply-templates' o' match' pero no en 'xsl: copy'. –

+0

@empo - Estoy corregido. (Supongo que quisiste decir 'xsl: copy-of' en lugar de' xsl: copy'.) Pensé que la expresión 'node()' tenía un eje implícito 'child ::', que excluiría los atributos. Pero las pruebas parecen demostrar que tienes razón. Tendré que revisar esos detalles. – LarsH

5

Try usando <xsl:copy-of... en lugar de <xsl:value-of... por ejemplo:

<xsl:template name="subelement"> 
    <xsl:copy-of select="*" /> 
</xsl:template> 

Nota la * que detendrá el <subelement></subelement> bits de ser una salida en los resultados, en lugar de utilizar . que incluirá los <subelement></subelement> bits.

Por ejemplo, la hoja de estilo XSL:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs" 
    version="2.0"> 

    <xsl:template match="root/element"> 
     <output> 
      <xsl:apply-templates select="subelement"/> 
     </output> 
    </xsl:template> 

    <xsl:template match="subelement"> 
     <xsl:copy-of select="*"/> 
    </xsl:template> 

</xsl:stylesheet> 

cuando se aplica a tu ejemplo de archivo XML devuelve:

<?xml version="1.0" encoding="UTF-8"?> 
<output> 
    <span class="highlight">displayed highlighted</span> 
</output> 
+1

Actualización con un ejemplo completo después de algunas pruebas –

+1

En el primer ejemplo anterior '" ./ "' no es una expresión XPath válida. En el segundo espécimen, '" ./* "' es válido, pero es equivalente a '" * "'. El comentario "Note que '/' ..." está completamente equivocado. –

+1

El ./ es un tipo y debe ser * - tienes razón. Lo que quiero decir con el comentario es que si solo haces Obtienes el outerxml incluido el nodo, que no es obligatorio. Lo estaba señalando para evitar la frustración. Lo aclararé. –

0

La declaración <xsl:value-of> toma el contenido concatenadas de todos los nodos de texto dentro del elemento, en orden secuencial, y no produce ningún elemento en absoluto.

Recomendaría usar <xsl:apply-templates> en su lugar. Donde encuentre un nodo de texto, mostrará el contenido tal como está, pero necesitaría definir una plantilla para manejar las etiquetas de rango para convertirlas a html. Si esa etiqueta span ES una etiqueta html, estrictamente hablando, debe tener espacios de nombres separados para su propia estructura de documento y html.

Cuestiones relacionadas