XSLT与前兄弟一起排序::

时间:2011-05-12 15:58:02

标签: xslt sorting

在foreach循环中,我想使用preceding-sibling ::

<for-each..>
    <xsl:sort select="type"/>
    <xsl:when test="preceding-sibling::data[1]/type != type

问题是foreach中的“type”与未排序的previous-sibling进行比较 例如

data1/type = 1 
data2/type = 2
data3/type = 1

将在第二个循环中比较silbling = 2(原始未排序)和type = 1(因为它已排序)

有办法吗?

更新:我的意图如下

before             after
data/type2         type1 value1
data/type1         type1 value2 
data/type1         and speaking in HTML a spacer here (I compare type2:value to preceding-sibling value
data/type2         type2 value1
                   type2 value2

我有一个未分类的地址列表,其中类型是一个城镇,我需要一个按城镇排序的HTML表格,并根据值和其他字段做一些事情(该部分正在运作,但由于与之前的比较 - 兄弟姐妹没有按照排序的方式工作,我遇到了问题

4 个答案:

答案 0 :(得分:4)

此解决方案现在适用于我:

    <xsl:variable name="sortedcopy">
      <xsl:for-each select="node1/node2/node3/data">
        <xsl:sort select="type" order="ascending"/>
        <xsl:copy-of select="current()"/>
      </xsl:for-each>
    </xsl:variable>
    <xsl:variable name="relItems" select="MSXML:node-set($sortedcopy)" />
    <xsl:for-each select="$relItems/data">
      <xsl:if test="not(preceding-sibling::data[1]/id = id)">
        <hr/>
      </xsl:if>
      <xsl:value-of select="val"/>
    </xsl:for-each>

答案 1 :(得分:1)

节点之间的关系 - 父节点,子节点,兄弟节点等不会通过排序更改。您可以按照出生日期的顺序查看员工,但他们仍然拥有与原始树中相同的父母,子女和兄弟姐妹 - 因为他们仍然是原始树中的节点。

所以你已经说过如何解决你的问题了,它不会起作用。下一步是告诉我们问题所在。

答案 2 :(得分:1)

您是否尝试按类型对数据元素进行分组?让我们知道你要做什么,我们可能会帮忙(正如@Michael Kay所说)。

一个选项(在XSLT 2.0中或使用节点集扩展)是将数据元素排序复制到新变量,然后在该新变量的节点集上运行xsl:for-each。然后前面的兄弟关系将反映排序的顺序。

答案 3 :(得分:0)

由于XSLT保证具有相同排序键的元素将按文档顺序出现,因此可以替换

<xsl:when test="preceding-sibling::data[1]/type != type">

<xsl:when test="not(preceding::data/type = type)">

检查当前节点是否是文档中的第一个节点(因此,在排序集中)是否为其类型。 (请注意,我使用的是preceding而不是preceding-sibling,因为我不知道您的所有数据元素是否都是原始文档中的兄弟姐妹。)

如果性能问题,您还可以使用xsl:key。另一种解决方案是分组(在XSLT 1.0中使用Muenchian分组,在XSLT 2.0中使用xsl:for-each-group)。