XPath получить подобный узел

#xml #xpath

#xml #xpath

Вопрос:

Я столкнулся со следующей проблемой.

Мой XML содержит несколько заказов со статусом. Они группируются вместе путем добавления целых чисел к тегам. Было бы проще, если бы у каждого заказа был свой собственный родительский тег, но именно так я получаю XML из внешнего приложения, и я не могу его изменить.

 <Values>
    <ORDER_1>506137</ORDER_1>
    <STATUS_1>3</STATUS_1>

    <ORDER_2>506129</ORDER_2>
    <STATUS_2>4</STATUS_2>

    <ORDER_3>51893</ORDER_3>
    <STATUS_3>1</STATUS_3>
</Values>
 

Что мне нужно сделать, так это найти порядок, соответствующий статусу ‘4’. Возможно ли это вообще с XPath? Похоже, мне нужен подстановочный знак для выбора статуса, но даже тогда, как мне найти соответствующий порядок?

К вашему сведению: XPath 1.0

Ответ №1:

Вы можете попробовать отфильтровать имя узла с помощью XPath name() и starts-with() функции, а затем использовать preceding-sibling для выбора соответствующего элемента заказа, например :

 //Values/*[starts-with(name(), 'STATUS_')][.=4]/preceding-sibling::*[1]
 

Приведенный выше XPath вернет этот узел :

 <ORDER_2>506129</ORDER_2>
 

Комментарии:

1. Спасибо. Видите ли вы какой-нибудь способ устранить зависимость от того, что все узлы находятся в одном и том же порядке? Таким образом, не используя previous-sibling . Кажется, что это может привести к ошибкам, если внешнее приложение должно добавить новый тег.

2. Вы можете отфильтровать предыдущий тег по имени, чтобы запрос не путал тег заказа с другим тегом, если таковой имеется, например : ....preceding-sibling::*[starts-with(name(), 'ORDER_')][1]

3. и если вы не уверены, будет ли ORDER_N это до или после STATUS_N использования then ../*[starts-with(....)] (все братья и сестры, предшествующие или следующие) вместо preceding-sibling::*[....]