XPath для поиска ближайшего элемента предка, который содержит элемент с атрибутом с определенным значением
ancestor::foo[bar[@attr="val"]]
Я думал, что это сработает, но это не так. Мне нужно найти ближайший элемент foo
, который растет в дереве с дочерним элементом bar
, который, в свою очередь, имеет атрибут attr
val
.
Ответы
Ответ 1
Это должно работать:
//*[ancestor::foo[bar[@attr="val"]]]
или, альтернативно,
root/foo/bar[ancestor::foo[bar[@attr="val"]]]
соответствует второму элементу <bar>
<root>
<foo>
<bar attr="xxx"></bar>
</foo>
<foo>
<bar attr="val"></bar>
</foo>
<foo>
<bar attr="zzz"></bar>
</foo>
</root>
Ответ 2
Обновлено для отражения решения, предназначенного OP.
См. ответ @David
Для примера xml ниже,
<root>
<foo id="0">
<bar attr="val"/>
<foo id="1">
<bar attr="xxx"/>
</foo>
<foo id="2">
<bar attr="val">
<one>1</one>
<two>
<three>3</three>
</two>
</bar>
</foo>
</foo>
действительный xpath на обратной оси с < три > как контекст node, допустимым решением является
./ancestor::foo[bar[@attr='val']][position() = 1]
"./" не является обязательным. position() = 1 не является необязательным, так как в противном случае также будет возвращен предок foo
, удовлетворяющий предикатам.
Старый ответ: игнорировать
Это старый вопрос. но кто-нибудь заинтересован, следующее должно получить вас, что первоначальный вопрос.
Обратная ось
//bar[@attr='val']/ancestor::*[position()=1]
Передняя ось
//*[child::bar[@attr='val']]
Ответ 3
По моему мнению, лучший ответ был предоставлен человеком, который задал вопрос. Его решение должно было вернуть всех предков. Он хочет только ближайший, который находится с позицией() = 1, поэтому его выражение xpath должно быть слегка изменено на:
ancestor::foo[bar[@attr="val"] and position() = 1]
Если он пишет, что ancestor::foo[bar[@attr="val"]]
ничего не вернул, у него была другая проблема в его xml или в его предположении о текущем элементе его контекста оценки XPath.
Другие ответы (начиная с // ) на самом деле не отвечают на вопрос и даже если они случайно встретили потребность кого-то, поэтому они неэффективны:
они выбирают ВСЕ элементы в XML файле, применяя к ним фильтр потом.
Хотя то, что относительный xpath, предложенный мной или человеком, который задавал этот вопрос, просто будет искать через несколько элементов, начиная с текущего node до родителя и его родителя и т.д. - он будет очень эффективным даже с большим XML файлы.