Ссылка на позицию текущего узла в выражении xpath


(Примечание: эта запись была отредактирована, чтобы показать конкретный случай использования. Смотрите снизу.)

Я хочу использовать текущее значение узла position () внутри выражения xpath (в котором изменяется контекст). К сожалению, я не вижу никакого простого способа сделать это, потому что current()/position() всегда кажется равным 1.

[я предполагаю, что это потому, что current()/position() говорит: "Какова позиция узла current () в контексте... одноузловый набор, содержащий только текущий().]

Чтобы быть точным, предположим, что у меня есть последовательность узлов $seq, и я хочу вернуть*n * - й узел в последовательности ($seq[n]), где n равно текущему значению position () (то есть значению position () до вычисления оператора).

Очевидно, что $seq[position()] не будет работать, потому что это расширяется до seq[position () = position ()], возвращая всю последовательность.

$seq[position (current ())] - это болтовня.

Единственное, что я смог найти, это кажется, может быть, работа-это

for $pos in position() return $seq[$pos]
Я предполагаю, что есть более простой способ.

Edit Мне было предложено привести более конкретный пример того, что я пытаюсь сделать. Я действительно нашел ответ первого лица достаточным для моих потребностей, хотя и не намного проще, чем то, что я придумал сам (вариант "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>
2 3

2 ответа:

Ну, поскольку вы отметили свой вопрос как XSLT 2.0, я бы использовал переменную, например

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

И затем использовать эту переменную, например

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

Примечание : я прошу прощения, что из-за ошибки в форматировании кода 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