在XSLT中是否可以按字母顺序排序,将5个项目作为“首选”。
即。给定
<teams>
<team id="142" name="Scotland" />
<team id="110" name="Liverpool" />
<team id="13" name="Manchester United" />
<team id="123" name="England" />
<team id="84" name="Chelsea" />
<team id="295" name="Wales" />
<team id="49" name="Arsenal" />
<team id="126" name="Northern Ireland" />
<team id="121" name="Republic of Ireland" />
<team id="42" name="Manchester City" />
<team id="298" name="Tottenham Hotspur" />
<team id="299" name="Bolton" />
</teams>
我要求国家队按照特定顺序排序,其余按字母顺序排列:
<teams>
<team id="123" name="England" />
<team id="126" name="Northern Ireland" />
<team id="121" name="Republic of Ireland" />
<team id="142" name="Scotland" />
<team id="295" name="Wales" />
<team id="49" name="Arsenal" />
<team id="299" name="Bolton" />
<team id="84" name="Chelsea" />
<team id="110" name="Liverpool" />
<team id="42" name="Manchester City" />
<team id="13" name="Manchester United" />
<team id="298" name="Tottenham Hotspur" />
</teams>
我一直在尝试,但失败了。
有没有一种巧妙的方法可以做到这一点,或者你是否需要单独对国家队进行排序,然后排除所有国家队?
答案 0 :(得分:11)
xsl:sort
条件:第一个将按首选/非首选项排序,第二个按名称按字母顺序排序:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/teams">
<teams>
<xsl:for-each select="team">
<xsl:sort select="not(@name = 'England' or @name='Northern Ireland'
or @name='Republic of Ireland'
or @name='Scotland' or @name='Wales')"
data-type="number"/>
<xsl:sort select="@name"/>
<team>
<xsl:value-of select="@name"/>
</team>
</xsl:for-each>
</teams>
</xsl:template>
</xsl:stylesheet>
请注意,您必须使用not()
反转第一个条件。原因是表达式的布尔结果被转换为数字(0表示false,1表示为true),因此将首先列出评估为“false”的项目。
答案 1 :(得分:6)
你可以这样做:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://tempuri.org"
exclude-result-prefixes="my"
>
<xsl:output method="xml" indent="yes" />
<my:data>
<my:nationalteams>
<my:team id="121" /><!-- Republic of Ireland -->
<my:team id="123" /><!-- England -->
<my:team id="126" /><!-- Northern Ireland -->
<my:team id="142" /><!-- Scotland -->
<my:team id="295" /><!-- Wales -->
</my:nationalteams>
</my:data>
<xsl:template match="teams">
<xsl:copy>
<xsl:variable name="national" select="
document('')/*/my:data/my:nationalteams/my:team
" />
<!-- national teams preferred -->
<xsl:apply-templates select="team[@id = $national/@id]">
<xsl:sort select="@name" />
</xsl:apply-templates>
<!-- other teams after them -->
<xsl:apply-templates select="team[not(@id = $national/@id)]">
<xsl:sort select="@name" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="team">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
可以将整个<my:data>
移动到辅助XML /配置文件,您也可以在其中取消“my”命名空间。
在那之后,一行需要一个小的改变:
<xsl:variable name="national" select="
document('config.xml')/data/nationalteams/team
" />
以上的输出有点不足为奇: - )
<teams>
<team id="123" name="England" />
<team id="126" name="Northern Ireland" />
<team id="121" name="Republic of Ireland" />
<team id="142" name="Scotland" />
<team id="295" name="Wales" />
<team id="49" name="Arsenal" />
<team id="299" name="Bolton" />
<team id="84" name="Chelsea" />
<team id="110" name="Liverpool" />
<team id="42" name="Manchester City" />
<team id="13" name="Manchester United" />
<team id="298" name="Tottenham Hotspur" />
</teams>
答案 2 :(得分:1)
您是否看过xsl:sort元素,您可以通过组合xsl:apply-templates和xsl:sort
来创建两个或多个排序条件Indeeed,这是一个示例,其中一些国家以预定义的顺序排在第一位, 所有其他人。 请注意,这些是元素,而不是上面的属性。
<xsl:sort select="not(CountryValue = 'Scotland')"/>
<xsl:sort select="not(CountryValue = 'India')"/>
<xsl:sort select="CountryValue"/>
示例结果:
国家
Scotland
Scotland
Scotland
India
Afghanistan
Afghanistan
Afghanistan
Afghanistan
Afghanistan
Afghanistan
Albania
Albania
Albania
Algeria
答案 3 :(得分:1)
在您的XSLT中,您是否可以使用扩展功能?
如果是这样,一种方法是在线修改现有节点列表,以创建新节点集,但每个节点上都有一个额外的“sortname”属性。然后,您可以遍历此新节点集,使用新的“sortname”属性进行排序:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml" />
<xsl:template match="/teams">
<xsl:variable name="extendedteams">
<xsl:for-each select="team">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:attribute name="sortname">
<xsl:choose>
<xsl:when test="@name='England' or @name='Northern Ireland' or @name='Republic of Ireland' or @name='Scotland' or @name='Wales'">1</xsl:when>
<xsl:otherwise>2</xsl:otherwise>
</xsl:choose>
<xsl:value-of select="@name" />
</xsl:attribute>
</xsl:copy>
</xsl:for-each>
</xsl:variable>
<xsl:copy>
<xsl:for-each select="exsl:node-set($extendedteams)/team">
<xsl:sort select="@sortname" />
<xsl:copy>
<xsl:copy-of select="@*[name() != 'sortname']" />
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
在上面的示例中,我在任何国家队前加上'1',在任何国内队名前加'2',然后对这个新属性进行排序。
请参阅Node Sets的信息,了解哪些XSLT处理器支持哪些扩展。