Sql server SQL解析具有重复结构的XML

Sql server SQL解析具有重复结构的XML,sql-server,xml,Sql Server,Xml,我试图找出如何处理重复结构的XML。在下面的例子中,史密斯先生应该有两个孩子(迈克和汤姆),马古女士应该没有孩子。汤姆,史密斯先生的孩子有一个名叫萨莉的孩子,萨莉是史密斯先生的孙子。马古女士没有孩子,也没有孙子 DECLARE @tableXML table ( ID int NOT NULL, XMLdata xml NOT NULL ); DECLARE @testXML xml SET @testXML = '<parent> <name>Mr. Smit

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

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      
Mr. Smith   Tom       Sally
Ms. Magoo       
想法

谢谢! 迈克

试着这样做:

父母|子女|孙子 :-------- | :------- | :--------- 史密斯先生|迈克| 史密斯先生|汤姆萨利|萨利 马古女士 dbfiddle

用以下方法尝试:

父母|子女|孙子 :-------- | :------- | :--------- 史密斯先生|迈克| 史密斯先生|汤姆萨利|萨利 马古女士 dbfiddle

你很接近

使用
交叉应用xyz.nodes()
可以深入嵌套结构。但是,您必须将其视为树中的相对地址(当前位置)

像这样的线条

CROSS APPLY parent.p.nodes('/parent/child/name') AS children (c)
。。。您再次从根目录开始阅读,而不是从父目录开始

试着这样做:

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);
你很接近

使用
交叉应用xyz.nodes()
可以深入嵌套结构。但是,您必须将其视为树中的相对地址(当前位置)

像这样的线条

CROSS APPLY parent.p.nodes('/parent/child/name') AS children (c)
。。。您再次从根目录开始阅读,而不是从父目录开始

试着这样做:

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);

很好,您提供了一些复制粘贴测试代码+1从我的角度来看,这在深度上是有限的(在本例中为3级),还是您正在寻找一种通用方法(Sally可能也有孩子)?顺便问一下:
IsNull()
?如果是
NULL
您返回
NULL
?太好了,您提供了一些复制粘贴测试代码+1从我的角度来看,这在深度上是有限的(在本例中为3级),还是您正在寻找一种通用方法(Sally可能也有孩子)?顺便问一下:
IsNull()
?如果是
NULL
则返回
NULL
?如果Sally有一个兄弟(在“Tom”下面还有一个孩子),则在所有情况下,您都会阅读第一个。您缺少第三级的
.nodes()
。如果Sally有一个兄弟(在“Tom”下面还有一个孩子),您在所有情况下都会阅读第一级。您缺少第三级的
.nodes()
。。。
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);