2011-10-17 62 views
2

我想定义某个元素中使用的字符串的顺序。例如,<类>高级< /类> <类>少年< /类> <类>大二< /类> <类>大一<类> 形容阶级合理排序。您可以使用XSLT中的函数定义自定义归类吗?

有没有办法使用< xsl:sort select ='class'>这将按上面给出的顺序进行排序?

在此先感谢。

+0

您使用的是XSLT 1.0还是2.0?撒克逊是你的选择吗? – LarsH

+0

我使用撒克逊和我可以使用任何版本:)通常,我使用3 –

回答

4

你看过萨克森的自定义整理扩展吗?

例如,

<xsl:variable name="rules" select="'&lt; Freshman &lt; Sophomore 
            &lt; Junior &lt; Senior'" /> 

它使用从Java类名的RuleBasedCollator格式。

要在排序使用它(捎带上添C'S有用的例子输入XML和样式表):

<xsl:apply-templates select="object"> 
    <xsl:sort select="@class" 
     collation="http://saxon.sf.net/collation?rules={encode-for-uri($rules)}"/> 
</xsl:apply-templates> 

这给了相同的结果,蒂姆C'S解决方案。 (使用Saxon PE 9.3.0.5进行测试。)

它不是xsl:函数,但它比数组提供了更多的灵活性,可以说是更加简洁。 AFAICT无法使用XSLT用户定义的函数创建自定义归类。既然你没有说你为什么想要一个xsl:function,那么很难猜测哪些替代品可以满足你的需求。

要获得完整的xsl:类似于功能的灵活性,您可以在Java中定义自己的collat​​or;有关实现java.util.Comparator接口并在class属性中指定比较器,请参见http://www.saxonica.com/documentation/extensibility/collation.xml

+1

我认为使用函数是唯一的方法,但这对于我来说同样适用 - 无需降级并使用Java。谢谢。 –

+2

这是一个非常好的答案 - 比所有其他选项都容易得多。 –

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']/*" /> 

现在,这可以让你查找给定类名的排序属性,当你排序(其中电流()表示当前节点进行排序)

<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> 
以下
+0

干净的解决方案,但我希望更简单。我希望能够定义一个xsl:函数来比较两个类的值(例如高级和低级)并返回一个值,指示gt,lt或eg。 –

相关问题