XSLT2: как ссылаться на атрибуты текущего узла в предикатах XPath2

Я разместил другой вопрос с этим как с одним аспектом. Мне сказали уточнить вопрос, но этот вопрос уже был довольно длинным и сложным, поэтому я создал новый.

Я хочу знать, существует ли стандартный способ ссылки на атрибут узла current в выражении XPath, проверяющем другое.

В качестве примера рассмотрим следующий XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <xsl:for-each select="potato/stem[eye]">
        In session <xsl:value-of select="@sessionID"/>, the potato had <xsl:value-of select="/potato/stem[@sessionID=@sessionID][scc]/scc/@leafnumber"/> s.c.c. leaves.
    </xsl:for-each>
</xsl:template>

(XML source at bottom of this question.) (Note that the for-each references nodes of type stem[eye] but the second value requested references nodes of type stem[scc], which are on a different branch of the source XML tree.)

Теперь, очевидно, часть «@sessionID=@sessoinID» в основном бессмысленна, потому что XPath воспринимает это как «значение атрибута sessionID узла должно равняться... значению атрибута sessionID узла».

Но я хочу сказать: «Проверьте, чтобы убедиться, что значение атрибута seesionID этого узла (тот, что в выражении XPath) совпадает с идентификатором сеанса узла любого узла /stem[eye], в котором я нахожусь. Сейчас."

Я не могу сделать это с переменной, потому что вам не разрешено объявлять переменную в предложении for-each.

Для справки, это источник XML. Его структура не такая, как хотелось бы, но это то, с чем мне приходится работать.

<?xml version="1.0" encoding="utf-8"?>
<potato>
<stem sessionID="1">
    <eye number = "25"/>
</stem>
<stem sessionID="3">
    <eye number = "33"/>
</stem>

<stem sessionID="1">
    <scc leafnumber = "234" />
</stem>
<stem sessionID="2">
    <scc leafnumber = "433"/>
</stem>
<stem sessionID="3">
    <scc leafnumber = "463"/>
</stem>

<stem sessionID="1">
    <agd leafnumber = "154"/>
</stem>
<stem sessionID="2">
    <agd leafnumber = "233"/>
</stem>
<stem sessionID="3">
    <agd leafnumber = "113"/>
</stem> 
</potato>

Результат, который я ищу:

В первом сеансе у картофеля было 234 s.c.c. листья.

В сеансе 3 у картофеля было 463 s.c.c. листья.

(Конечно, это всего лишь пример песочницы. Я понимаю, что, вероятно, есть простые способы выполнить приведенный выше вывод совершенно по-другому, но я надеюсь, что этот пример отвечает на мой вопрос, а именно, как использовать значения, связанные с текущим узлом. (скажем, в for-each) в предикате для XPath, ищущего другой.)


person David R    schedule 28.10.2011    source источник


Ответы (2)


В XSLT 1.0 вы можете использовать стандартную функцию current(), которая ссылается на узел, соответствующий текущему шаблону, или самый внутренний узел xsl:for-each:

/potato/stem[@sessionID=current()/@sessionID][scc]/scc/@leafnumber

или путем определения ключа (на глобальном уровне):

<xsl:key name="kPotById" match="stem[scc]" use="@sessionID"/>

и ссылаясь на этот ключ:

key('kPotById', @sessionID)/scc/@leafnumber

В XSLT 2.0 / XPath 2.0 у вас есть дополнительные способы выразить это (переменные диапазона):

for $thisSessionID in @sessionId
 return
    /potato/stem[@sessionID=$thisSessionID][scc]/scc/@leafnumber
person Dimitre Novatchev    schedule 28.10.2011
comment
Вау, я тоже не знал о ключе. Шеш! Какая у меня дерьмовая книга. Мне также нужно будет больше изучить переменные диапазона. Это очень полезно. - person David R; 29.10.2011
comment
@DavidR: Добро пожаловать. Кстати, я исправил опечатку в своем ответе - пропустил 2-й аргумент в примере key(). Теперь хорошо. - person Dimitre Novatchev; 29.10.2011

Используйте, например. current()/@sessionID для доступа к атрибуту sessionID текущего обрабатываемого узла (например, того, который обрабатывается for-each в вашем образце или шаблонами применения с обработкой push).

person Martin Honnen    schedule 28.10.2011
comment
БЛАГОДАРНОСТЬ! именно это я и пытался выяснить. Почему в моей книге XSLT никогда не упоминалась эта функция?? [XML для чайников тратит более 130 страниц на XSLT и никогда не упоминает эту функцию.] - person David R; 29.10.2011