2009-10-03 47 views
1

我已经创建了XSLT但我还想能够对数据进行排序,还可以添加某种指数的,所以我可以组项目一起,难度林有就是我想要的节点排序依据包含多个值 - 值id喜欢排序。XSLT - 排序多个值

例如,下面是我的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包含主题数学,英语&科学,所以我想输出标题和描述3次,因为它与所有3个科目有关。

什么在XSLT的最好办法做到这一点?

+0

XSLT 1.0或2.0? – 2009-10-04 00:07:48

+0

这是XSLT 1.0 – CLiown 2009-10-04 10:43:09

回答

1

我认为这样做是通过使用节点集extenstion函数来完成多通道处理的一种方式。首先,你将遍历现有的主题节点,用逗号分割它们,以创建一组新的节点;每个主题一个。

接下来,您将通过在受顺序设置这个新的节点循环。

<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的扩展功能。根据您使用的XSLT处理器的不同,您可能必须为处理器指定其他名称空间。

您可能还需要科目做一些“微调”,因为你的XML样本中上面,没有在逗号分隔列表中的对象(技术)的一个前一个空间。

1

好,处理文本节点的内容是不是真的XSLT的任务。如果可以的话,您可能应该更改表示形式以将更多XML结构添加到主题元素中。否则,您将不得不使用XPath字符串函数编写一些非常聪明的字符串处理代码,或者可能使用基于Java的XSLT处理器并将字符串处理交给Java方法。这并不简单。