2016-07-22 172 views
0

试图找出如何选择XSLT节点以下,兄弟当节点已经在XSLT 1.0被排序如下兄弟。我已经搜索但找不到排序节点的任何内容,因为它只选择未排序的节点的兄弟节点。选择排序节点

数据

<data> 
    <number order='4'>Four</number> 
    <number order='1'>One</number> 
    <number order='3'>Three</number> 
    <number order='2'>Two</number> 
</data> 

代码

<xsl:for-each select="/data/number"> 
    <xsl:sort select="@order"/> 
    <xsl:if test="position() mod 2 = 1"> 
     <xsl:value-of select="text()"/> 
     <xsl:text> - </xsl:text> 
     <xsl:value-of select="following-sibling::*/text()"/> 
    </xsl:if> 
</xsl:for-each> 

预期输出

One - Two 
Three - Four 

实际输出

One - Three 
Three - Two 
+0

可以尝试使用数字(位置())模2 = 1的测试中。由于位置()将返回不知道它是否会工作只是给一个尝试 –

回答

1

当你排序一个节点序列时,你会得到一个新序列中的相同节点。因为它们是相同的节点,所以它们拥有和它们一样的兄弟姐妹。如果将节点复制到结果树中,那么这些副本将有新的兄弟节点,但这是因为将它们写入结果树的操作,而不是因为排序操作。

把这个另一种方式:您要处理的是不是同级节点的顺序,所以你不能使用以下同胞来获取序列中的下一个节点。

处理节点的排序序列成为XSLT 2.0,这使得这样的序列将被绑定到变量容易得多。 XSLT 1.0只有节点集,因此特定顺序的节点序列只能暂时存在。

但在这种特殊情况下,它似乎很容易做到

<xsl:value-of select="."/> 
<xsl:if test="position() mod 2 = 1"> 
    <xsl:text> - </xsl:text> 
</xsl:if> 
+0

谢谢。我遇到的实际问题并没有通过解决方案解决,但您确实回答了我的问题是否可能。我将其标记为接受的答案,因为它回答了我最好的问题。 –

1

它仅选择未排序节点的兄弟节点。

这是正确的。你为什么不这样做简单:

<xsl:for-each select="/data/number"> 
    <xsl:sort select="@order"/> 
    <xsl:value-of select="."/> 
    <xsl:choose> 
     <xsl:when test="position() mod 2 = 1"> 
      <xsl:text>-</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:text>&#10;</xsl:text> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:for-each> 

注意,默认排序的数据类型是text;你可能想要:

<xsl:sort select="@order" data-type="number"/> 
+0

这适用于我的简单的例子,但我想利用这个代码的实际地方string.im是不会工作的一个HTML表格表格行标记被分割。 那么,这根本不可能得到一个分类节点的兄弟在XSLT 1.0吗? –

+1

如果你真的需要他们是兄弟姐妹,你必须首先将他们复制(或重新创建为新节点)到变量中。在XSLT 1.0中,您还需要将该变量转换为节点集,然后才能进一步处理它。 –