2015-07-27 4 views
1

У меня этот XML:XPath выбрать все до первого <br />

<test> 
    <a> 
    abc 
    <xyz /> 
    def 
    <br /> 
    ghi jkl 
    <br /> 
    mno pqr 
    </a> 
    <a> 
    xxx 
    </a> 
</test> 

В каждом <a> мне нужно, чтобы выбрать все подузлы (даже текстуальные) до первого <br />. Если нет <br />, мне нужно выбрать все подносы в заданном <a>. Таким образом, ожидаемый результат:

abc 
<xyz /> 
def 

и

xxx 

Я могу выбрать "все перед <br />", как это:

//a/*[following::br] 

... но он выбирает все до последняя<br />. Мне нужно выбрать все перед первым. Я пробовал вот так:

//a/*[following::br[1]] 

... с таким же результатом, как раньше. Они также не выбирают узлы в «не <br />» <a> s.

Как это сделать, используя (желательно одно) выражение XPath? Спасибо за любые предложения.

ответ

3

Вы можете попробовать этот способ (отформатирован для удобства чтения):

//a/node()[ 
    following-sibling::br[not(preceding-sibling::br)] 
     or 
    not(../br) 
] 

краткое объяснение о выражениях предикатов (содержание []) используется:

  • following-sibling::br[not(preceding-sibling::br)]: вычисляет true когда соответствующий узел, расположенный до , первый <br/>-выставляется как «<br>, который не имеет предшествующих родственный <br/>» -

  • not(../br): вычисляет true, когда родитель <a> не имеет никакого ребенка <br/>

+0

, кажется, работает, спасибо! Теперь я собираюсь изучить, как это работает :-) –

+3

@ RomanHocke работает над объяснением, проверьте это – har07

Смежные вопросы