Это 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 и в любом месте в Интернете.
Только что проверили. Ваше выражение работает. – Flack
На каком языке? Если вы работаете в .NET, проблема может быть неправильной конфигурацией пространств имен в документе XML и процессоре XPath. –
Кроме того, вы уверены, что работаете с хорошо сформированным XML? – Cameron