2013-05-09 2 views
1

Структура моего XMLКак получить все предыдущие узлы, независимо от текущей позиции

<root> 
    <Q id="a">1</Q> 
    <Q id="b">2</Q> 
    <Q id="c">3</Q> 
     <x> 
      <Q id="d">3.1</Q> 
      <Q id="e">3.2</Q> 
      <Q id="f">3.3</Q> 
     </x> 
    <Q id="g">4</Q> 
    <Q id="h">5</Q> 
</root> 

Это мое выражение XPath: // Q [@ ID = $ CurrentQid]/предшествующее :: Q

Я пытаюсь получить список предыдущих узлов Q независимо от текущей позиции (я передаю текущую позицию как параметр в мой xslt) , когда я нахожусь на узлах a, b, c, g, h, он возвращает мне правильный список предыдущих узлов. Бу, когда я нахожусь на d, e, f, он не работает правильно.

пример: когда мой текущий узел г возвращается, а, б, в, г, д, е но когда мой текущий узел е он возвращает только D, E, F хотя я ожидал чтобы быть a, b, c, d, e

Если кто-нибудь может найти решение, которое было бы очень хорошим.

Спасибо.

+2

Вы уверены, что это происходит с этим примером xml? Это не должно и не для меня. –

+1

Не могли бы вы отредактировать вопрос и добавить свой 'XSL', пожалуйста? – andyb

+1

Тем не менее я не вижу, что произойдет. Похоже, что предыдущий-сиблинг вместо предыдущего выполняется каким-то образом. Какой процессор xslt/xpaht вы используете? –

ответ

2

Применение:

($yourNode/preceding::Q | $yourNode/ancestor::Q)/@id 

XSLT - на основе проверки:

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

<xsl:variable name="vQg" select="(//Q[@id='g'])[1]"/> 
<xsl:variable name="vQf" select="(//Q[@id='f'])[1]"/> 

<xsl:template match="/"> 
    "Preceding" $vQg: 

    <xsl:for-each select= 
    "($vQg/preceding::Q | $vQg/ancestor::Q)/@id"> 
    <xsl:value-of select="concat(., ' ')"/> 
    </xsl:for-each> 
===================== 

    "Preceding" $vQf: 

    <xsl:for-each select= 
    "($vQf/preceding::Q | $vQf/ancestor::Q)/@id"> 
    <xsl:value-of select="concat(., ' ')"/> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

Когда это преобразование применяется на документе, при условии, XML:

<root> 
    <Q id="a">1</Q> 
    <Q id="b">2</Q> 
    <Q id="c">3</Q> 
     <x> 
      <Q id="d">3.1</Q> 
      <Q id="e">3.2</Q> 
      <Q id="f">3.3</Q> 
     </x> 
    <Q id="g">4</Q> 
    <Q id="h">5</Q> 
</root> 

выражение XPath оценивается в два раза (в течение двух Q элементов из вашего вопроса) и строковых значений результатов выводятся через пробел:

"Preceding" $vQg: 

    a b c d e f 
===================== 

    "Preceding" $vQf: 

    a b c d e 

Пояснение:

preceding:: ось не выбирает все предыдущие узлы в порядке документа - для этого необходимо также использовать ось ancestor::.

От W3C XPath 1.0 specification:

«• предшествующей оси содержит все узлы в том же документе, что и узел контекста , которые находятся перед узлом контекста в порядке документа, за исключением любых предков и за исключением узлы атрибутов и пространство имен узлы "

+0

Это хорошее объяснение предыдущих ::. Но в примере xml нет Q-предка для любого Q. Поэтому предыдущий :: должен иметь тот же результат. Или что мне здесь не хватает? –

+0

@ hr_117, О, я был введен в заблуждение от отступов в вопросе. Возможно, ОП не предоставил реальный документ (судя по отступу), и его проблема заключалась в том, чтобы не учитывать ось «предка». –

+0

Спасибо Dimitre> –

Смежные вопросы