Как выделить эти элементы с помощью Xpath? - PullRequest
4 голосов
/ 11 июля 2009

У меня есть документ, что-то вроде этого:

<root>
   <A node="1"/>
   <B node="2"/>
   <A node="3"/>
   <A node="4"/>
   <B node="5"/>
   <B node="6"/>
   <A node="7"/>
   <A node="8"/>
   <B node="9"/>
</root>

Используя xpath, как я могу выбрать все элементы B, которые последовательно следуют за данным элементом A?

Это что-то вроде follow-silbing :: B, за исключением того, что я хочу, чтобы они были только , следующими сразу за элементами

Если я нахожусь на A (узел == 1), то я хочу выбрать узел 2. Если я нахожусь на A (узел == 3), то я ничего не хочу выбирать. Если я нахожусь на A (узел == 4), то я хочу выбрать 5 и 6.

Могу ли я сделать это в xpath? РЕДАКТИРОВАТЬ : оно входит в оператор выбора таблицы стилей XSL.


EDIT2 : я не хочу использовать атрибут узла для различных элементов в качестве уникального идентификатора. Я включил атрибут узла только для иллюстрации своей точки зрения. В настоящем документе XML у меня нет атрибута, который я использую в качестве уникального идентификатора. Xpath "follow-sibling :: UL [previous-sibling :: LI [1] / @ node = current () / @ node]" ключи на атрибуте узла, и это не то, что я хочу.

Ответы [ 3 ]

5 голосов
/ 11 июля 2009

Краткий ответ (при условии, что current () в порядке, так как он помечен xslt):

following-sibling::B[preceding-sibling::A[1]/@node = current()/@node]

Пример таблицы стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml"/>
    <xsl:template match="/">
        <xsl:apply-templates select="/root/A"/>
    </xsl:template>

    <xsl:template match="A">
        <div>A: <xsl:value-of select="@node"/></div>
        <xsl:apply-templates select="following-sibling::B[preceding-sibling::A[1]/@node = current()/@node]"/>
    </xsl:template>

    <xsl:template match="B">
        <div>B: <xsl:value-of select="@node"/></div>
    </xsl:template>
</xsl:stylesheet>

Удачи!

3 голосов
/ 13 июля 2009

Хотя ответ @Chris Nielsen является правильным, он оставляет неопределенность в тех случаях, когда сравниваемый атрибут не является уникальным. Более правильный способ решения этой проблемы:

following-sibling::B[
  generate-id(preceding-sibling::A[1]) = generate-id(current())
]

Это гарантирует, что preceding-sibling::A идентичен текущему A, а не просто сравнивает некоторые значения атрибутов. Если у вас нет атрибутов, которые гарантированно являются уникальными, это единственный безопасный способ.

1 голос
/ 11 июля 2009

Решение может состоять в том, чтобы сначала собрать все следующие узлы, используя following-sibling::*, захватить первый из них и потребовать, чтобы он был узлом 'B'.

following-sibling::*[position()=1][name()='B']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...