Xml XSLT:排序路径跟踪
我有以下意见:Xml XSLT:排序路径跟踪,xml,xslt,Xml,Xslt,我有以下意见: <articles> <item name="B"> <item name="Bb"> <item name="Bbb"/> <item name="Abb"/> </item> <item name="Ab"> <item name="Bab"/> <item name="Aab"/> &
<articles>
<item name="B">
<item name="Bb">
<item name="Bbb"/>
<item name="Abb"/>
</item>
<item name="Ab">
<item name="Bab"/>
<item name="Aab"/>
</item>
</item>
<item name="A">
<item name="Ba">
<item name="Bba"/>
<item name="Aba"/>
</item>
<item name="Aa">
<item name="Baa"/>
<item name="Aaa"/>
</item>
</item>
<item name="D"/>
<item name="C">
<item name="Ac"/>
</item>
</articles>
也就是说,每个路径都应明确,并在每个级别上进行排序。我有下面的XSLT,它生成路径,但除了第一级之外,我无法计算排序
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="articles">
<xsl:apply-templates select="//item[not(item)]">
<xsl:sort select="ancestor-or-self::item[parent::articles]/@name"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="item">
<xsl:for-each select="ancestor-or-self::item">
<xsl:value-of select="@name"/>
<xsl:choose>
<xsl:when test="not(item)">
<xsl:text>
</xsl:text>
</xsl:when>
<xsl:otherwise>-</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
;
-
恐怕我目前的做法是走不通的。想法?不太好,但是下面的内容是针对3个项目的深度进行的,并且每增加一个级别都需要额外的排序。我相信一位大师能够更一般地做到这一点:)
;
-
请注意,XSLT2.0解决方案(第二部分)要短得多、简单得多
I.这里是一个简单的两遍解决方案:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:variable name="vrtfPass1">
<xsl:apply-templates/>
</xsl:variable>
<xsl:for-each select="ext:node-set($vrtfPass1)/*">
<xsl:sort/>
<xsl:value-of select="concat(., '
')"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="item[not(item)]">
<x>
<xsl:for-each select="ancestor-or-self::item">
<xsl:if test="not(position() = 1)">-</xsl:if>
<xsl:value-of select="@name"/>
</xsl:for-each>
</x>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each-group select="//item[not(item)]"
group-by="string-join(ancestor-or-self::item/@name, '-')">
<xsl:sort select="current-grouping-key()"/>
<xsl:sequence select="current-grouping-key(), '
'"/>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
注意事项:这是一个通用解决方案,可正确处理项
元素的任何嵌套
说明:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:variable name="vrtfPass1">
<xsl:apply-templates/>
</xsl:variable>
<xsl:for-each select="ext:node-set($vrtfPass1)/*">
<xsl:sort/>
<xsl:value-of select="concat(., '
')"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="item[not(item)]">
<x>
<xsl:for-each select="ancestor-or-self::item">
<xsl:if test="not(position() = 1)">-</xsl:if>
<xsl:value-of select="@name"/>
</xsl:for-each>
</x>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each-group select="//item[not(item)]"
group-by="string-join(ancestor-or-self::item/@name, '-')">
<xsl:sort select="current-grouping-key()"/>
<xsl:sequence select="current-grouping-key(), '
'"/>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
<x xmlns:ext="http://exslt.org/common">B-Bb-Bbb</x>
<x xmlns:ext="http://exslt.org/common">B-Bb-Abb</x>
<x xmlns:ext="http://exslt.org/common">B-Ab-Bab</x>
<x xmlns:ext="http://exslt.org/common">B-Ab-Aab</x>
<x xmlns:ext="http://exslt.org/common">A-Ba-Bba</x>
<x xmlns:ext="http://exslt.org/common">A-Ba-Aba</x>
<x xmlns:ext="http://exslt.org/common">A-Aa-Baa</x>
<x xmlns:ext="http://exslt.org/common">A-Aa-Aaa</x>
<x xmlns:ext="http://exslt.org/common">D</x>
<x xmlns:ext="http://exslt.org/common">C-Ac</x>
<x xmlns:ext="http://exslt.org/common">B-Bb-Bbb</x>
<x xmlns:ext="http://exslt.org/common">B-Bb-Abb</x>
<x xmlns:ext="http://exslt.org/common">B-Ab-Bab</x>
<x xmlns:ext="http://exslt.org/common">B-Ab-Aab</x>
<x xmlns:ext="http://exslt.org/common">A-Ba-Bba</x>
<x xmlns:ext="http://exslt.org/common">A-Ba-Aba</x>
<x xmlns:ext="http://exslt.org/common">A-Aa-Baa</x>
<x xmlns:ext="http://exslt.org/common">A-Aa-Aaa</x>
<x xmlns:ext="http://exslt.org/common">D</x>
<x xmlns:ext="http://exslt.org/common">C-Ac</x>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each-group select="//item[not(item)]"
group-by="string-join(ancestor-or-self::item/@name, '-')">
<xsl:sort select="current-grouping-key()"/>
<xsl:sequence select="current-grouping-key(), '
'"/>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>