我正在尝试使用xslt对xml进行排序,但问题是我的代码仅对特定节点下的元素进行排序,这是一个示例xml:
<region name="Germany">
<company name="Mercedes" rank="2" />
<company name="BMW" rank="3" />
</region>
<region name="Japan">
<company name="Toyota" rank="1" />
<company name="Mazda" rank="4" />
</region>
我尝试了以下操作,但没有成功
<xsl:template match="region">
<Companies>
<xsl:for-each select="company">
<xsl:sort select="@rank" />
<xsl:call-template name="companies">
</xsl:for-each>
</Companies>
</xsl:template>
<xsl:template name="companies">
<Company>
<xsl:value-of select="@name" />
</Company>
</xsl:template>
输出应为:
<Companies>
<Company>Toyota</Company>
<Company>Mercedes</Company>
<Company>BMW</Company>
<Company>Mazda</Company>
</Companies>
答案 0 :(得分:1)
在输出中,您似乎想按等级而不是名称进行排序。
关于随节点进行的排序,因为您的模板正在每个区域运行,所以排序是针对一个区域内的公司节点。 您可以为区域的父级运行模板,然后遍历元素并按名称排序。 这是具有匹配输出的模板。
<xsl:template match="*[region]">
<Companies>
<xsl:for-each select="region/company">
<xsl:sort select="@rank" />
<xsl:call-template name="companies" />
</xsl:for-each>
</Companies>
</xsl:template>
<xsl:template name="companies">
<Company>
<xsl:value-of select="@name" />
</Company>
</xsl:template>
答案 1 :(得分:1)
对于这些region
元素,您没有显示任何容器元素,但是假设您将它们包含在一个公共容器中,请编写一个与该容器匹配的模板(例如,在下面的示例代码中名为root
),然后我只是建议将模板应用于包含company
属性的xsl:sort
的{{1}}孙子。
然后添加一个模板,该模板从基于属性的rank
输入元素转换为基于值的元素,您已完成:
company
https://xsltfiddle.liberty-development.net/94rmq6B
如果要以一种排序的方式一起处理所有<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="root">
<Companies>
<xsl:apply-templates select="region/company">
<xsl:sort select="xs:integer(@rank)"/>
</xsl:apply-templates>
</Companies>
</xsl:template>
<xsl:template match="company">
<xsl:copy>
<xsl:value-of select="@name"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
,似乎没有任何意义。