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 не очень много говорит о проблеме...
Ответы
Ответ 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;