XPath, чтобы соответствовать только непосредственно после братьев и сестер - PullRequest
3 голосов
/ 04 января 2010

У меня есть следующий вид HTML. Содержимое сгруппировано по элементам <div "id=foo"> и <div "id=foo1"> с <div "style=padding…"> между ними.

Я пытаюсь выяснить, как создать выражение XPath, которое позволит мне вызвать "id=foo", чтобы вернуть брата <div> s с "style=padding…"

Получение <div id="foo"> тривиально. Однако я не могу просто сделать following-sibling на основе "style=padding…", потому что тогда он возвращает все соответствующие <div> s.

Мне нужен способ вернуть совпадающие <div> с, пока я не столкнусь с братом, который совпадает с "id=foo1". Я уверен, что есть простой подход, который мне не хватает!

<div id="foo">stuff...</div>

<div style="padding:2px; ">stuff...</div>

<div id="foo1">stuff...</div>

<div id="foo">stuff...</div>

<div style="padding:2px; ">stuff...</div>
<div style="padding:2px; ">stuff...</div>
<div style="padding:2px; ">stuff...</div>

<div id="foo1">stuff...</div>

Ответы [ 5 ]

5 голосов
/ 04 января 2010

Есть ли какая-то причина, по которой вы не можете использовать простой способ выбора всех div s, которые не имеют атрибутов id?

div[not(@id)]

Или, может быть, div с атрибутом стиля?

div[@style]

Если по какой-то причине это неприемлемо, вы можете пойти с чем-то более похожим на то, что вы думали:

div[@style][following-sibling::div[@id='foo1']]

Получает все div с атрибутами стиля, которые предшествуют div с определенным идентификатором. Это то, что вы просите?

Я полагаю, что ваш фактический исходный HTML-код менее тривиален, чем приведенный вами пример, но все перечисленные выше выражения XPath работают с вашим примером. Если бы вы могли предоставить более подробную информацию о том, каковы ваши ожидаемые результаты и с какими проблемами вы столкнулись, я могу вам помочь.

1 голос
/ 06 января 2010

Один не очень приятный на вид способ сделать то, что вы, похоже, намереваетесь сделать следующим образом (обратите внимание, что он основан на предположении, что у вас действительно есть несколько <div> с одним и тем же id !):

/*/div[@id='foo'][n]/following-sibling::div[@style='padding…']
[
  count(preceding-sibling::div[@id='foo']) 
  =
  count(/*/div[@id='foo'][n]/preceding-sibling::div[@id='foo']) + 1
]

Первая строка выражения XPath принимает любого <div style="padding…">, который является следующим братом n'th <div id="foo"> (это все, что вы получили самостоятельно, выбрав all из них ).

Затем он подсчитывает предшествующего брата <div id="foo"> для каждого из них и сопоставляет только те, которые имеют правильное число здесь, например, на один <div id="foo"> больше, чем соответствующий <div id="foo"> . Измените число n, чтобы выбрать другой набор.

Если на самом деле ваш ввод не имеет несколько элементов с одним и тем же идентификатором, он становится намного проще:

//div[@style='padding…'][preceding-sibling::div[@id][1]/@id = 'foo']

Это выбирает те <div style="padding…">, где первый предшествующий <div> (имеющий идентификатор) имеет значение идентификатора 'foo'. Как указано, это означает, что существует только один <div> с идентификатором 'foo', и что другие предшествующие <div> s делают не имеют идентификатор.

0 голосов
/ 05 января 2010

Ваша лучшая долгосрочная ставка - исправить HTML. Любое другое решение хрупко.

0 голосов
/ 04 января 2010

Я не думаю, что это возможно с помощью запросов XPath. Вам потребуется запомнить индекс выбранного div (не так сложно), но затем сравнить индекс его братьев и сестер с этим и первый # foo1 div, следующий за ним. Это, если возможно, очень сложный запрос XPath. XPath не позволяет легко сохранять несколько областей для сравнения элементов или атрибутов.

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

Если вам действительно нужно сделать это в XPath, вы хотите, чтобы div-разделители имели разные идентификаторы (для начала, несколько элементов с одинаковым идентификатором в любом случае недопустимы, поэтому используйте разные или имена классов), а затем каким-то образом сопоставить идентификаторы или имена классов на элементах div с отступом. Другими словами, измените HTML, чтобы обеспечить достаточное количество ссылок, вместо того, чтобы пытаться полностью решить его в XPath.

0 голосов
/ 04 января 2010

дайте им имя класса вместо использования встроенного стиля

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...