XSLT: <xsl:strip-space> funktioniert nicht

- Ashish

Ich habe einen Servlet-Filter in meiner Anwendung, der alle eingehenden Anforderungen abfängt und versucht, die Leerzeichen aus dem eingehenden XML zu entfernen und das resultierende 'saubere' XML in die Antwort zu schreiben. Ich verwende XSLT, um dies zu erreichen. Bitte beachten Sie die XSLT unten:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="@*|node()">
<xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

Dies funktioniert jedoch nicht wie erwartet. Das resultierende XML ist identisch mit dem ursprünglichen XML (trotz der Verwendung der <xsl:strip-space elements="*"/> im Stylesheet.

Bitte helfen Sie mir, das richtig zu machen.

Grüße,

Antwort auf "XSLT: &lt;xsl:strip-space&gt; funktioniert nicht " 3 von antworten

Es ist nicht klar, was Sie als Output zu bekommen beabsichtigen, und was Sie von xsl:strip-whitespace in the first place. But one thing to note is that it doesn't strip in erster Linie erwarten. Aber eine Sache zu beachten ist, dass es nicht alle Leerzeichen entfernt, sondern nur das, was unter den "üblichen" Regeln als unbedeutend angesehen wird. Insbesondere aus XSLT 1.0-Spezifikation:

Ein Textknoten wird nie entfernt, es sei denn, er enthält nur Leerzeichen.

So wird zum Beispiel dies:

<foo>
  <bar>   </bar>
</foo>

auf" herabgesacht:

<foo><bar/></foo>

, weil es 3 Leerraum-Textknoten hatte (nach <foo> and before und vor <bar>, between , zwischen <bar> and und </bar>, and after und nach </bar> and before und vor </foo>). ).

Beachten Sie auch, dass, weil Sie <xsl:output indent="yes"> in your stylesheet, it will end up being transformed to: in Ihrem Stylesheet haben, es am Ende in

<foo>
   <bar/>
<foo>

in der Ausgabe transformiert wird.

Auf der anderen Seite wird dies:

<foo>
   text1
   <bar>  text2  </bar>
   text3
</foo>

überhaupt nicht entfernt, da alle darin enthaltenen Textknoten keine reinen Leerzeichen sind.

Hinzufügen dieser als zweite Antwort, denn die Erklärung in der ersten ist immer noch (hoffentlich) informativ genug, um sie zu behalten.

Unter der Annahme, dass Sie mit "trimmen" "alle Leerzeichen unmittelbar nach dem Öffnen und vor dem Schließen von Tags entfernen" meinen, sollten die folgenden zusätzlichen Vorlagenregeln den Trick tun:

<xsl:variable name="whitespace">&#x20;&#x9;&#xD;&#xA;</xsl:variable>

<!-- Trim all whitespace at beginning of string -->
<xsl:template name="trim-start">
   <xsl:param name="text"/>
   <xsl:variable name="first-char" select="substring($text, 1, 1)" />
   <xsl:choose>
     <xsl:when test="contains($whitespace, $first-char)">
       <xsl:call-template name="trim-start">
         <xsl:with-param name="text" select="substring($text, 2)" />
       </xsl:call-template>
     </xsl:when>
     <xsl:otherwise>
       <xsl:value-of select="$text" />
     </xsl:otherwise>
   </xsl:choose>
</xsl:template>

<!-- Trim all whitespace at end of string -->
<xsl:template name="trim-end">
   <xsl:param name="text"/>
   <xsl:variable name="last-char" select="substring($text, string-length($text), 1)" />
   <xsl:choose>
     <xsl:when test="contains($whitespace, $last-char)">
       <xsl:call-template name="trim-end">
         <xsl:with-param name="text" select="substring($text, 1, string-length($text) - 1)" />           </xsl:call-template>
       </xsl:call-template>
     </xsl:when>
     <xsl:otherwise>
       <xsl:value-of select="$text" />
     </xsl:otherwise>
   </xsl:choose>
</xsl:template>

<xsl:template match="text()">
  <xsl:call-template name="trim-start">
    <xsl:with-param name="text">
      <xsl:call-template name="trim-end">
        <xsl:with-param name="text" select=".">
      </xsl:call-template>
    <xsl:param>
  </xsl:call-template>
</xsl:template>

Mit dem xslt aus der ursprünglichen Frage sollte ein <xsl:template match="text()"><xsl:value-of select="normalize-space(.)"/></xsl:template> should do the trick. den Trick machen.