Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XSLT排序与前面的同级::_Xslt_Sorting - Fatal编程技术网

XSLT排序与前面的同级::

XSLT排序与前面的同级::,xslt,sorting,Xslt,Sorting,在foreach循环中,我希望使用前面的同级:: <for-each..> <xsl:sort select="type"/> <xsl:when test="preceding-sibling::data[1]/type != type 将在第二个循环中比较silling=2(原始未排序)和type=1(因为它已排序) 有办法绕过它吗 更新:我的意图如下 before after data/type2 ty

在foreach循环中,我希望使用前面的同级::

<for-each..>
    <xsl:sort select="type"/>
    <xsl:when test="preceding-sibling::data[1]/type != type
将在第二个循环中比较silling=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

我有一个未排序的地址列表,其中类型为town,我需要一个按town排序的HTML表,并根据值和其他字段执行一些操作(这一部分是有效的,但由于与前面兄弟姐妹的比较在排序中不起作用,我发现了一个问题

节点之间的关系-父节点、子节点、兄弟节点等,不会因排序而改变。您可以按出生日期的顺序查看员工,但他们的父节点、子节点和兄弟节点与其他节点相同它们在原始树中确实存在,因为它们仍然是原始树中的节点


所以你已经说过你想如何解决你的问题,但这是行不通的。下一步是告诉我们问题是什么。

你想按类型对数据元素进行分组吗?让我们知道你想做什么,我们可能会帮上忙(正如@Michael Kay所说)


一个选项(在XSLT2.0中或具有节点集扩展)排序是将数据元素复制到一个新变量,然后在该新变量的节点集上运行
xsl:for each
。然后前面的同级关系将反映排序顺序。

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

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


检查当前节点是否是文档中的第一个节点(因此在排序集中也是如此)及其类型。(请注意,我使用的是
前面的
,而不是
前面的同级
,因为我不知道您的所有数据元素是否都将是原始文档中的同级。)


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

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

    <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>



我想按数据/类型对节点进行排序,然后再使用它。我如何制作该节点的排序副本?很高兴这个建议有所帮助。我确实认为,正如每个回答者所指出的,如果使用建议的分组功能,例如Meunchian,您的性能会更好。这是一个专有功能,不是无法移植。替换对我无效。第一个组按预期生成(
),但其余组重复(
,而不是预期的
)。这并不能提供问题的答案。若要评论或要求作者澄清,请在其帖子下方留下评论。我会声称“你的问题不连贯,这就是原因”这是一个答案。这不是OP问题的解决方案,但它是他们问题的答案。如果其他人,像我一样,通过谷歌来到这里,Michael Kay提供了一个类似问题的答案。
<xsl:when test="not(preceding::data/type = type)">
    <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>