我想定义某个元素中使用的字符串的排序。例如,< class> Senior< / class> <类>小型< /类> <类>大二< /类> <类>大一<类> 会在课堂上描述一个合理的排序。
有没有办法使用< xsl:sort select ='class'>那将按上面给出的顺序排序?
提前致谢。
答案 0 :(得分:5)
您在XSLT中可以做的是定义一个变量来表示您的自定义排序,如此
<xsl:variable name="inline-array">
<class sort="1">Senior</class>
<class sort="2">Junior</class>
<class sort="3">Sophomore</class>
<class sort="4">Freshman</class>
</xsl:variable>
然后,要访问此“数组”,您可以定义另一个变量来引用XSLT文档本身:
<xsl:variable name="array"
select="document('')/*/xsl:variable[@name='inline-array']/*" />
现在,您可以在排序时查找给定类名的排序属性(其中current()表示正在排序的当前节点)
<xsl:sort select="$array[. = current()/@class]/@sort" />
例如,这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="inline-array">
<class sort="1">Senior</class>
<class sort="2">Junior</class>
<class sort="3">Sophomore</class>
<class sort="4">Freshman</class>
</xsl:variable>
<xsl:variable name="array"
select="document('')/*/xsl:variable[@name='inline-array']/*"/>
<xsl:template match="/objects">
<xsl:copy>
<xsl:apply-templates select="object">
<xsl:sort select="$array[. = current()/@class]/@sort" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
将此应用于以下示例XML ...
<objects>
<object id="2" name="Junior Jo" class="Junior" />
<object id="1" name="Senior Sue" class="Senior" />
<object id="4" name="Freshman Frank" class="Freshman" />
<object id="3" name="Sophie Sophomore" class="Sophomore" />
</objects>
返回以下内容
<objects>
<object id="1" name="Senior Sue" class="Senior"></object>
<object id="2" name="Junior Jo" class="Junior"></object>
<object id="3" name="Sophie Sophomore" class="Sophomore"></object>
<object id="4" name="Freshman Frank" class="Freshman"></object>
</objects>
答案 1 :(得分:4)
您是否研究过Saxon的自定义排序规则?
例如,
<xsl:variable name="rules" select="'< Freshman < Sophomore
< Junior < Senior'" />
这使用该名称的Java类中的RuleBasedCollator格式。
要在排序中使用它(捎带Tim C的有用示例输入XML和样式表):
<xsl:apply-templates select="object">
<xsl:sort select="@class"
collation="http://saxon.sf.net/collation?rules={encode-for-uri($rules)}"/>
</xsl:apply-templates>
这与Tim C的解决方案具有相同的结果。 (使用Saxon PE 9.3.0.5测试。)
它不是一个xsl:函数,但它比数组提供了更多的灵活性,可以说更简洁。 AFAICT无法使用XSLT用户定义的函数创建自定义归类。既然您没有说出为什么需要xsl:function
,那么很难推测出哪些替代品可以满足您的需求。
对于完全xsl:类似功能的灵活性,您可以在Java中定义自己的collator;有关实现java.util.Comparator接口并在class
属性中指定比较器,请参阅http://www.saxonica.com/documentation/extensibility/collation.xml。