【问题标题】:TSQL + XML Nodes Query & XMLNameSpaces - Getting a list of valuesTSQL + XML 节点查询和 XMLNameSpaces - 获取值列表
【发布时间】:2014-01-13 23:23:15
【问题描述】:

我一直在查看此处的示例,但我仍在努力正确查询我的 XML。 我一直在尝试通过 SQL xml.nodes 查询分解我的 XML,但我没有得到任何结果

这是 XML 示例:

<?xml version="1.0" encoding="UTF-8"?>
<gesmes:Envelope 
    xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" 
    xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
    <gesmes:subject>Reference rates
    </gesmes:subject>
    <gesmes:Sender>
        <gesmes:name>European Central Bank
        </gesmes:name>
    </gesmes:Sender>
    <Cube>
        <Cube time="2013-12-09">
            <Cube currency="USD" rate="1.3722"/>    
            <Cube currency="EUR" rate="1.0"/>
            </Cube>
        <Cube time="2013-12-10">
            <Cube currency="USD" rate="1.5555"/>
            <Cube currency="EUR" rate="1.2"/>
        </Cube>
    </Cube>
</gesmes:Envelope>

我需要将这些值插入到以下格式的表格中:

MyDate      Currency    Rate
2013-12-09  USD         1.3722
2013-12-09  EUR         1.0
2013-12-10  USD         1.5555
2013-12-10  EUR         1.2

经过多次尝试,我想我会尝试删除 gesmes* 节点并将其替换为,我实际上设法获得了值。

这是我使用的 SQL:

    declare @xml as xml;
    set @xml = 
    '<Root>
    <Cube>
        <Cube time="2013-12-09">
            <Cube currency="USD" rate="1.3722"/>
            <Cube currency="EUR" rate="1.0"/>
            </Cube>
        <Cube time="2013-12-10">
            <Cube currency="USD" rate="1.5555"/>
            <Cube currency="EUR" rate="1.2"/>
        </Cube>
    </Cube>
    </Root>'

    SELECT FXDate.value('@time', 'varchar(100)') AS FXDATE
        ,FXRates.value('@currency','varchar(100)') AS FXCurrency
        ,FXRates.value('@rate','varchar(100)') AS FXRate
    FROM @XML.nodes('Root/Cube/Cube') as Test(FXDate) 
    CROSS APPLY Test.FXDate.nodes('Cube') as Test2(FXRates);

然后我意识到它可能与命名空间(?)有关,因为我注意到其他人为其他人的查询指出了这一点。所以现在我很纠结如何让 SQL 与命名空间一起工作。由于此文件将作为参数发送,因此我必须使用名称空间。

这是我在使用命名空间的 SQL 时的尝试,但我在结果中一无所获。任何反馈/答案将不胜感激。谢谢!

declare @xml as xml;
set @xml = 
'<?xml version="1.0" encoding="UTF-8"?>
<gesmes:Envelope 
    xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" 
    xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
<gesmes:subject>Reference rates</gesmes:subject>
<gesmes:Sender>
    <gesmes:name>European Central Bank</gesmes:name>
</gesmes:Sender>
<Cube>
    <Cube time="2013-12-09">
        <Cube currency="USD" rate="1.3722"/>
        <Cube currency="EUR" rate="1.0"/>
        </Cube>
    <Cube time="2013-12-10">
        <Cube currency="USD" rate="1.5555"/>
        <Cube currency="EUR" rate="1.2"/>
    </Cube>
</Cube>
</gesmes:Envelope>'

select @xml

;with xmlnamespaces('http://www.ecb.int/vocabulary/2002-08-01/eurofxref' AS ns
,'http://www.gesmes.org/xml/2002-08-01' as ns2 )
SELECT FXDate.value('@time', 'varchar(100)')
FROM @XML.nodes('ns:gesmes/Cube/Cube/Cube') as Test(FXDate)

【问题讨论】:

    标签: sql sql-server xml tsql xml-namespaces


    【解决方案1】:

    试试这个:

    ;WITH XMLNAMESPACES (DEFAULT 'http://www.ecb.int/vocabulary/2002-08-01/eurofxref',
        'http://www.gesmes.org/xml/2002-08-01' AS ns)
    SELECT 
        FXDate = FXDate.value('../@time', 'varchar(100)'),
        FXCurrency = FXDate.value('@currency','varchar(100)'),
        FXRate = FXDate.value('@rate','varchar(100)') 
    FROM 
        @XML.nodes('ns:Envelope/Cube/Cube/Cube') as Test(FXDate) 
    

    基本上,您的 XML 中的 default XML 命名空间也应该用作查询中的默认 XML 命名空间,而第二个 XML 命名空间只是与您选择的一些前缀一起列出。

    此外,您的 XPath 在顶部使用 /Root 是错误的 - 在您的 XML 中根元素称为 &lt;Envelope&gt;

    我还删除了CROSS APPLY,因为它似乎没有必要——只需选择最低级别的&lt;Cube&gt; 条目,然后使用../@time 引用“父级”上的“上一级”属性&lt;Cube&gt; XML 元素。

    【讨论】:

      猜你喜欢
      • 2011-05-22
      • 2011-11-15
      • 2011-12-11
      • 2017-05-29
      • 2022-01-10
      • 1970-01-01
      • 2013-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多