2014-12-10 2 views
0

У меня есть следующий xml, и мне нужно выбрать только b, имеющий тип desc в элементе, имеющем тип «header».xPath, который выбирает элементы между двумя конкретными дочерними элементами

<?xml version="1.0" encoding="UTF-8"?> 
<x> 
<a> 
    <b type="header" text="A." /> 
</a> 
<a> 
    <b type="desc" text="A1." /> 
</a> 
<a> 
    <b type="desc" text="A2." /> 
</a> 
<a> 
    <b type="desc" text="A3." /> 
</a> 
<a> 
    <b type="desc" text="A4." /> 
</a> 
<a> 
    <b type="header" text="B." /> 
</a> 
<a> 
    <b type="desc" text="B1." /> 
</a> 

Кодекс должен быть чем-то вроде этого: /x/a/b/[@type='desc']....

выход должен быть:

A1. 
A2. 
A3. 
A4. 

Заранее спасибо ...

ответ

1
/x/a/b[@type="header"]/../following-sibling::*[0][name()='a']/b[@type="desc"]/@text 

Непроверено бушель t вы найдете заголовок, вернитесь к a, возьмите первый следующий элемент, убедитесь, что он a, затем найдите дочерний элемент b, введите desc и возьмите текстовый атрибут.
......

+0

Привет Майк спасибо за ответ, но запрос возвращает ошибку, как: " Пространство имен с префиксом 'next-sibling' не объявлено. " – fjallstorm

+0

Пропущенный толстой кишки. Код изменился, но вы можете видеть, что происходит. – Mike

+0

Я тестировал, но этот не дает совпадения. – fjallstorm

1

Вы можете попробовать этот способ:

/x/a[following-sibling::a[b[@type='header']] and preceding-sibling::a[b[@type='header']]]/b[@type='desc']/@text 
+0

Это работает, но когда я ставлю другой заголовок ниже B1. он не даст такой же результат. – fjallstorm

+0

Хм ... Я не понимаю, почему вы ожидаете того же выхода, когда другой заголовок добавляется ниже B1. В этом случае B1 находится между двумя заголовками, поэтому он будет в списке вывода. – har07

1

По умолчанию XPath использует ребенок оси, но в этом случае вам нужно проверить предыдущие и следующие брат и сестра.

Сначала необходимо указать начальный узел a. Он должен содержать узел btypeheader и с textA..

a[b[@type="header" and @text = "A."]]

Он должен быть предшествующим сестринским узлов, которые вы хотите извлечь.

preceding-sibling::a[b[@type="header" and @text = "A."]]

Второй предел является первым последующим родственником этого узла с typeheader:

preceding-sibling::a[b[@type="header" and @text = "A."]]/following-sibling::a[b[@type="header"]][1]

Следующая сделать это условие для a узлов. Таким образом, вы выбираете только узлы между этими двумя:

/x/a[ 
    preceding-sibling::a[b[@type="header" and @text = "A."]] and 
    preceding-sibling::a[b[@type="header" and @text = "A."]]/following-sibling::a[b[@type="header"]][1] 
    ] 

Последние выбора атрибутов узлов b дочерних узлов text с атрибутом typedesc

/x/a[ 
    preceding-sibling::a[b[@type="header" and @text = "A."]] and 
    preceding-sibling::a[b[@type="header" and @text = "A."]]/following-sibling::a[b[@type="header"]][1] 
    ]/b[@type = "desc"]/@text 
+0

Это хорошо, но у меня есть только один параметр, который является заголовком текста «A.». поэтому у меня нет информации о следующем заголовке в моем запросе. Спасибо, в любом случае... – fjallstorm