Подтвердить что ты не робот

XPath 1.0, чтобы узнать, находится ли значение элемента в списке значений

Есть ли способ построить XPath, который оценивает, является ли значение элемента в предопределенном списке значений? Что-то похожее на это:

/Location/Addr[State='TX or AL or MA']

Что будет соответствовать узлам с элементами штата для Техаса, Алабамы или Массачусетса? Я знаю, что я могу распаковать выражение:

/Location/Addr[State='TX] or  /Location/Addr[State='AL'], etc...

Но это немного громоздко, поскольку xpaths довольно длинны, как и список значений. Мой google-fu не очень много говорит о проблеме...

4b9b3361

Ответ 1

Вы можете проверить несколько условий в тех же квадратных скобках:

/Location/Addr[State='TX' or State='AL' or State='MA']

Или, если у вас действительно длинный список, вы можете создать список состояний и использовать функцию contains().

/Location/Addr[contains('TX AL MA', State)]

Это будет отлично работать для двухбуквенных сокращений. Если вы хотите сделать его более надежным для более длинных строк, вы можете добавить некоторые пробелы на концах и проверить _TX_, _AL_ и т.д. (Где подчеркивания - это пробелы).

/Location/Addr[contains(' TX AL MA ', concat(' ', State, ' '))]

Ответ 2

Просто некромант, так как XPath 2.0 пришел.

С XPath 2.0 вы можете:

/Location/Addr[State=('TX', 'AL', 'MA')]

В качестве альтернативы, с XPath 1.0, вы можете использовать содержит в сочетании с длиной строки:

declare @tXML xml = '<svg>
<g>
<path></path>
<path data-objid="0000X1"></path>
<path data-objid="0000X2"></path>
<path data-objid="0000X3"></path>
</g>
</svg>';

-- select @tXML;

SELECT 
    c.p.value('(@data-objid)[1]', 'varchar(50)') AS 'DocumentID'
FROM @tXML.nodes('//node()[contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0]') AS c(p)


set @tXML.modify('delete //node()[contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0]'); 

select @tXML;