2010-12-26 2 views
3

Если у меня есть две ссылки:Как найти первую ссылку на страницу, содержащую этот текст?

<div class="abc"> 
    <a id="def1" href="/definitely">Definitely 1</a> 
    <a id="def2" href="/definitely">Definitely 2</a>  
</div> 

И я хочу, чтобы определить первый (def1), я думал, что это будет работать:

var linkXPath = "//div[@class='abc']//a[contains(@href,'def')][1]"; 

Но это, кажется, не.

Что я делаю неправильно?

+0

Только что проверили. Ваше выражение работает. – Flack

+0

На каком языке? Если вы работаете в .NET, проблема может быть неправильной конфигурацией пространств имен в документе XML и процессоре XPath. –

+0

Кроме того, вы уверены, что работаете с хорошо сформированным XML? – Cameron

ответ

2

Ваше выражение XPath выбирает первый элемент a (с правой HREF) из каждогоdiv (который имеет правильный класс), который содержит один. Так что, если бы было два div s, которые соответствовали друг другу, каждый из которых соответствовал бы нескольким элементам a, вы бы установили набор повторных попыток, содержащий два элемента: первый a в первом div и первый a во втором div.

Чтобы выбрать только первый элемент всего набора результатов, используйте круглые скобки так:

(//div[@class='abc']//a[contains(@href,'def')])[1] 

Кроме этого, ваше выражение отлично работает для меня (проверено here).

+0

+1 Хорошее объяснение. –

3

Это FAQ почему

//someName[1] 

не выбирает первый элемент //someName.

Глядя на the definition of the // abbreviation, можно было бы понять, что на самом деле

//someName[1] 

эквивалентно:

/descendant-or-self::node()/someName[1] 

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

Таким образом, если есть два или более элемента someName, которые являются первыми дочерними элементами someName их родителя, все они выбраны.

Решение:

Вместо

//someName[1] 

использование:

(//someName)[1] 

Таким образом, в вашем конкретном случае использование:

(//div[@class='abc']//a[contains(@href,'def')]) [1] 

Помимо этого, ни одно из приведенных выше выражений не выберет любой узел, если в фактическом документе XML было указано пространство имен по умолчанию. Выбор узлов в документе с пространством имен по умолчанию - это самый большой FAQ по XPath. Чтобы найти решение, просто найдите «пространство имен по умолчанию» в этом теге SO и в любом месте в Интернете.