Hay tres razones para obtener un espacio en blanco no deseado en el resultado de una transformación XSLT:
- espacios en blanco que viene de entre los nodos en el documento fuente
- espacios en blanco que viene de dentro de los nodos en el documento fuente
- espacios en blanco que viene de la hoja de estilo
voy a hablar de los tres porque puede ser difícil saber de dónde viene el espacio en blanco, por lo que es posible que necesite usar varias estrategias.
Para hacer frente a los espacios en blanco que se encuentra entre los nodos en el documento de origen, se debe utilizar <xsl:strip-space>
que se deben eliminar cualquier espacio en blanco que aparece entre dos nodos, y luego usar <xsl:preserve-space>
para preservar el espacio en blanco significativo que pudiera aparecer dentro de contenido mixto.Por ejemplo, si el documento de origen se ve así:
<ul>
<li>This is an <strong>important</strong> <em>point</em></li>
</ul>
, entonces tendrá que pasar por alto el espacio en blanco entre el <ul>
y la <li>
y entre la </li>
y la </ul>
, que no es significativo, pero conservar el espacio en blanco entre el <strong>
y <em>
elementos, que es significativo (de lo contrario, obtendría "Este es un ** punto *** importante *"). Para ello el uso
<xsl:strip-space elements="*" />
<xsl:preserve-space elements="li" />
El atributo elements
en <xsl:preserve-space>
debe básicamente una lista de todos los elementos del documento que se han mezclado el contenido.
Aparte: el uso de <xsl:strip-space>
también reduce el tamaño del árbol de fuentes en la memoria, y hace que su hoja de estilo más eficiente, por lo que vale la pena hacer, incluso si usted no tiene problemas de espacio en blanco de este tipo.
Para abordar el espacio en blanco que aparece dentro de los nodos en su documento de origen, debe usar normalize-space()
. Por ejemplo, si usted tiene:
<dt>
a definition
</dt>
y usted puede estar seguro de que el elemento <dt>
no dará ningún elemento que desee hacer algo con, entonces usted puede hacer:
<xsl:template match="dt">
...
<xsl:value-of select="normalize-space(.)" />
...
</xsl:template>
El los espacios en blanco iniciales y finales se eliminarán del valor del elemento <dt>
y obtendrá la cadena "a definition"
.
Para hacer frente a los espacios en blanco que viene de la hoja de estilo, que es quizás el que usted está experimentando, es cuando tiene texto dentro de una plantilla como esta:
<xsl:template match="name">
Name:
<xsl:value-of select="." />
</xsl:template>
hojas de estilo XSLT se analizan de la misma manera como el documentos de origen que procesan, por lo que el XSLT anterior se interpreta como un árbol que contiene un elemento <xsl:template>
con un atributo match
cuyo primer hijo es un nodo de texto y cuyo segundo hijo es un elemento <xsl:value-of>
con un atributo select
. El nodo de texto tiene espacios en blanco iniciales y finales (incluidos saltos de línea); dado que es texto literal en la hoja de estilo, se copia literalmente en el resultado, con todos los espacios en blanco iniciales y finales.
Pero algunos espacios en blanco en hojas de estilos XSLT se eliminan automáticamente, es decir, aquellos entre los nodos. No obtiene un salto de línea en su resultado porque hay un salto de línea entre el <xsl:value-of>
y el cierre del <xsl:template>
.
Para obtener únicamente el texto que desee en el resultado, utilice el elemento <xsl:text>
así:
<xsl:template match="name">
<xsl:text>Name: </xsl:text>
<xsl:value-of select="." />
</xsl:template>
El procesador XSLT ignorará los saltos de línea y sangría que aparecen entre nodos, y sólo la salida del texto dentro de el elemento <xsl:text>
.
¡Esto fue extremadamente útil! Gracias. – Black
que de hecho fue útil, pero estoy confundido por el uso de la frase "entre nodos". ¿No es cierto que todos los espacios en blanco están contenidos en los nodos de texto? ¿Qué quieres decir con "entre nodos"? Si no hubiera reconocido su nombre, hubiera asumido que necesitaba una conferencia sobre la estructura del documento XML. – LarsH
¡Buen artículo, gracias! Pero estrictamente hablando, estás usando el término 'nodo' en el que realmente quieres decir 'elemento'. – rustyx