我需要从XML列中读取属性的值。数据是一个声明了多个名称空间的XML:
<sd:objectData xmlns:sd="http://sd-uri">
<sd:object sourceKey="FC5A0A51-7FB6-4C64-A13E-D4B00649E80E">
<do:properties xmlns:do="http://do-uri">
<do:property name="DECISION">
<do:propertyValues clearExistingValues="true">
<do:propertyValue action="add" valueInteger="1000142" tag="Approve" />
</do:propertyValues>
</do:property>
</do:properties>
</sd:object>
</sd:objectData>
我想读取valueInteger
的值,即在此示例1000142
中。我尝试使用WITH XMLNAMESPACES()
,但我无法将它们组合在一起来定义两个别名。
答案 0 :(得分:3)
这对你有用吗?
DECLARE @XML xml = '
<sd:objectData xmlns:sd="http://sd-uri">
<sd:object sourceKey="FC5A0A51-7FB6-4C64-A13E-D4B00649E80E">
<do:properties xmlns:do="http://do-uri">
<do:property name="DECISION">
<do:propertyValues clearExistingValues="true">
<do:propertyValue action="add" valueInteger="1000142" tag="Approve" />
</do:propertyValues>
</do:property>
</do:properties>
</sd:object>
</sd:objectData>';
WITH XMLNAMESPACES ('http://sd-uri' AS sd,
'http://do-uri' AS do)
SELECT @XML.value('(/sd:objectData/sd:object/do:properties/do:property/do:propertyValues/do:propertyValue/@valueInteger)[1]','int') AS valueInteger;
答案 1 :(得分:2)
除了Larnu的答案(这是最好和正确的答案)之外,还有一些替代的快捷方式,如果您只想获得一个值:
此查询以四种不同的方法获取所需的值
SELECT @XML.value(N'(//*/@valueInteger)[1]',N'int') AS Super_easy_with_double_wildcard
,@XML.value(N'(//*:propertyValue/@valueInteger)[1]',N'int') AS Easy_with_namespace_wildcard
,@XML.value(N'declare namespace do="http://do-uri";
(//do:propertyValue/@valueInteger)[1]',N'int') AS with_local_declaration
,@XML.value(N'declare namespace do="http://do-uri";
declare namespace sd="http://sd-uri";
(/sd:objectData/sd:object/do:properties/do:property/do:propertyValues/do:propertyValue/@valueInteger)[1]',N'int') AS with_full_local_declaration;
一般建议是:尽量避免使用hassel 。如果你不打扰,只需要一个可读的,快速的捕获,你可以采取其中一种选择。
使用谓词,您可以放置过滤器:
SELECT @XML.value(N'(//*:property[@name="DECISION"]//*:propertyValue/@valueInteger)[1]',N'int') AS Example_with_predicate