2010-07-08 4 views
76

В Xpath я хочу выбрать элементы, которые соответствуют определенному значению.XPath - выбор элементов, которые равны значению

Пример данных XML:

<aaa id="11" > 
    <aaa id="21" > 
     <aaa id="31" ></aaa> 
     <bbb id="32" > 
      <aaa id="41" ></aaa> 
      <bbb id="42" ></bbb> 
      <ccc id="43" ></ccc> 
      <ddd id="44" >qwerty</ddd> 
      <ddd id="45" ></ddd> 
      <ddd id="46" ></ddd> 
     </bbb> 
    </aaa> 
    <bbb id="22" > 
     <aaa id="33" >qwerty</aaa> 
     <bbb id="34" ></bbb> 
     <ccc id="35" ></ccc> 
     <ddd id="36" ></ddd> 
     <ddd id="37" ></ddd> 
     <ddd id="38" ></ddd> 
    </bbb> 
    <ccc id="23" >qwerty</ccc> 
    <ccc id="24" ></ccc> 
</aaa> 

Теперь, используя XPath:

//ccc[.='qwerty'] 

я получаю правильные, ожидаемые результаты:

Name Value 
ccc  qwerty 

Теперь, используя XPath :

//aaa[.='qwerty'] 

Я получаю неожиданные результаты:

Name Value 
aaa  
aaa  qwerty 

И что мне особенно интересно, как выбрать любой элемент с таким значением

XPath:

//*[.='qwerty'] 

Мне очень странно неожиданные результаты:

Name Value 
aaa 
bbb 
ddd  qwerty 
bbb  qwerty 
aaa  qwerty 
ccc  qwerty 

Может кто-то объяснить эти результаты, и как исправить мои XPath выражения, чтобы получить больше ожидаемых результатов?

+0

Потому что XPath '. = 'отличается от XPath' text() = '. См. [** соответствующие текстовые узлы отличаются от совпадающих строковых значений **) (http://stackoverflow.com/a/34595441/290085), чтобы узнать, почему. – kjhughes

ответ

126

XPath спецификация. определяет строковое значение элемента в качестве конкатенации (в порядке документа) всех его потомков текстовых узлов.

Это объясняет «странные результаты».

«лучше» результаты могут быть получены с использованием выражений ниже:

//*[text() = 'qwerty'] 

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

//*[text() = 'qwerty' and not(text()[2])] 

Вышеприведенные выбирает каждый элемент в документе, который имеет только один дочерний текстовый узел и его значение: «QWERTY».

+0

Спасибо! Это работает. Я не знал о тексте(). Каково его определение? – developer

+3

@iHeartGreek: Рад, что он работает. Как насчет принятия/поддержки?'text()' является одним из возможных * node-tests * в XPath, что означает «это текстовый узел?». Другими узлами являются 'comment()', 'processing-instruction()' или просто 'node()'. –

12

Попробуйте

//*[text()='qwerty'] потому . Вашего текущего элемент

+1

Спасибо! Это работает. Я не знал о тексте(). Каково его определение? – developer