Принятый ответ исправляет ошибку, но на самом деле не объясняет, почему исходное выражение пути пошло не так.
Вашего первое выражение выглядит следующим образом:
//table[//b[contains(@class, "2")]]
имеет два предикатов, один вложена в другом:
//table[//b[contains(@class, "2")]]
^---------------------^ inner predicate
^--------------------------^ outer predicate
Думайте предикаты в качестве фильтров, которые применяются к левому контексту предикат. В крайних случаях ни один, ни все промежуточные узлы результата не отбрасываются таким предикатом.
Каждый промежуточный результирующий узел поддерживается только в том случае, если предикат справа оценивает значение true
.В случае внутреннего предиката:
//b[contains(@class, "2")]
//b
дает множество промежуточных узлов элементов b
(все b
узлов элементов во всем документе), которые затем фильтруют с помощью предиката [contains(@class, "2")]
. Учитывая ваш входной документ XML, выражение внутри предиката возвращает true
для один из b
элементов.
Но //b[contains(@class, "2")]
в свою очередь, служит содержание внешнего предиката:
//table[outer predicate]
Теперь //table
выбирает в качестве промежуточного результата все table
узлы элементов во всем документе, и для каждого из них, выражение внутри проверяется предикат.
Важно отметить, что внешний предикат //b[contains(@class, "2")]
возвратит true
для обоихtable
элементов. Это потому, что для обоих из них верно, что где-то во всем документе есть элемент b
, атрибут class
содержит 2
.
Что вы на самом деле хотели бы сделать: оценить внешнее предикатное выражение с точки зрения каждого элемента table
- и принятый ответ показывает, как это сделать. А именно, используя .//
вместо //
в предикате.
Спасибо. был неправильным :) +1 – splash58
1) вы можете посмотреть демоверсию eval 2) ваше объяснение не соответствует правильности. В первом случае его достаточно, чтобы быть b [содержит] в любом месте документа. Но спасибо любым способом – splash58
Почему второй запрос не так? Мне кажется правильным: сначала он выбирает все (два) элемента 'table' в документе; для каждого из них выбираются все «b» потомки (по одному на таблицу); то для каждого из них проверяется атрибут @ @ class; предикат оказывается истинным для одного из них; для этого элемента 'b' выражение последнего шага возвращает его' ancestor: table'. Я ошибаюсь в своей интерпретации? Здесь [eval.in fork] (https://eval.in/516425) с текстовыми узлами, измененными для различения возвращаемых элементов таблицы. – CiaPan