2015-01-03 2 views
0
<?xml version="1.0" encoding="utf-8"?> 
<client name="test"> 
    <projects active="true"> 
    <project id="pr1" active="false" /> 
    <project id="pr2" active="true" /> 
    <project id="pr3" /> 
</projects> 
</client> 

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

Нам нужно получить все элементы проекта, следовательно, это должно вернуть

<project id="pr2" /> 
<project id="pr3" /> 

Я использовал следующие, но он не работает:

//project/ancestor-or-self::node()/@active[position()=1] 

Пожалуйста, помогите.

ответ

4

Следующее выражение XPath дает правильный результат:

/client/projects/project[@active = 'true' or (../@active = 'true' and not(@active = 'false'))] 

Это переводит к

/client/projects/project   Find an outermost element node "client", all its child 
           elements "projects" and all child elements "project" 
           of "projects". 
[@active = 'true'    But only return them if there is an attribute "active" 
           with a value "true" 
or (../@active = 'true'   or if its parent has an attribute "active" with its 
           value set to "true" 
and not(@active = 'false'))]  and at the same time there's no attribute "active" on 
           the "project" element set to "false". 

и возвращает

<project id="pr2" active="true"/> 
----------------------- 
<project id="pr3"/> 

Или, возможно, немного другой вариант имеет больше смысла:

/client/projects/project[@active = 'true' or (not(@active) and ../@active = 'true')] 

результат такой же.

1

Попробуйте

//project[(ancestor-or-self::*/@active)[last()] = 'true'] 
Смежные вопросы