我从Web服务接收XML文件,有时这个XML带有命名空间,有时它没有。
当我在@myDoc变量中包含XML时,select返回null。但是,如果我删除“xmlns”部分,则select会正常返回值。
我做错了什么?
DECLARE @myDoc xml
DECLARE @CSTAT VARCHAR(MAX);
SET @myDoc = '<infProt Id="ID311140002329206" xmlns="some_namespace">
<cStat>100</cStat>
</infProt>'
SET @CSTAT = @myDoc.value('(/infProt/cStat)[1]', 'VARCHAR(MAX)' )
SELECT @CSTAT
答案 0 :(得分:3)
您需要使用WITH XMLNAMESPACES
指定名称空间,并将命名空间归属于命名空间(我在这里使用过x
)。请注意,您还需要将SET
切换为SELECT
才能使用此功能:
WITH XMLNAMESPACES ('some_namespace' as x)
SELECT @CSTAT = @myDoc.value('(/x:infProt/x:cStat)[1]', 'VARCHAR(MAX)' );
编辑,重新:带/不带名称空间的动态
您可以使用名称空间不可知函数local-name()
来绕过名称空间:
SELECT @CSTAT = @myDoc.value(
'(/*[local-name()="infProt"]/*[local-name()="cStat"])[1]', 'VARCHAR(MAX)');
使用local-name()
时的强制性警告是,这显然会检测路径中具有相同名称的任何命名空间中的元素,除非您还使用namespace-uri
。
答案 1 :(得分:0)
对于value()方法,在select text
中声明命名空间DECLARE @myDoc xml
DECLARE @CSTAT VARCHAR(MAX);
SET @myDoc = '<infProt Id="ID311140002329206" xmlns="some_namespace">
<cStat>100</cStat>
</infProt>'
select @CSTAT = @myDoc.value('declare namespace x="some_namespace"; ( /x:infProt/x:cStat)[1]', 'VARCHAR(MAX)' )
select @CSTAT