Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List XPath 1.0查找元素';s值位于值列表中_List_Xpath_Expression - Fatal编程技术网

List XPath 1.0查找元素';s值位于值列表中

List XPath 1.0查找元素';s值位于值列表中,list,xpath,expression,List,Xpath,Expression,有没有一种方法可以构造一个XPath来评估元素的值是否在预定义的值列表中?类似于此: /Location/Addr[State='TX or AL or MA'] 哪个节点与德克萨斯州、阿拉巴马州或马萨诸塞州的州元素相匹配?我知道我可以打开表达式: /Location/Addr[State='TX] or /Location/Addr[State='AL'], etc... 但是这有点麻烦,因为XPath和值列表都很长。我的google fu在这个问题上没有出现太多…您可以在同一方括号内检

有没有一种方法可以构造一个XPath来评估元素的值是否在预定义的值列表中?类似于此:

/Location/Addr[State='TX or AL or MA']
哪个节点与德克萨斯州、阿拉巴马州或马萨诸塞州的州元素相匹配?我知道我可以打开表达式:

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

但是这有点麻烦,因为XPath和值列表都很长。我的google fu在这个问题上没有出现太多…

您可以在同一方括号内检查多个条件:

/Location/Addr[State='TX' or State='AL' or State='MA']
或者,如果您有一个很长的列表,您可以创建一个状态列表并使用
contains()
函数

/Location/Addr[contains('TX AL MA', State)]
这对于两个字母的州缩写很好。如果您想使其对较长字符串更健壮,可以在末尾添加一些空格,并检查
\u TX\u
\u AL\u
等(其中下划线是空格)


只是亡灵巫术,因为XPath 2.0已经出现

使用XPath 2.0,您可以执行以下操作:

/Location/Addr[State=('TX', 'AL', 'MA')]
或者,对于XPath 1.0,您可以将contains与字符串长度结合使用:

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;
以及插入和删除属性

-- insert attribute
-- SET @tXML.modify('insert attribute data-objid1 {"1"} into (//path[contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0])[1]')
-- delete attribute
-- and then, delete suddenly can remove several nodes - unlike insert or modify ... 
-- SET @tXML.modify('delete (//path[contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0])/@data-objid[1]')

-- only insert if there is no attribute "data-objid", therefore check with [not(@data-objid)]
-- (on replace, it doesn't create an attribute if it doesn't exist)
SET @tXML.modify('insert attribute data-objid {"1"} into (//path[not(@data-objid) and contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0])[1]')
SET @tXML.modify('replace value of (//path[contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0]/@data-objid)[1] with "Test"')
和变量:

DECLARE @testvar varchar(30); 
SET @testvar = 'abc'; 
SET @tXML.modify('insert attribute data-objid {sql:variable("@testvar")} into (//path[not(@data-objid)] and contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0)[1]')
SET @tXML.modify('replace value of (//path[contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0]/@data-objid)[1] with sql:variable("@testvar")')
SET @testvar = '0000X1,0000X2'; 
SET @tXML.modify('delete (//path[contains(sql:variable("@testvar"), @data-objid) and string-length(@data-objid) != 0])/@data-objid[1]')
注意,您应该将属性
数据objid
连接到
(“,“+objid+”,”)
,这样,如果testvar是
,0000X1a,0000X2b,“
,而不是
,0000x10000x2,”
,modify就不会意外地找到它(例如)

-- insert attribute
-- SET @tXML.modify('insert attribute data-objid1 {"1"} into (//path[contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0])[1]')
-- delete attribute
-- and then, delete suddenly can remove several nodes - unlike insert or modify ... 
-- SET @tXML.modify('delete (//path[contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0])/@data-objid[1]')

-- only insert if there is no attribute "data-objid", therefore check with [not(@data-objid)]
-- (on replace, it doesn't create an attribute if it doesn't exist)
SET @tXML.modify('insert attribute data-objid {"1"} into (//path[not(@data-objid) and contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0])[1]')
SET @tXML.modify('replace value of (//path[contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0]/@data-objid)[1] with "Test"')
DECLARE @testvar varchar(30); 
SET @testvar = 'abc'; 
SET @tXML.modify('insert attribute data-objid {sql:variable("@testvar")} into (//path[not(@data-objid)] and contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0)[1]')
SET @tXML.modify('replace value of (//path[contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0]/@data-objid)[1] with sql:variable("@testvar")')
SET @testvar = '0000X1,0000X2'; 
SET @tXML.modify('delete (//path[contains(sql:variable("@testvar"), @data-objid) and string-length(@data-objid) != 0])/@data-objid[1]')
DECLARE @testvar varchar(30); 
SET @testvar = ',0000X1a,0000X2b,'; 
SET @tXML.modify('delete (//path[contains(sql:variable("@testvar"), concat(",", @data-objid, ",")) and string-length(@data-objid) != 0])/@data-objid[1]')

SELECT @tXML