【问题标题】:XSLT - Sorting multiple valuesXSLT - 对多个值进行排序
【发布时间】:2009-10-03 17:20:54
【问题描述】:

我已经创建了我的 XSLT,但我希望能够对数据进行排序,还添加了某种索引以便我可以将项目组合在一起,我遇到的困难是我想要排序的节点包含多个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>

所以如果我按&lt;subjects&gt; 排序,我会得到这个订单:

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

但我想要这样的输出:

English
Geography
History
Maths
Maths
Physical Education
Science
Technology

为&lt;subjects&gt; 中包含的每个主题输出 XML,因此 Item1 包含数学、英语和科学主题,因此我想输出该标题和描述 3 次,因为它与所有 3 个主题相关。

XSLT 中最好的方法是什么?

【问题讨论】:

    标签: xslt


    【解决方案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 的扩展功能。根据您使用的 XSLT 处理器,您可能需要为该处理器指定另一个命名空间。

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2012-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-10
        • 1970-01-01
        • 2023-02-05
        • 2016-03-14
        • 1970-01-01
        相关资源
        最近更新 更多