我想知道编写 T-SQL 查询以从动态(多级)XML 结构返回节点的值或属性的正确方法是什么?
例如,如果 XML 如下所示:
<xml>
<a>
<b>1</b>
<c>
<node attrib="ant">2</node>
</c>
</a>
<a>
<node attrib="bird">3</node>
</a>
<a>
<b>
<c>
<node attrib="cat">4</node>
</c>
</b>
</a>
</xml>
返回 node 的值和/或属性的正确查询是什么?如本示例所示,node可以处于任何级别...
我尝试过这样的事情(没有成功):
SELECT
node.value('node[1]', 'varchar(50)') AS node
node.value('(node/@attrib)[1]', 'varchar(50)') AS attrib
FROM
xml.nodes('//xml/*') AS xml(node)
编辑: 感谢 StuartLC 在下面的回答...
根据下面的帮助,这是一个工作示例,其中也包含命名空间:
DECLARE @xml XML;
SET @xml = '
<xml xmlns:abc="xyz">
<a>
<b>1</b>
<c>
<abc:node attrib="ant">2</abc:node>
</c>
</a>
<a>
<abc:node attrib="bird">3</abc:node>
</a>
<a>
<b>
<c>
<abc:node attrib="cat">4</abc:node>
</c>
</b>
</a>
</xml>';
;WITH XMLNAMESPACES('xyz' AS ns)
SELECT
Nodes.node.value('.', 'varchar(50)') AS node,
Nodes.node.value('(./@attrib)[1]', 'varchar(50)') AS attrib
FROM
@xml.nodes('//ns:node') AS Nodes(node);
像这样:
SELECT
Nodes.node.value('.', 'varchar(50)') AS node,
Nodes.node.value('(./@attrib)[1]', 'varchar(50)') AS attrib
FROM
@xml.nodes('//node') AS Nodes(node);
因为您的
node
元素似乎可以位于 xml
文档中的任何位置,所以 //
用于搜索所有元素。一旦找到每个 node
,就可以使用 current()
或仅使用 .
来访问该节点。
编辑:用于解析表中的
xml
列(而不是 Xml @variable):
SELECT
Nodes.node.value('.', 'varchar(50)') AS node,
Nodes.node.value('(./@attrib)[1]', 'varchar(50)') AS attrib
FROM
[TableWithXmlColumn] xyz
cross apply xyz.XmlCol.nodes('//node') as Nodes(node);
如果您想要同一列中的值,您可以使用如下内容:
select T.X.value('.', 'varchar(50)')
from @XML.nodes('//*/text(), //@*') as T(X)
如何添加节点名称@mikaelEriksson?