在SQL中使用多级嵌套解析XML

时间:2015-03-17 20:46:37

标签: sql sql-server xml sql-server-2008

我正在尝试解析SQL中具有多个嵌套级别的XML。我在这里遇到的问题是如何编写我的查询通用,足以解析下面的XML,而不必硬编码节点路径e:g

EXEC sp_xml_preparedocument @handle OUTPUT, @xml

INSERT #Root(ID)
SELECT *
FROM OPENXML(@handle, '/Root')
WITH (ID VARCHAR(100))

INSERT #ConditionSet(Operator)
SELECT *
FROM OPENXML(@handle, '/Root/ConditionSet')
WITH (Operator VARCHAR(100))

INSERT #ConditionSet(Operator)
SELECT *
FROM OPENXML(@handle, '/Root/ConditionSet/ConditionSet')
WITH (Operator VARCHAR(100))

INSERT #ConditionSet(Operator)
SELECT *
FROM OPENXML(@handle, '/Root/ConditionSet/ConditionSet/ConditionSet')
WITH (Operator VARCHAR(100))

有没有更好的方法来解析SQL中的以下XML 并以表格形式表示所有数据?

<?xml version="1.0"?>
-<Root ID="414141" Source="AudienceBuilder">
  -<ConditionSet Operator="I">
    -<Condition Operator="E" ID="74373">
      -<Relationship ID="56756">
        <Relationship ID="67868"/>
      </Relationship>
      -<Value>
        <![CDATA[ABC]]>
      </Value>
    </Condition>
    -<ConditionSet Operator="O">
      -<Condition Operator="E" ID="6566">
        -<Relationship ID="7658">
          <Relationship ID="6547"/>
        </Relationship>
        -<Value>
          <![CDATA[DEF]]>
        </Value>
      </Condition>
      -<Condition Operator="E" ID="96967">
        -<Relationship ID="3884">
          <Relationship ID="9954"/>
        </Relationship>
        -<Value>
          <![CDATA[GHI]]>
        </Value>
      </Condition>
      -<ConditionSet Operator="A">
        -<Condition Operator="E" ID="31654">
          -<Relationship ID="57894">
            <Relationship ID="8532"/>
          </Relationship>
          -<Value>
            <![CDATA[JKL]]>
          </Value>
        </Condition>
        -<Condition Operator="E" ID="65636">
          -<Relationship ID="843">
            <Relationship ID="7473"/>
          </Relationship>
          -<Value>
            <![CDATA[MNO]]>
          </Value>
        </Condition>
      </ConditionSet>
    </ConditionSet>
  </ConditionSet>
</Root>

高度赞赏任何意见/建议:)

谢谢

Zeaous

1 个答案:

答案 0 :(得分:1)

假设您在名为@XML的SQL Server变量中使用了XML,则可以使用SQL Server 2005及更高版本中的本机XQuery 支持来更优雅高效地执行此操作:< / p>

DECLARE @XML XML = '...(your XML here).....' 

SELECT
    RootID = @xml.value('(/Root/@ID)[1]', 'int'),
    ConditionSetOperator = XC.value('@Operator', 'varchar(50)'),
    ConditionID =  XC2.value('@ID', 'int'),
    ConditionOperator = XC2.value('@Operator', 'varchar(50)')
FROM 
    @Xml.nodes('//ConditionSet') AS XT(XC)
CROSS APPLY
    xc.nodes('Condition') AS XT2(XC2)

这给了我一个输出

enter image description here

使用.nodes().value()之类的XQuery运算符,您可以轻松地将XML文档“碎化”为关系数据并根据需要进行存储。

@xml.nodes('//ConditionSet')的第一次调用将为每个匹配节点获取一个“伪”表 - 因此每个<ConditionSet>节点将在“伪”表XT中作为列{{ 1}},然后我可以使用像XC这样的XQuery方法轻松地从该XML片段中获取属性(或XML元素)。

或者我甚至可以获取每个.value()个节点的子节点<Condition>列表 - 使用<ConditionSet>并再次调用CROSS APPLY