更多的反映是一个问题。我创建了一个存储过程,它将xml作为输入参数,并在查询数据时遇到一些问题。
这是其中一个查询
DECLARE @xVar XML
SET @xVar =
'<?xml version="1.0"?>
<Workflow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://ait.com/workflow/">
<Users>
<User ObjectId="1232">
<UserId>123</UserId>
</User>
<User ObjectId="1232">
<UserId>124</UserId>
</User>
</Users>
</Workflow>';
WITH XMLNAMESPACES(DEFAULT 'http://ait.com/workflow/')
SELECT [UserId] = reportdata.item.value('UserId[1]', 'varchar(36)')
FROM @xVar.nodes('//Workflow/Users/User') AS reportdata(item)
这只返回xml文档中的用户ID。如果我仔细查看select语句的最后部分
FROM @xVar.nodes('//Workflow/Users/User') AS reportdata(item)
它有效且似乎合乎逻辑,从根开始并指定路径,对我来说奇怪的是这也有效
FROM @xVar.nodes('//Users/User') AS reportdata(item)
甚至更奇怪这是有效的
FROM @xVar.nodes('//User') AS reportdata(item)
可能错过了XML Book for dummies中的某些页面,请有人启发我
答案 0 :(得分:1)
双//
表示它将为您提供与表达式匹配的所有后代节点。
这个//Workflow/Users/User
并不意味着“从根开始”。与根匹配的表达式类似于/Workflow/Users/User
。
因此,//User
将为您提供所有后代用户节点,无论它们在何处。
试试这个:
declare @XML xml =
'<root>
<user>1</user>
<user>2</user>
<child>
<user>3</user>
</child>
</root>'
select T.N.value('.', 'int') as Value
from @XML.nodes('//user') as T(N)
select T.N.value('.', 'int') as Value
from @XML.nodes('/user') as T(N)
select T.N.value('.', 'int') as Value
from @XML.nodes('/root/user') as T(N)
结果:
Value
-----------
1
2
3
(3 row(s) affected)
Value
-----------
(0 row(s) affected)
Value
-----------
1
2
(2 row(s) affected)
答案 1 :(得分:0)
这一点都不奇怪。
它的作用是搜索所有xml树,直到找到预期的用户叶。