【问题标题】:How to get XML element and attribute value in SQL?如何在 SQL 中获取 XML 元素和属性值?
【发布时间】:2017-12-23 05:33:18
【问题描述】:

我需要从 XML 中获取它在元素或属性中呈现的所有值。

例子:

DECLARE @XML = '<root>
                    <row1 attr1="x">1</row1>
                    <row2 attr2="x">2</row2>
                </root>'

这里,我的预期输出:

Column         Value
---------------------    
row1              1
attr1             x
row2              1
attr2             x

我可以使用以下查询分别获取元素和属性值。

SELECT  
    element.value('local-name(.)', 'VARCHAR(50)'), 
    element.value('.', 'VARCHAR(100)')  
FROM 
    @OldXML.nodes('/root/*') node(element)

SELECT  
    element.value('local-name(.)', 'VARCHAR(50)'), 
    element.value('.', 'VARCHAR(100)')  
FROM 
    @OldXML.nodes('/root/row1/@*') node(element)

SELECT  
    element.value('local-name(.)', 'VARCHAR(50)'), 
    element.value('.', 'VARCHAR(100)')  
FROM 
    @OldXML.nodes('/root/row2/@*') node(element)

但是,我需要在单个查询中获取值。

我浏览了很多方法,但找不到满足此要求的解决方案。

有什么办法吗?

【问题讨论】:

  • XML 支持高度特定于供应商 - 所以请添加标签以指定您是否使用mysqlpostgresqlsql-serveroracledb2 - 或完全不同的东西。

标签: mysql sql oracle postgresql sqlxml


【解决方案1】:

试试这个 UNION ALL

SELECT  
    element.value('local-name(.)', 'VARCHAR(50)'), 
    element.value('.', 'VARCHAR(100)')  
FROM 
    @OldXML.nodes('/root/*') node(element)
UNION ALL
SELECT  
    element.value('local-name(.)', 'VARCHAR(50)'), 
    element.value('.', 'VARCHAR(100)')  
FROM 
    @OldXML.nodes('/root/row1/@*') node(element)
UNION ALL
SELECT  
    element.value('local-name(.)', 'VARCHAR(50)'), 
    element.value('.', 'VARCHAR(100)')  
FROM 
    @OldXML.nodes('/root/row2/@*') node(element)

【讨论】:

    【解决方案2】:

    我不知道oracle对XQuery的支持有多深。您可以像这样转换您的 XML(SQL-Server-syntax):

    DECLARE @XML XML = '<root>
                          <row1 attr1="x" attrAdd="test">1</row1>
                          <row2 attr2="y">2</row2>
                          <row3>3</row3>
                        </root>';
    
    SELECT @XML.query
    (
    N'
        <root>
        {
        for $e in /root/*
        return <element type="element" name="{local-name($e)}" value="{$e/text()}"/>
        }
        {
        for $a in /root/*/@*
        return <element type="attr" parent="{local-name($a/..)}" name="{local-name($a)}" value="{$a}"/>
        }
        </root>
    '
    );
    

    结果

    <root>
      <element type="element" name="row1" value="1" />
      <element type="element" name="row2" value="2" />
      <element type="element" name="row3" value="3" />
      <element type="attr" parent="row1" name="attr1" value="x" />
      <element type="attr" parent="row1" name="attrAdd" value="test" />
      <element type="attr" parent="row2" name="attr2" value="y" />
    </root>
    

    另一种嵌套方法允许保持元素和属性之间的关系:

    SELECT @XML.query
    (
    N'
        <root>
        {
            for $e in /root/*
            return 
            <element tag="{local-name($e)}" value="{$e/text()}">
            {
                for $a in $e/@*
                return <attribute tag="{local-name($a)}" value="{$a}"/>
            }
            </element>
        }
        </root>
    '
    )
    

    结果

    <root>
      <element tag="row1" value="1">
        <attribute tag="attr1" value="x" />
        <attribute tag="attrAdd" value="test" />
      </element>
      <element tag="row2" value="2">
        <attribute tag="attr2" value="y" />
      </element>
      <element tag="row3" value="3" />
    </root>
    

    这两种方法都允许以表格形式读取数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-07
      • 1970-01-01
      • 2011-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-07
      • 1970-01-01
      相关资源
      最近更新 更多