4

(注意:这篇文章已经过编辑以显示特定的用例。见底部。)

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

[我认为这是因为 current()/position() 说“节点 current() 在...的上下文中的位置是什么......仅包含 current() 的单节点集。]

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

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

$seq[position(current())] 是乱码。

我唯一能找到的似乎可行的是

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

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

编辑 有人要求我给出一个更具体的例子来说明我正在尝试做的事情。实际上,我发现第一个人的答案足以满足我的需求,尽管并不比我自己想出的简单得多(“for $pos in position() return $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">

<---- 大量的各种测试---->

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

<--- 许多其他测试----->

</xsl:for-each>
4

2 回答 2

0

好吧,当您将问题标记为 XSLT 2.0 时,我将使用一个变量,例如

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

然后使用该变量,例如

<xsl:sequence select="$seq[$pos]"/>
于 2012-01-28T14:52:10.517 回答
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
于 2012-01-29T01:43:30.817 回答