在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表格,并根据值和其他字段做一些事情(该部分正在运作,但由于与之前的比较 - 兄弟姐妹没有按照排序的方式工作,我遇到了问题
答案 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
)。