2010-11-22 13 views
7

tengo algo de XML que se parece ano se convierten> a > en XSLT

<?xml version="1.0"?> 
<root> 
    <![CDATA[ 
    > foo 
    ]]> 
</root> 

(Nota el signo> en "> foo") y una hoja de estilo XSLT

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="/root"> 
    <foo><xsl:value-of select='.'/></foo> 
</xsl:template> 
</xsl:stylesheet> 

Cuando corro xsltproc stylesheet.xsl data.xml consigo

<?xml version="1.0"?> 
<foo> 

    &gt; foo 

</foo> 

pero la salida que quiero es

<?xml version="1.0"?> 
<foo> 

    > foo 

</foo> 

es decir, mantener el ">" como está en lugar de convertirlo en una entidad. ¿Cómo puedo lograr esto?

+1

con '>' sería inválida como XML. – khachik

+2

@khachik, no es cierto; ver mi respuesta – LarsH

+0

@khachik El validador W3C XML está de acuerdo con LarsH, el resultado deseado es XML válido. – pafcu

Respuesta

8

@Oded, @khachik,

Trate checking his desired output for well-formedness. De hecho, está bien formado XML. ("Válido" ni siquiera es una pregunta aquí, ya que no hay esquema.)

Es un error común que ">" no es legal en XML bien formado. En la mayoría de los contextos, "<" no es legal, pero ">" es legal en todas partes con una rara excepción. El relevant paragraph de la especificación:

el carácter y comercial (&) y el soporte ángulo izquierdo (<) no debe aparecer en su forma literal, excepto cuando utilizado como delimitadores de marcado, o dentro de un comentario , una instrucción de procesamiento, o una sección CDATA. Si se necesitan en otro lugar, DEBEN escaparse utilizando referencias de caracteres numéricos o las cadenas "&" y "<" respectivamente. El soporte ángulo recto (>) puede ser representado usando el cadena "& gt;", y debe, por compatibilidad, se escapó utilizando "& gt;" o una referencia de carácter cuando aparece en la cadena "]]>" en contenido, cuando esa cadena no es marcando el final de una sección CDATA.

Con XSLT 2.0, la forma "correcta" de hacer lo que quiera es usar <xsl:character-map>. Con XSLT 1.0, creo que la única forma de forzar el uso de ">" en la salida es usar disable-output-escaping, como @khachik sugirió. Sin embargo, tenga en cuenta que los procesadores XSLT son not required to honor DOE or character maps, y algunos no (por ejemplo, si están en una canalización y no están conectados a la serialización). Pero probablemente ya sepa si el suyo puede hacerlo, y si no puede, tendrá que manejar los problemas de serialización al final de la canalización.

Sin embargo, vale la pena preguntarse, por qué ¿Quieres que el ">" serializado como ">"? Como se ve en la especificación, & gt; es una forma perfectamente aceptable de expresar exactamente la misma información en lo que concierne a XML. Ningún consumidor de XML descendente debe conocer la diferencia o el cuidado. ¿Lo quieres por razones estéticas?

Actualización: OP quiere eso porque la salida necesita ser no solo el XML bien formado, también debe ser Literate Haskell bien formado.

+0

Se supone que la salida es Literate Haskell, que requiere que las líneas que contienen código de programa ejecutable comiencen con el carácter literal ">", mientras que todo lo demás se ve como comentarios. El analizador Literate Haskell no sabe nada sobre XML o que > y> son equivalentes en XML. – pafcu

+0

@LarsH ¿qué es valioso en tu respuesta? – khachik

+1

@pafcu ¿Usted escribe el generador de código haskell en XSLT? ¡Bonito! :) – khachik

1

<xsl:value-of select='.' disable-output-escaping="yes"/> pero no sería un XML bien formado.

Actualización Con > estará bien formado. (Con < no lo hará.)

+0

Confieso que rechacé su respuesta debido a la parte incorrecta de que '>' no era un XML bien formado. Desearía poder eliminar ese voto negativo, o bien agregar un voto positivo, debido a la útil sugerencia de usar d-o-e. Sin embargo, no me lo permitirá, a menos que edite su respuesta. Si lo hace, hágamelo saber para poder cambiar mi voto. – LarsH

+1

@LarsH Actualicé mi respuesta para ser correcta. No es necesario volver a votar, porque se votó negativamente, '>' no hace que XML no esté bien formado (y la palabra "no válida" no era correcta en este contexto). Gracias :) – khachik

4

Agregando a la muy buena explicación de @LarsH:

Si su procesador XSLT permite DOE, entonces usted puede utilizar:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/root"> 
     <foo><xsl:value-of select='.' disable-output-escaping="yes"/></foo> 
    </xsl:template> 
    </xsl:stylesheet> 

y cuando esta transformación se aplica sobre la proporcionado documento XML:

<?xml version="1.0"?> 
<root> 
    <![CDATA[ 
    > foo 
    ]]> 
</root> 

la salida deseada se produce:

<foo> 
    > foo 
    </foo>