Saltar al contenido

XSLT: eliminar espacios en blanco de la plantilla

Solución:

En XSLT, los espacios en blanco se conservan de forma predeterminada, ya que pueden muy bien ser datos relevantes.

La mejor manera de evitar espacios en blanco no deseados en la salida es no crearlos en primer lugar. No hagas:

<xsl:template match="foo">
  foo
</xsl:template>

porque eso es "n··foon", desde el punto de vista del procesador. Prefiero hacerlo

<xsl:template match="foo">
  <xsl:text>foo</xsl:text>
</xsl:template>

El espacio en blanco en la hoja de estilo se ignora siempre que ocurra solo entre elementos XML. En pocas palabras: nunca use texto “desnudo” en ningún lugar de su código XSLT, siempre encárguelo en un elemento.

Además, usando un no específico:

<xsl:apply-templates />

es problemático, porque la regla XSLT predeterminada para los nodos de texto dice “cópielos en la salida”. Esto también se aplica a los nodos de “solo espacios en blanco”. Por ejemplo:

<xml>
  <data> value </data>
</xml>

contiene tres nodos de texto:

  1. "n··" (justo después de <xml>)
  2. "·value·"
  3. n" (justo antes de </xml>)

Para evitar que los números 1 y 3 se cuelen en la salida (que es la razón más común para los espacios no deseados), puede anular la regla predeterminada para los nodos de texto declarando una plantilla vacía:

<xsl:template match="text()" />

Todos los nodos de texto ahora están silenciados y la salida de texto debe crearse explícitamente:

<xsl:value-of select="data" />

Para eliminar el espacio en blanco de un valor, puede usar el normalize-space() Función XSLT:

<xsl:value-of select="normalize-space(data)" />

Pero cuidado, ya que la función normaliza cualquier espacio en blanco que se encuentre en la cadena, por ejemplo "·value··1·" se convertiría "value·1".

Además, puede utilizar el <xsl:strip-space> y <xsl:preserve-space> elementos, aunque generalmente esto no es necesario (y personalmente, prefiero el manejo explícito de espacios en blanco como se indicó anteriormente).

De forma predeterminada, las plantillas XSLT tienen <xsl:preserve-space> set, que mantendrá los espacios en blanco en su salida. Puedes añadir <xsl:strip-space elements="*"> para indicarle dónde eliminar los espacios en blanco.

Es posible que también deba incluir una directiva de normalizar el espacio, así:

<xsl:template match="text()"><xsl:value-of select="normalize-space(.)"/></xsl:template> 

Aquí hay un ejemplo para preservar / eliminar el espacio de las escuelas W3.

En cuanto a eliminar pestañas pero retener líneas separadas, probé el siguiente enfoque XSLT 1.0 y funciona bastante bien. Su uso de la versión 1.0 o 2.0 depende en gran medida de la plataforma que esté utilizando. Parece que la tecnología .NET todavía depende de XSLT 1.0, por lo que está limitado a plantillas extremadamente desordenadas (ver más abajo). Si está utilizando Java u otra cosa, consulte el enfoque XSLT 2.0 mucho más limpio que se enumera en la parte inferior.

Estos ejemplos deben ser ampliados por usted para satisfacer sus necesidades específicas. Estoy usando pestañas aquí como ejemplo, pero esto debería ser lo suficientemente genérico como para ser extensible.

XML:

<?xml version="1.0" encoding="UTF-8"?>
<text>
        adslfjksdaf

                dsalkfjdsaflkj

            lkasdfjlsdkfaj
</text>

… y la plantilla XSLT 1.0 (necesaria si usa .NET):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet  
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">   
 <xsl:template name="search-and-replace">
   <xsl:param name="input"/>
   <xsl:param name="search-string"/>
   <xsl:param name="replace-string"/>
   <xsl:choose>
    <xsl:when test="$search-string and 
                    contains($input,$search-string)">
       <xsl:value-of
           select="substring-before($input,$search-string)"/>
       <xsl:value-of select="$replace-string"/>
       <xsl:call-template name="search-and-replace">
         <xsl:with-param name="input"
               select="substring-after($input,$search-string)"/>
         <xsl:with-param name="search-string"
               select="$search-string"/>
         <xsl:with-param name="replace-string"
               select="$replace-string"/>
       </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$input"/>
    </xsl:otherwise>
   </xsl:choose>
  </xsl:template>                
  <xsl:template match="text">
   <xsl:call-template name="search-and-replace">
     <xsl:with-param name="input" select="text()" />
     <xsl:with-param name="search-string" select="'&#x9;'" />
     <xsl:with-param name="replace-string" select="''" />
   </xsl:call-template>    
  </xsl:template>
</xsl:stylesheet>

XSLT 2.0 hace que esto sea trivial con el replace función:

<?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="text">
  <xsl:value-of select="replace(text(), '&#x9;', '')" />
 </xsl:template>
</xsl:stylesheet>
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : / /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *