如何在SQL中获取XML元素和属性值?

时间:2017-07-18 11:16:47

标签: mysql sql oracle postgresql sqlxml

我需要从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)

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

我有很多方法,但我无法得到这个要求的解决方案。

有没有办法做到这一点?

2 个答案:

答案 0 :(得分:0)

试试这个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)

答案 1 :(得分:0)

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

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>

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