Ссылка на текущую позицию узла в выражении xpath - PullRequest
3 голосов
/ 28 января 2012

(Примечание. Это сообщение было отредактировано для отображения конкретного случая использования. См. Внизу.)

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

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

Если говорить точнее, скажем, у меня есть последовательность узлов $ seq, и я хочу вернуть * n * -й узел в последовательности ($ seq [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>

Ответы [ 2 ]

0 голосов
/ 29 января 2012

Примечание : Я извиняюсь, что из-за ошибки в форматировании кода 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
0 голосов
/ 28 января 2012

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

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

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

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