引用当前节点在xpath表达式中的位置

时间:2012-01-28 14:45:49

标签: position xslt-2.0 xpath-2.0

(注意:此帖子已经过编辑以显示特定用例。请参阅底部。)

我想在xpath表达式(上下文发生变化)中使用当前节点的position()值。不幸的是,我没有看到任何简单的方法,因为current()/ position()似乎总是等于1.

[我假设这是因为current()/ position()表示“在仅包含current()的单节点集合的上下文中节点current()的位置是什么。”

具体来说,假设我有一系列节点$ seq,我想在序列中返回* n * th节点($ seq [n]),其中n等于position()的当前值(即是,在评估语句之前的position()的值。)

显然,$ seq [position()]将不起作用,因为它扩展为seq [position()= position()],返回整个序列。

$ seq [position(current())]是乱七八糟的。

我能找到的唯一可能有用的东西是

for $pos in position() return $seq[$pos]

我认为有一种更简单的方法。

修改 有人要求我提供一个更具体的例子,说明我正在尝试做什么。我实际上发现第一个人的答案足以满足我的需求,虽然不比我自己提出的要简单得多(“$ pos in position()返回$ correctOrder [$ pos]”选项)。

以下是实际情况:我有一组“会话”节点,每个节点都有一个@startTime属性。我想找到哪个与@startTime属性有关,或者至少不在适当的位置,如果输入文档的节点被@startTime正确排序。

这只是在每个会话节点上执行的许多测试之一。

我想要做的是创建一个序列,该序列的节点顺序正确,并将文档排序序列中的第n个元素与正确排序序列中的第n个元素进行比较。

这样的事情:

<xsl:template match="/">
<xsl:variable name="correctOrder" as="node()*">
<xsl:for-each select="session">
<xsl:sort select="@xs:dateTime(@startTime)"/>
<xsl:sequence select="."/>
</xsl:for-each>
</xsl:variable>

<xsl:for-each select="session">

&lt; ----各种各样的测试----&gt;

<xsl:if test="current()/@startTime eq 
$correctOrder[<-here I want to put the value "position()" had prior to this <xsl:if> statement->]/@startTime"
<error description="Node out of order."/>
</xsl:if>

&lt; ---很多其他测试-----&gt;

</xsl:for-each>

2 个答案:

答案 0 :(得分:0)

因为您已将问题标记为XSLT 2.0,我会使用变量,例如

<xsl:variable name="pos" as="xs:integer" select="position()"/>

然后使用该变量,例如

<xsl:sequence select="$seq[$pos]"/>

答案 1 :(得分:0)

注意:我很抱歉,由于SO代码格式中的错误,此代码没有缩进。

以下示例说明了使用相同位置的一般模式:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/> 

 <xsl:variable name="vSeq1" select="/*/names/*/text()"/>
 <xsl:variable name="vSeq2" select="/*/values/*/text()"/>

 <xsl:template match="/">
  <xsl:sequence select=
   "for $i in 1 to count($vSeq1)
     return
        ($vSeq1[$i], '=', $vSeq2[$i], '&#xA;')

   "/>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于以下XML文档

<t>
 <names> 
  <name>N1</name>
  <name>N2</name>
  <name>N3</name>
  <name>N4</name>
  <name>N5</name>
 </names>

 <values>
  <value>V1</value>
  <value>V2</value>
  <value>V3</value>
  <value>V4</value>
  <value>V5</value>
 </values>
</t>

产生了想要的正确结果

N1=V1
N2=V2
N3=V3
N4=V4
N5=V5