2016-05-12 1 views
1

の値に基づいて、番号属性を作成:XSLT - など次のリストなどの文書から別の属性

<list> 
    <city ref="Paris">Paris</city> 
    <city ref="Rome">Rome</city> 
    <city ref="NYC">New York</city> 
    <city ref="Lisboa">Lisboa</city> 
    <city ref="Lisboa">Lisbon</city> 
    <city ref="Lisboa">Lisbonne</city> 
    <city ref="NYC">The Big Apple</city> 
</list> 
私が由来追加数値属性で、このリストのコピーを入手したいと思います

(理想的には、アルファベット順)@ref属性は、のような出力のために:

<list> 
    <city ref="Paris" id="3">Paris</city> 
    <city ref="Rome" id="4">Rome</city> 
    <city ref="NYC" id="2">New York</city> 
    <city ref="Lisboa" id="1">Lisboa</city> 
    <city ref="Lisboa" id="1">Lisbon</city> 
    <city ref="Lisboa" id="1">Lisbonne</city> 
    <city ref="NYC" id="2">The Big Apple</city> 
</list> 

私は@ref属性のソートされたリストに番号を付ける<xsl:key>を使用する方法があるとしますが、取得するのに十分堪能ではありませんよそこ。

事前に感謝します。 XSLT 3.0で

+0

XSLT 2.0を使用できますか? –

答えて

1

(サクソン9.7でサポートされているように)、我々がXSLT 1.0と最後

<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:variable name="cities" as="xs:string*"> 
     <xsl:perform-sort select="distinct-values(/list/city/@ref)"> 
      <xsl:sort select="."/> 
     </xsl:perform-sort> 
    </xsl:variable> 

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

    <xsl:template match="city/@ref"> 
     <xsl:copy/> 
     <xsl:attribute name="id" select="index-of($cities, .)"/> 
    </xsl:template> 

</xsl:stylesheet> 

を使用することができるXSLT 2.0

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:math="http://www.w3.org/2005/xpath-functions/math" 
    exclude-result-prefixes="xs math" 
    version="3.0"> 

    <xsl:variable name="cities" select="sort(distinct-values(/list/city/@ref))"/> 

    <xsl:mode on-no-match="shallow-copy"/> 

    <xsl:template match="city/@ref"> 
     <xsl:copy/> 
     <xsl:attribute name="id" select="index-of($cities, .)"/> 
    </xsl:template> 

</xsl:stylesheet> 

ほど簡単である上に

に "変換"
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:exsl="http://exslt.org/common" 
    exclude-result-prefixes="exsl" 
    version="1.0"> 

    <xsl:key name="city" match="city" use="@ref"/> 

    <xsl:variable name="cities-rtf"> 
     <xsl:for-each select="/list/city[generate-id() = generate-id(key('city', @ref)[1])]"> 
      <xsl:sort select="@ref"/> 
      <city id="{position()}" ref="{@ref}"/> 
     </xsl:for-each> 
    </xsl:variable> 

    <xsl:variable name="cities" select="exsl:node-set($cities-rtf)/city"/> 

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

    <xsl:template match="city/@ref"> 
     <xsl:copy/> 
     <xsl:attribute name="id"> 
      <xsl:value-of select="$cities[@ref = current()]/@id"/> 
     </xsl:attribute> 
    </xsl:template> 

</xsl:stylesheet> 
+0

ありがとうございました! 好奇心の渦中に、XSLT 2.0の実用的な代替手段はありますか? – Robin

+0

ありがとう! – Robin

+0

うわー、3.0,2.0,1.0 - 良い回答の三角形! – kjhughes

関連する問題