TSQL无法解析XML(名称空间)

时间:2017-07-01 14:02:47

标签: sql sql-server xml tsql

这是我的SQL:

    create table sqm (data xml)    
    insert into sqm
    select '<DataSet xmlns="http://www.bnr.ro/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bnr.ro/xsd nbrfxrates.xsd">
            <Cube date="2017-06-30">
                <Rate currency="AED">1.0867</Rate>
                <Rate currency="AUD">3.0665</Rate>
                <Rate currency="BGN">2.3284</Rate>
            </Cube>
            </DataSet>'

    select
    m.c.value('@date', 'date') as valuta
    from sqm as s
    outer apply s.data.nodes('/DataSet/Body/Cube') as m(c)

花了好几个小时试图找出我的SQL在数据库中保持返回NULL的原因后,我发现我的问题是由于XML开头的超链接引用(在DataSet之后)。 我真的想知道为什么会这样,以及我可以删除<DataSet结束>之间的所有内容。还有其他选择吗?

如果您能想到更好的标题,请编辑。

2 个答案:

答案 0 :(得分:2)

您需要使用WITH XMLNAMESPACES

声明命名空间

此外,您的示例XML没有Body元素,因此我将其从Xpath中删除。

Demo

WITH XMLNAMESPACES (DEFAULT 'http://www.bnr.ro/xsd')  

select
m.c.value('@date', 'date') as valuta
from sqm as s
outer apply s.data.nodes('/DataSet/Cube') as m(c)

或者您可以使用

select
m.c.value('@date', 'date') as valuta
from sqm as s
outer apply s.data.nodes('/*:DataSet/*:Cube') as m(c)

答案 1 :(得分:2)

除了Martin的解决方案(+1)之外,还有一个解决方案是使用 inline 声明XML命名空间:

-- Solution #1
select  m.c.value('@date', 'date') as valuta
from    sqm as s
outer apply s.data.nodes('declare default element namespace "http://www.bnr.ro/xsd";DataSet/Cube') as m(c)

-- Solution #2
select  m.c.value('@date', 'date') as valuta
from    sqm as s
outer apply s.data.nodes('
    declare default element namespace "http://www.bnr.ro/xsd";  
    declare namespace xsi="http://www.w3.org/2001/XMLSchema-instance";  
    declare namespace schemaLocation="http://www.bnr.ro/xsd nbrfxrates.xsd";  
    DataSet/Cube') as m(c)