SQL解析具有重复结构的XML

时间:2017-06-19 19:54:22

标签: sql-server xml

我试图弄清楚如何处理XML重复结构。在下面的例子中,史密斯先生应该有两个孩子(迈克和汤姆),而马古女士应该没有孩子。汤姆,史密斯先生的孩子有一个名叫莎莉的孩子,他是史密斯先生的孙子。 Magoo女士,没有孩子,也没有孙子。

DECLARE @tableXML table (
ID int NOT NULL,
XMLdata xml NOT NULL
);

DECLARE @testXML xml
SET @testXML =
'<parent>
    <name>Mr. Smith</name>
    <child>
        <name>Mike</name>
        <child />
    </child>
    <child>
        <name>Tom</name>
        <child>
            <name>Sally</name>
        </child>
    </child>
</parent>
<parent>
    <name>Ms. Magoo</name>
    <child>
        <name />
        <child />
    </child>
</parent>'

INSERT INTO @tableXML VALUES
 (1, @testXML);

SELECT 
    IsNull(parent.p.value('self::node()','varchar(100)'),Null) AS [Parent],
    IsNull(children.c.value('self::node()','varchar(100)'),Null) AS [Child],
    IsNull(grandChildren.g.value('self::node()','varchar(100)'),Null) AS [Grandchild]
FROM @tableXML
CROSS APPLY XMLdata.nodes('/parent/name') AS parent (p)
CROSS APPLY parent.p.nodes('/parent/child/name') AS children (c)
CROSS APPLY children.c.nodes('/parent/child/child/name') AS grandChildren (g)

以上结果集是:

Parent   |  Child  | Grandchild
---------------------------------
Mr. Smith   Mike      Sally
Mr. Smith   Tom       Sally
Mr. Smith             Sally
Ms. Magoo   Mike      Sally
Ms. Magoo   Tom       Sally
Ms. Magoo             Sally

结果应为:

Parent   |  Child  | Grandchild
---------------------------------
Mr. Smith   Mike      
Mr. Smith   Tom       Sally
Ms. Magoo       

思想?

谢谢! 麦克

2 个答案:

答案 0 :(得分:0)

以这种方式尝试:

SELECT 
    p2.lin.value('(./name)[1]','varchar(100)') AS [Parent],
    p3.lin.value('self::node()','varchar(100)') AS [Child],
    p3.lin.value('(./child)[1]','varchar(100)') AS [GrandChild]
FROM @tableXML
CROSS APPLY XMLdata.nodes('/parent') AS p2(lin)
CROSS APPLY p2.lin.nodes('child') AS p3(lin)
GO
Parent    | Child    | GrandChild
:-------- | :------- | :---------
Mr. Smith | Mike     |           
Mr. Smith | TomSally | Sally     
Ms. Magoo |          |           

dbfiddle Angular: Should I use this or $scope

答案 1 :(得分:0)

你很亲密......

使用CROSS APPLY xyz.nodes(),您可以深入挖掘嵌套结构。但是你必须在树中考虑相对地址(当前位置)。

使用类似

的行
CROSS APPLY parent.p.nodes('/parent/child/name') AS children (c)

...您正在从根目录再次阅读,而不是从parent.p

开始

试试这样:

SELECT 
    IsNull(parent.p.value('(name/text())[1]','varchar(100)'),Null) AS [Parent],
    IsNull(children.c.value('(name/text())[1]','varchar(100)'),Null) AS [Child],
    IsNull(grandChildren.g.value('(name/text())[1]','varchar(100)'),Null) AS [Grandchild]
FROM @tableXML
CROSS APPLY XMLdata.nodes('/parent') AS parent (p)
CROSS APPLY parent.p.nodes('child') AS children (c)
CROSS APPLY children.c.nodes('child') AS grandChildren (g);