2017-12-30 58 views
1

Ich habe eine xml lists.xml:Umgang mit Leerraum in XSLT

<?xml version="1.0" encoding="UTF-8"?> 
<data> 
    <list> 
    <item>Salt</item> 
    <item>Sugar</item> 
    </list> 
    <list> 
    <item>Eggs</item> 
    <item>Butter</item> 
    </list> 
</data> 

und einen XSLT-Stylesheet transform.xslt

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"> 
    <xsl:output method="text"/> 
    <xsl:template match="//list/item"> 
    <xsl:text> - </xsl:text> 
    <xsl:value-of select="." /> 
    <xsl:text>&#xa;</xsl:text><!--put a line-break between two list points---> 
    <xsl:if test="position() = last()"><!--put another line-break at the end of a list--> 
     <xsl:text>&#xa;</xsl:text> 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

Meine erwartete Ausgabe ist in etwa wie folgt:

- Salt  
- Sugar 

- Eggs 
- Butter 

aber stattdessen bekomme ich das oben genannte mit viel zu viel ausgabe, wenn ich mit sachsen (oder oth) trasforme Prozessoren). Wie behandle ich White-Space in XSLT richtig?

Hinweis: Ich bin komplett neu in XSLT und ich bin mir bewusst, dass mein Code oben schlecht sein könnte - so, neben der Frage, schätze ich alle Vorschläge, um es eleganter/besser zu lesen/schneller/kürzer. ..

Antwort

4

Einfach <xsl:strip-space elements="*"/> zum Stylesheet hinzufügen.

+0

danke, hat perfekt funktioniert! – chr

2

Neben <xsl:strip-space elements="*"/> verwenden, auf eine andere Art und Weise zu steuern, ob diese nur aus Leerzeichen text() Knoten enthalten sind, in Ihrer Ausgabe eine leere Schablonenanpassung auf text() zu verwenden ist, dessen Wert haben keine „sinnvolle“ Text.

Verwenden Sie im folgenden Beispiel normalize-space(), um alle Leerzeichen (Leerzeichen, Tabulator, Wagenrücklauf) zu reduzieren, und negieren Sie dann diesen Wert in einem Vergleichselement. Der Vorteil dieses Ansatzes besteht darin, dass Sie diese Vorlage immer anpassen können, um bestimmte text()-Knoten einzubeziehen/auszuschließen und keine globale/binäre Entscheidung zu treffen.

Auch für Ihre Vorlage Übereinstimmung Ausdruck benötigen Sie nicht den Nachkomme //. Das Übereinstimmungsmuster kann einfach list/item sein, um mit einem beliebigen item übereinzustimmen, das ein Kind von list ist.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"> 
    <xsl:output method="text"/> 

    <xsl:template match="text()[not(normalize-space())]"/> 

    <xsl:template match="list/item"> 
    <xsl:text> - </xsl:text> 
    <xsl:value-of select="." /> 
    <xsl:text>&#xa;</xsl:text><!--put a line-break between two list points--> 
    <xsl:if test="not(following-sibling::item)"><!--put another line-break at the end of a list--> 
     <xsl:text>&#xa;</xsl:text> 
    </xsl:if> 
    </xsl:template> 

</xsl:stylesheet> 
+0

danke für deine tipps ... Das Problem mit deiner Lösung für mich ist, dass es den Nebeneffekt zu haben scheint, den zusätzlichen Zeilenumbruch am Ende einer Liste zu löschen ... – chr

+0

hoppla, hab nicht nah genug aufgepasst Beachten Sie, dass der zusätzliche Zeilenumbruch für jeden Satz von Listenelementen galt. Aktualisiert –