Querying XML data types which have xmlns node attr

2019-04-26 13:29发布

I have the following SQL query:

DECLARE @XMLDOC XML
SET @XMLDOC = '<Feed><Product><Name>Foo</Name></Product></Feed>'

SELECT  x.u.value('Name[1]', 'varchar(100)') as Name
from @XMLDOC.nodes('/Feed/Product') x(u)

This returns:

Name
----
Foo

However, if my <Feed> node has an xmlns attribute, then this doesn't return any results:

DECLARE @XMLDOC XML
SET @XMLDOC = '<Feed xmlns="bar"><Product><Name>Foo</Name></Product></Feed>'

SELECT  x.u.value('Name[1]', 'varchar(100)') as Name
from @XMLDOC.nodes('/Feed/Product') x(u)

Returns:

Name
----

This only happens if I have an xmlns attribute, anything else works fine.

Why is this, and how can I modify my SQL query to return results regardless of the attributes?

3条回答
Summer. ? 凉城
2楼-- · 2019-04-26 14:14

If your XML document has XML namespaces, then you need to consider those in your queries!

So if your XML looks like your sample, then you need:

-- define the default XML namespace to use
;WITH XMLNAMESPACES(DEFAULT 'bar')
SELECT   
    x.u.value('Name[1]', 'varchar(100)') as Name
from 
    @XMLDOC.nodes('/Feed/Product') x(u)

Or if you prefer to have explicit control over which XML namespace to use (e.g. if you have multiple), use XML namespace prefixes:

-- define the XML namespace 
;WITH XMLNAMESPACES('bar' as b)
SELECT   
    x.u.value('b:Name[1]', 'varchar(100)') as Name
from 
    @XMLDOC.nodes('/b:Feed/b:Product') x(u)
查看更多
可以哭但决不认输i
3楼-- · 2019-04-26 14:14

As well as the XMLNAMESPACES solution, you can also use the hideously bulky local-name syntax...

DECLARE @XMLDOC XML
SET @XMLDOC = '<Feed xmlns="bar"><Product><Name>Foo</Name></Product></Feed>'

SELECT  x.u.value('*[local-name() = "Name"][1]', 'varchar(100)') as Name
from @XMLDOC.nodes('/*[local-name() = "Feed"]/*[local-name() = "Product"]') x(u)
查看更多
Animai°情兽
4楼-- · 2019-04-26 14:27

You can define namespaces like:

WITH    XMLNAMESPACES ('bar' as b)
SELECT  x.u.value('b:Name[1]', 'varchar(100)') as Name
FROM    @XMLDOC.nodes('/b:Feed/b:Product') x(u)
查看更多
登录 后发表回答