XSLT - 对多个值进行排序

时间:2009-10-03 17:20:55

标签: xslt

我已经创建了我的XSLT,但id喜欢能够对数据进行排序,还添加了某种索引,因此我可以将项目组合在一起,我遇到的难点是我要排序的节点包含多个values - 值id喜欢按排序。

例如,这是我的XML:

<item>
 <title>Item 1</title>
 <subjects>English,Maths,Science,</subjects>
 <description>Blah Blah Bah...</description>
</item>
<item>
 <title>Item 2</title>
 <subjects>Geography,Physical Education</subjects>
 <description>Blah Blah Bah...</description>
</item>
<item>
 <title>Item 3</title>
 <subjects>History, Technology</subjects>
 <description>Blah Blah Bah...</description>
</item>
<item>
 <title>Item 4</title>
 <subjects>Maths</subjects>
 <description>Blah Blah Bah...</description>
</item>

因此,如果按<subjects>排序,我会收到此订单:

English,Maths,Science,
Geography,Physical Education
History, Technology
Maths

但我想要这种输出:

English
Geography
History
Maths
Maths
Physical Education
Science
Technology

输出<subjects>中包含的每个主题的XML,因此Item1包含主题Maths,English&amp;科学所以我想输出那个标题和描述3次,因为它与所有3个科目相关。

XSLT中最好的方法是什么?

2 个答案:

答案 0 :(得分:1)

那么,处理文本节点的内容实际上并不是XSLT的任务。如果可以,您应该更改表示以在主题元素中添加更多XML结构。否则,您将不得不使用XPath字符串函数编写一些非常聪明的字符串处理代码,或者使用基于Java的XSLT处理器并将字符串处理移交给Java方法。这不是直截了当的。

答案 1 :(得分:1)

我认为一种方法是使用节点集扩展功能进行多次传递处理。首先,您将循环遍历现有主题节点,用逗号分隔它们,以创建一组新的项目节点;每个科目一个。

接下来,您将按主题顺序遍历此新节点集。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="urn:schemas-microsoft-com:xslt" extension-element-prefixes="exsl" version="1.0">

   <xsl:output method="text"/>

   <xsl:template match="/">
      <xsl:variable name="newitems">
         <xsl:for-each select="items/item">
            <xsl:call-template name="splititems">
               <xsl:with-param name="itemtext" select="subjects"/>
            </xsl:call-template>
         </xsl:for-each>
      </xsl:variable>
      <xsl:for-each select="exsl:node-set($newitems)/item">
         <xsl:sort select="text()"/>
         <xsl:value-of select="text()"/>
         <xsl:text> </xsl:text>
      </xsl:for-each>
   </xsl:template>

   <xsl:template name="splititems">
      <xsl:param name="itemtext"/>
      <xsl:choose>
         <xsl:when test="contains($itemtext, ',')">
            <item>
               <xsl:value-of select="substring-before($itemtext, ',')"/>
            </item>
            <xsl:call-template name="splititems">
               <xsl:with-param name="itemtext" select="substring-after($itemtext, ',')"/>
            </xsl:call-template>
         </xsl:when>
         <xsl:when test="string-length($itemtext) &gt; 0">
            <item>
               <xsl:value-of select="$itemtext"/>
            </item>
         </xsl:when>
      </xsl:choose>
   </xsl:template>

</xsl:stylesheet>

请注意,上面的示例使用Microsoft的Extension函数。根据您使用的XSLT处理器,您可能必须为处理器指定另一个命名空间。

您可能还需要对主题进行一些“修剪”,因为在上面的XML示例中,在逗号分隔列表中的某个主题(技术)之前有一个空格。