在XML中选择,命名空间返回null

时间:2014-12-18 12:41:00

标签: sql-server xml

我从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

2 个答案:

答案 0 :(得分:3)

您需要使用WITH XMLNAMESPACES指定名称空间,并将命名空间归属于命名空间(我在这里使用过x)。请注意,您还需要将SET切换为SELECT才能使用此功能:

WITH XMLNAMESPACES ('some_namespace' as x)
SELECT @CSTAT =  @myDoc.value('(/x:infProt/x:cStat)[1]', 'VARCHAR(MAX)' );

SqlFiddle Demo

编辑,重新:带/不带名称空间的动态

您可以使用名称空间不可知函数local-name()来绕过名称空间:

SELECT @CSTAT =  @myDoc.value(
      '(/*[local-name()="infProt"]/*[local-name()="cStat"])[1]', 'VARCHAR(MAX)');

Updated Fiddle

使用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