2017-03-20 3 views
0

Ich habe eine xml zu verwandeln:Transformation mit xslt 2.0 durchführen Wie erhalte ich zitierte Werte, die durch ein Trennzeichen getrennt sind?

<root> 
    <item name="first" /> 
    <item name="second" /> 
    <item name="third" /> 
</root> 

Was ich ein String zu bekommen ist, wo jeder Wert notiert und Werte getrennt sind (Reihenfolge spielt keine Rolle):

"first" , "second" , "third" 

Meine Frage ist, Wie erreiche ich das mit xslt 2.0 richtig?

Hier ist meine Lösung, die nicht wie erwartet funktioniert. Also meine Frage ist - warum ist es nicht?

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:ns="urn:my.name.space" 
    version="2.0"> 

    <xsl:output method="text" media-type="text/json"/> 

    <xsl:template match="root"> 
    <xsl:value-of select="item/@name" separator=" , "/> 
    <xsl:text> :: </xsl:text> 
    <xsl:value-of select="item/ns:quotedString(@name)" separator=" , "/> 
    </xsl:template> 

    <xsl:function name="ns:quotedString"> 
    <xsl:param name="input"/> 
    <xsl:variable name="quote">&quot;</xsl:variable> 
    <xsl:value-of select="concat($quote, $input, $quote)"/> 
    </xsl:function> 

</xsl:stylesheet> 

Das gibt mir:

first , second , third :: "second""third""first" 

Hinweis der Separator fehlt, wenn ich meine zitierte Funktion aufrufen.

Ich wenden Transformation mit Saxon-B 9.1.0.8.

Antwort

1

Es gibt mehrere Lösungen, um einer Reihe von Strings beizutreten.

XPath für ... in ...

<xsl:template match="root"> 
    <xsl:value-of select="string-join(for $i in item return concat('&quot;', $i/@name, '&quot;'), ' , ')"/> 
</xsl:template> 

<string-join> verbindet die quotated Saiten jedes item/@name. Die Parameter <string-join> sind Strings.


Funktionsaufruf "ns: QuotedString"

<xsl:template match="root"> 
    <xsl:value-of select="item/ns:quotedString(@name)" separator=" , "/> 
</xsl:template> 

<xsl:function name="ns:quotedString"> 
    <xsl:param name="input"/> 
    <xsl:variable name="quote">&quot;</xsl:variable> 
    <xsl:sequence select="concat($quote, $input, $quote)"/> 
</xsl:function> 

Dies wird Ihre Frage beantworten, warum ist es nicht arbeiten. Siehe die <xsl:sequence> als letzte Anweisung in Funktion. Die @separator funktioniert nur, wenn die <xsl:value select="..."> Anweisung eine Sequenz zurückgibt, in Ihrem Fall ist der Rückgabewert ein einzelner Textknoten.

0

Ihre Funktion gibt einen Textknoten und adjacent text nodes in the sequence are merged into a single text node zurück. Lass es eine Sequenz zurückgeben.

So xsl:value von in Ihrer Funktion zu xsl:sequence ändern ...

<xsl:function name="ns:quotedString"> 
    <xsl:param name="input"/> 
    <xsl:variable name="quote">&quot;</xsl:variable> 
    <xsl:sequence select="concat($quote, $input, $quote)"/> 
</xsl:function> 

Meine Präferenz ist es, nur die Sequenz senden an die Funktion ...

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:ns="urn:my.name.space" 
    version="2.0"> 

    <xsl:output method="text" media-type="text/json"/> 

    <xsl:template match="root"> 
    <xsl:value-of select="item/@name" separator=" , "/> 
    <xsl:text> :: </xsl:text> 
    <xsl:value-of select="ns:quotedString(item/@name)"/> 
    </xsl:template> 

    <xsl:function name="ns:quotedString"> 
    <xsl:param name="input"/> 
    <xsl:value-of select="concat('&quot;', 
     string-join($input,'&quot;, &quot;'), 
     '&quot;')"/> 
    </xsl:function> 

</xsl:stylesheet> 

Haftungsausschluss: I don‘ t haben Saxon-B 9.1.0.8. mit testen. Ich habe Saxon-HE 9.5.1.7 verwendet. zu testen.

+2

"Ihre Funktion gibt eine Zeichenfolge zurück" ist falsch, es gibt einen Textknoten zurück. Wenn es einen String zurückliefert, dann würde der Ausdruck '' tun, was das Poster will. Es funktioniert nicht als https://www.w3.org/TR/xslt20/#constructing-simple-content Mandate "Benachbarte Textknoten in der Sequenz werden zu einem einzigen Textknoten zusammengeführt.". –

+0

@MartinHonnen - Danke für die Klarstellung. Ich werde meine Antwort aktualisieren. –

Verwandte Themen