use*_*902 30 xpath expression list
有没有办法构造一个XPath来评估元素的值是否在预定义的值列表中?类似于此的东西:
/Location/Addr[State='TX or AL or MA']
Run Code Online (Sandbox Code Playgroud)
哪个匹配德克萨斯州,阿拉巴马州或马萨诸塞州的州元素?我知道我可以解压缩表达式:
/Location/Addr[State='TX] or /Location/Addr[State='AL'], etc...
Run Code Online (Sandbox Code Playgroud)
但这有点麻烦,因为xpath很长,值列表也是如此.我的google-fu在这个问题上没有太多关注......
Joh*_*ica 51
您可以在同一个方括号内检查多个条件:
/Location/Addr[State='TX' or State='AL' or State='MA']
Run Code Online (Sandbox Code Playgroud)
或者如果你有一个很长的列表,你可以创建一个状态列表并使用该contains()
功能.
/Location/Addr[contains('TX AL MA', State)]
Run Code Online (Sandbox Code Playgroud)
这适用于两个字母的州缩写.如果你想让它长字符串更强大的,你可以在两端添加一些空间和检查_TX_
,_AL_
等等(其中下划线是空格).
/Location/Addr[contains(' TX AL MA ', concat(' ', State, ' '))]
Run Code Online (Sandbox Code Playgroud)
只是暗示,因为XPath 2.0已经出现.
使用XPath 2.0,您可以:
/Location/Addr[State=('TX', 'AL', 'MA')]
Run Code Online (Sandbox Code Playgroud)
或者,使用XPath 1.0,您可以将contains与string-length结合使用:
DECLARE @tXML xml = '<svg>
<g>
<path></path>
<path data-objid="0000X1">tt</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 objID
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 AS del;
DECLARE @newRecord xml = '<path data-objid="0000X4"></path>';
-- SET @tXML.modify('insert sql:variable("@newRecord") as first into (/svg/g)[1]')
SET @tXML.modify('insert sql:variable("@newRecord") as last into (/svg/g)[1]')
SELECT @tXML AS ins;
Run Code Online (Sandbox Code Playgroud)