sql-server - 通过 XQuery 在嵌套元素中遍历/迭代
问题描述
我需要在名为 Group 的子元素中进行迭代。
DECLARE @XMLData XML = N'<Nodes>
<Sheet FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" NodeText="Model1">
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" NodeText="Consensus Model">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" LineItemID="1225" NodeText="Net Revenue" />
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" LineItemID="1226" NodeText="Cost of Revenue">
<BM FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" BMID="01" NodeText="As % of Net Revenue" />
<BM FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" BMID="02" NodeText="Year over Year Growth" />
</LineItem>
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" NodeText="Test Group1">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" LineItemID="1225" NodeText="Test_Group_LI" />
</Group>
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" NodeText="Test Group2"/>
</Group>
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" NodeText="Segment Details">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" LineItemID="1227" NodeText="Cost of Revenue-GAAP" />
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" LineItemID="1228" NodeText="Gross Profit" />
</Group>
</Sheet>
<Sheet FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" NodeText="Model2">
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" NodeText="Key Financials">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" LineItemID="1235" NodeText="Total Operating Expenses-GAAP" />
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" LineItemID="1236" NodeText="EBITDA">
<BM FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" BMID="01" NodeText="BM_Test1" />
<BM FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" BMID="02" NodeText="BM_Test2" />
</LineItem>
</Group>
</Sheet>
</Nodes>';
我在 MSDN 论坛上发布了这个问题,Yitzhak Khabinsky 先生在那里回答了我的情况。哪个有效,但是当有嵌套组时,代码不会插入嵌套组数据。
我的 XML 将包含 Sheet、Group、Lineitem 和 BM 元素。只有组可以嵌套。一个组可以有多个嵌套的子组,这些子组可能有 Lineitem 或 BM 元素。
所以层次结构是:
- 工作表可能有多个组。sheet 不会被嵌套。
- 组可以有 lineitems,组也可以有多个子组。
- lineitem 将 BM 元素作为子元素。
所以只有 Group 可能有嵌套的第 N 个子元素。
现在在这里我分享一个我从 MSDN 论坛获得的代码,该代码正在运行,但是当有嵌套组时,那些嵌套组数据不会被插入。我的xquery
知识并不好。我认为代码的微小变化将使代码适用于嵌套组。
示例代码
DECLARE @XMLData XML = N'<Nodes>
<Sheet FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" NodeText="Model1">
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" NodeText="Consensus Model">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" LineItemID="1225" NodeText="Net Revenue" />
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" LineItemID="1226" NodeText="Cost of Revenue">
<BM FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" BMID="01" NodeText="As % of Net Revenue" />
<BM FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" BMID="02" NodeText="Year over Year Growth" />
</LineItem>
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" NodeText="Test Group1">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" LineItemID="1225" NodeText="Test_Group_LI" />
</Group>
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" NodeText="Test Group2"/>
</Group>
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" NodeText="Segment Details">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" LineItemID="1227" NodeText="Cost of Revenue-GAAP" />
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" LineItemID="1228" NodeText="Gross Profit" />
</Group>
</Sheet>
<Sheet FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" NodeText="Model2">
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" NodeText="Key Financials">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" LineItemID="1235" NodeText="Total Operating Expenses-GAAP" />
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" LineItemID="1236" NodeText="EBITDA">
<BM FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" BMID="01" NodeText="BM_Test1" />
<BM FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor="" BMID="02" NodeText="BM_Test2" />
</LineItem>
</Group>
</Sheet>
</Nodes>';
DECLARE @tblCSM_Details TABLE
(
[CSM_ID] [int] NOT NULL,
[ID] [int] IDENTITY(1,1) NOT NULL,
[ParentID] [int] NULL,
[Type] [varchar](30) NULL,
[DisplayInCSM] [varchar](200) NULL,
[FontName] [varchar](max) NULL,
[FontStyle] [varchar](max) NULL,
[FontSize] [varchar](max) NULL,
[UnderLine] [varchar](max) NULL,
[BGColor] [varchar](max) NULL,
[LineItemID] [int] NULL,
[BMID] [int] NULL,
[ColOrder] [int] NULL
);
DECLARE @SheetID INT,@GroupID INT,@LineItemID INT, @BMID INT;
DECLARE @SheetStartIndex INT, @SheetCount INT;
DECLARE @GroupStartIndex INT, @GroupCount INT;
DECLARE @LineitemStartIndex INT, @LineitemCount INT;
DECLARE @BMStartIndex INT, @BMCount INT;
SET @SheetStartIndex = 1;
SET @SheetCount = @XMLData.value('count(/Nodes/Sheet)', 'INT');
WHILE @SheetStartIndex <= @SheetCount BEGIN --Inserting sheet data
INSERT INTO @tblCSM_Details(CSM_ID,[ParentID],[Type],[DisplayInCSM],[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[LineItemID],[BMID],[ColOrder])
SELECT 1,0, c.value('local-name(.)','VARCHAR(30)') --'SHEET'
, c.value('@NodeText', 'VARCHAR(MAX)')
, c.value('@FontName', 'VARCHAR(MAX)')
, c.value('@FontStyle', 'VARCHAR(MAX)')
, c.value('@FontSize', 'VARCHAR(MAX)')
, c.value('@UnderLine', 'VARCHAR(MAX)')
, c.value('@BGColor', 'VARCHAR(MAX)')
, 0,0, @SheetStartIndex
FROM @XMLData.nodes('/Nodes/Sheet[position() = sql:variable("@SheetStartIndex")]') AS t(c);
SELECT @SheetID = SCOPE_IDENTITY();
--Inserting Group data
SET @GroupStartIndex = 1;
SET @GroupCount = @XMLData.value('count(/Nodes/Sheet[position() = sql:variable("@SheetStartIndex")]/Group)', 'INT');
WHILE @GroupStartIndex <= @GroupCount BEGIN --Inserting Group data
INSERT INTO @tblCSM_Details(CSM_ID,[ParentID],[Type],[DisplayInCSM],[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[LineItemID],[BMID],[ColOrder])
SELECT 1,@SheetID, c.value('local-name(.)','VARCHAR(30)') --'GROUP'
, c.value('@NodeText', 'VARCHAR(MAX)')
, c.value('@FontName', 'VARCHAR(MAX)')
, c.value('@FontStyle', 'VARCHAR(MAX)')
, c.value('@FontSize', 'VARCHAR(MAX)')
, c.value('@UnderLine', 'VARCHAR(MAX)')
, c.value('@BGColor', 'VARCHAR(MAX)')
, 0,0, @GroupStartIndex
FROM @XMLData.nodes('/Nodes/Sheet[position() = sql:variable("@SheetStartIndex")]/Group[position() = sql:variable("@GroupStartIndex")]') AS t(c);
SELECT @GroupID = SCOPE_IDENTITY();
--Inserting LineItem data
SET @LineitemStartIndex = 1;
SET @LineitemCount = @XMLData.value('count(/Nodes/Sheet[position() = sql:variable("@SheetStartIndex")]/Group[position() = sql:variable("@GroupStartIndex")]/LineItem)', 'INT');
WHILE @LineitemStartIndex <= @LineitemCount BEGIN
INSERT INTO @tblCSM_Details(CSM_ID,[ParentID],[Type],[DisplayInCSM],[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[LineItemID],[BMID],[ColOrder])
SELECT 1,@GroupID, c.value('local-name(.)','VARCHAR(30)') --'LINEITEM'
, c.value('@NodeText', 'VARCHAR(MAX)')
, c.value('@FontName', 'VARCHAR(MAX)')
, c.value('@FontStyle', 'VARCHAR(MAX)')
, c.value('@FontSize', 'VARCHAR(MAX)')
, c.value('@UnderLine', 'VARCHAR(MAX)')
, c.value('@BGColor', 'VARCHAR(MAX)')
, c.value('@LineItemID', 'INT')
, 0, @LineitemStartIndex
FROM @XMLData.nodes('/Nodes/Sheet[position() = sql:variable("@SheetStartIndex")]/Group[position() = sql:variable("@GroupStartIndex")]/LineItem[position() = sql:variable("@LineitemStartIndex")]') AS t(c);
SELECT @LineItemID = SCOPE_IDENTITY();
--Inserting BM data
SET @BMStartIndex = 1;
SET @BMCount = @XMLData.value('count(/Nodes/Sheet[position() = sql:variable("@SheetStartIndex")]/Group[position() = sql:variable("@GroupStartIndex")]/LineItem[position() = sql:variable("@LineitemStartIndex")]/BM)', 'INT');
WHILE @BMStartIndex <= @BMCount BEGIN --Inserting sheet data
INSERT INTO @tblCSM_Details(CSM_ID,[ParentID],[Type],[DisplayInCSM],[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[LineItemID],[BMID],[ColOrder])
SELECT 1,@LineItemID, c.value('local-name(.)','VARCHAR(30)') --BM
, c.value('@NodeText', 'VARCHAR(MAX)')
, c.value('@FontName', 'VARCHAR(MAX)')
, c.value('@FontStyle', 'VARCHAR(MAX)')
, c.value('@FontSize', 'VARCHAR(MAX)')
, c.value('@UnderLine', 'VARCHAR(MAX)')
, c.value('@BGColor', 'VARCHAR(MAX)')
, 0
, c.value('@BMID', 'INT')
, @BMStartIndex
FROM @XMLData.nodes('/Nodes/Sheet[position() = sql:variable("@SheetStartIndex")]/Group[position() = sql:variable("@GroupStartIndex")]/LineItem[position() = sql:variable("@LineitemStartIndex")]/BM[position() = sql:variable("@BMStartIndex")]') AS t(c);
SET @BMStartIndex += 1;
END;
SET @LineitemStartIndex += 1;
END;
SET @GroupStartIndex += 1;
END;
SET @SheetStartIndex += 1;
END;
SELECT * FROM @tblCSM_Details;
请有人告诉我要在代码中更改什么,因此它应该可以处理嵌套的组元素。
编辑
DECLARE @XMLData XML =
N'<Nodes>
<Sheet FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor=""
NodeText="Model1">
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor=""
NodeText="Consensus Model">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" LineItemID="1225" NodeText="Net Revenue"/>
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" LineItemID="1226" NodeText="Cost of Revenue">
<BM FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" BMID="01" NodeText="As % of Net Revenue"/>
<BM FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" BMID="02" NodeText="Year over Year Growth"/>
</LineItem>
<Group FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" NodeText="Test Group1">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" LineItemID="1225" NodeText="Test_Group_LI"/>
</Group>
<Group FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" NodeText="Test Group2"/>
</Group>
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor=""
NodeText="Segment Details">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" LineItemID="1227"
NodeText="Cost of Revenue-GAAP"/>
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" LineItemID="1228" NodeText="Gross Profit"/>
</Group>
</Sheet>
<Sheet FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor=""
NodeText="Model2">
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor=""
NodeText="Key Financials">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" LineItemID="1235"
NodeText="Total Operating Expenses-GAAP"/>
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" LineItemID="1236" NodeText="EBITDA">
<BM FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" BMID="01" NodeText="BM_Test1"/>
<BM FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" BMID="02" NodeText="BM_Test2"/>
</LineItem>
</Group>
</Sheet>
</Nodes>';
WITH Sheets AS
(
SELECT 'Sheet' AS [Type]
,ROW_NUMBER() OVER(ORDER BY A.sh) AS Id
,REPLACE(STR(ROW_NUMBER() OVER(ORDER BY A.sh),2),' ','0') AS SortString
,sh.query('.') Content
FROM @XMLData.nodes('/Nodes/Sheet') A(sh)
)
,SheetGroups AS
(
SELECT sh.* FROM Sheets sh
UNION ALL
SELECT 'Group'
,ROW_NUMBER() OVER(PARTITION BY sh.SortString ORDER BY A.gr)
,CONCAT(sh.SortString,REPLACE(STR(ROW_NUMBER() OVER(PARTITION BY sh.SortString ORDER BY A.gr),2),' ','0'))
,gr.query('.')
FROM Sheets sh
OUTER APPLY Content.nodes('Sheet/Group') A(gr)
)
,LineItems AS
(
SELECT shgr.* FROM SheetGroups shgr
UNION ALL
SELECT 'LineItem'
,ROW_NUMBER() OVER(PARTITION BY shgr.SortString ORDER BY A.li)
,CONCAT(shgr.SortString,REPLACE(STR(ROW_NUMBER() OVER(PARTITION BY shgr.SortString ORDER BY A.li),2),' ','0'))
,li.query('.')
FROM SheetGroups shgr
OUTER APPLY Content.nodes('Group/LineItem') A(li)
)
,BMs AS
(
SELECT li.* FROM LineItems li
UNION ALL
SELECT 'BM'
,ROW_NUMBER() OVER(PARTITION BY li.SortString ORDER BY A.bm)
,CONCAT(li.SortString,REPLACE(STR(ROW_NUMBER() OVER(PARTITION BY li.SortString ORDER BY A.bm),2),' ','0'))
,bm.query('.')
FROM LineItems li
OUTER APPLY Content.nodes('LineItem/BM') A(bm)
)
,FinalList AS
(
SELECT 1 AS CSM_ID
,ROW_NUMBER() OVER(ORDER BY BMs.SortString) AS ID
,BMs.SortString
,BMs.[Type]
,BMs.Content.value('(/*/@NodeText)[1]','varchar(max)') As DisplayInCSM
,BMs.Content.value('(/*/@FontName)[1]','varchar(max)') As FontName
,BMs.Content.value('(/*/@FontStyle)[1]','varchar(max)') AS FontStyle
,BMs.Content.value('(/*/@FontSize)[1]','varchar(max)') AS FontSize
,BMs.Content.value('(/*/@UnderLine)[1]','varchar(max)') AS UnderLine
,BMs.Content.value('(/*/@BGColor)[1]','varchar(max)') AS BGColor
,BMs.Content.value('(/*/@LineItemID)[1]','varchar(max)') AS LineItemID
,BMs.Content.value('(/*/@BMID)[1]','varchar(max)') AS BMID
,BMs.Id AS ColOrder
FROM BMs
WHERE Content IS NOT NULL
)
SELECT f1.CSM_ID
,f1.ID
,(SELECT f2.ID FROM FinalList f2 WHERE f2.SortString=LEFT(f1.SortString,LEN(f1.SortString)-2))
,f1.[Type]
,f1.DisplayInCSM
,f1.FontName
,f1.FontStyle
,f1.FontSize
,f1.UnderLine
,f1.BGColor
,f1.LineItemID
,f1.BMID
,f1.ColOrder
FROM FinalList f1
ORDER BY SortString;
--从表格中选择 *
@Shnugo 当我使用嵌套组测试您的代码时,它无法考虑那些嵌套组。xml 中有一个嵌套组,称为Group1 和 Group2
<Group FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" NodeText="Test Group1">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" LineItemID="1225" NodeText="Test_Group_LI"/>
</Group>
<Group FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" NodeText="Test Group2"/>
一个组可以有多个嵌套组,每个嵌套组可以有或没有 lineitem,每个 lineitem 可以有或没有 BM 元素。
解决方案
这是另一种处理方式。没有循环。
该方法使用递归 CTE。这样任何元素都可以在任何地方。您可以取消注释最后一个WHERE
子句以获取偶数属性。
此链接上的所有功劳都归于人们:如何从 SQL Server 中的 XML 值中获取元素名称列表
SQL
DECLARE @xml XML =
N'<Nodes>
<Sheet FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor=""
NodeText="Model1">
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor=""
NodeText="Consensus Model">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" LineItemID="1225" NodeText="Net Revenue"/>
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" LineItemID="1226" NodeText="Cost of Revenue">
<BM FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" BMID="01" NodeText="As % of Net Revenue"/>
<BM FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" BMID="02" NodeText="Year over Year Growth"/>
</LineItem>
<Group FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" NodeText="Test Group1">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" LineItemID="1225" NodeText="Test_Group_LI"/>
</Group>
<Group FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" NodeText="Test Group2"/>
</Group>
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor=""
NodeText="Segment Details">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" LineItemID="1227"
NodeText="Cost of Revenue-GAAP"/>
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" LineItemID="1228" NodeText="Gross Profit"/>
</Group>
</Sheet>
<Sheet FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor=""
NodeText="Model2">
<Group FontName="" FontStyle="" FontSize="" UnderLine="false" BGColor=""
NodeText="Key Financials">
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" LineItemID="1235"
NodeText="Total Operating Expenses-GAAP"/>
<LineItem FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" LineItemID="1236" NodeText="EBITDA">
<BM FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" BMID="01" NodeText="BM_Test1"/>
<BM FontName="" FontStyle="" FontSize="" UnderLine="false"
BGColor="" BMID="02" NodeText="BM_Test2"/>
</LineItem>
</Group>
</Sheet>
</Nodes>';
-- Solution # 2.
-- a thing of beauty.
WITH cte AS (
SELECT 1 AS lvl,
x.value('local-name(.)','NVARCHAR(MAX)') AS Name,
CAST(NULL AS NVARCHAR(MAX)) AS ParentName,
CAST(1 AS INT) AS ParentPosition,
CAST(N'Element' AS NVARCHAR(20)) AS NodeType,
x.value('local-name(.)','NVARCHAR(MAX)') AS FullPath,
x.value('local-name(.)','NVARCHAR(MAX)')
+ N'['
+ CAST(ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS NVARCHAR)
+ N']' AS XPath,
ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS Position,
x.value('local-name(.)','NVARCHAR(MAX)') AS Tree,
x.value('text()[1]','NVARCHAR(MAX)') AS Value,
x.query('.') AS this,
x.query('*') AS t,
CAST(CAST(1 AS VARBINARY(4)) AS VARBINARY(MAX)) AS Sort,
CAST(1 AS INT) AS ID
FROM @xml.nodes('/*') a(x)
UNION ALL
SELECT p.lvl + 1 AS lvl,
c.value('local-name(.)','NVARCHAR(MAX)') AS Name,
CAST(p.Name AS NVARCHAR(MAX)) AS ParentName,
CAST(p.Position AS INT) AS ParentPosition,
CAST(N'Element' AS NVARCHAR(20)) AS NodeType,
CAST(p.FullPath + N'/' + c.value('local-name(.)','NVARCHAR(MAX)') AS NVARCHAR(MAX)) AS FullPath,
CAST(p.XPath + N'/'+ c.value('local-name(.)','NVARCHAR(MAX)')
+ N'['
+ CAST(ROW_NUMBER() OVER(PARTITION BY c.value('local-name(.)','NVARCHAR(MAX)') ORDER BY (SELECT 1)) AS NVARCHAR)
+ N']' AS NVARCHAR(MAX)) AS XPath,
ROW_NUMBER() OVER(PARTITION BY c.value('local-name(.)','NVARCHAR(MAX)')
ORDER BY (SELECT 1)) AS Position,
CAST( SPACE(2 * p.lvl - 1) + N'|' + REPLICATE(N'-', 1) + c.value('local-name(.)','NVARCHAR(MAX)') AS NVARCHAR(MAX)) AS Tree,
CAST( c.value('text()[1]','NVARCHAR(MAX)') AS NVARCHAR(MAX) ) AS Value, c.query('.') AS this,
c.query('*') AS t,
CAST(p.Sort + CAST( (lvl + 1) * 1024 + (ROW_NUMBER() OVER(ORDER BY (SELECT 1)) * 2) AS VARBINARY(4)) AS VARBINARY(MAX) ) AS Sort,
CAST((lvl + 1) * 1024 + (ROW_NUMBER() OVER(ORDER BY (SELECT 1)) * 2) AS INT)
FROM cte p
CROSS APPLY p.t.nodes('*') b(c))
, cte2 AS (
SELECT lvl AS Depth,
Name AS NodeName,
ParentName,
ParentPosition,
NodeType,
FullPath,
XPath,
Position,
Tree AS TreeView,
Value,
this AS XMLData,
Sort, ID
FROM cte
UNION ALL
SELECT p.lvl,
x.value('local-name(.)','NVARCHAR(MAX)'),
p.Name,
p.Position,
CAST(N'Attribute' AS NVARCHAR(20)),
p.FullPath + N'/@' + x.value('local-name(.)','NVARCHAR(MAX)'),
p.XPath + N'/@' + x.value('local-name(.)','NVARCHAR(MAX)'),
1,
SPACE(2 * p.lvl - 1) + N'|' + REPLICATE('-', 1)
+ N'@' + x.value('local-name(.)','NVARCHAR(MAX)'),
x.value('.','NVARCHAR(MAX)'),
NULL,
p.Sort,
p.ID + 1
FROM cte p
CROSS APPLY this.nodes('/*/@*') a(x)
)
SELECT ROW_NUMBER() OVER(ORDER BY Sort, ID) AS ID,
ParentName, ParentPosition,Depth, NodeName, Position,
NodeType, FullPath, XPath, TreeView, Value, XMLData
, XMLData.value('*[1]/@NodeText','VARCHAR(30)') AS NodeText
, XMLData.value('*[1]/@FontName','VARCHAR(30)') AS FontName
, XMLData.value('*[1]/@FontStyle','VARCHAR(30)') AS FontStyle
FROM cte2
WHERE cte2.NodeType = 'Element';
推荐阅读
- python - Py2app 应用程序无法使用 tensorflow
- javascript - 使用 HTMLElement.click() 方法时防止 JavaScript 冒泡 DOM
- javascript - Chrome 扩展通过 chrome.runtime.onMessage 传递当前选项卡 url
- java - Jackson 将 JSON 属性反序列化为不同的 Java 对象
- python - How do I save my image which is decoded from tfrecord after plotting a box on it using matplotlib?
- python - 变量后的Python逗号
- android - 在 Animation 类中找不到名称为 mListener 的字段
- php - 对 wordpress 的 SVG 支持
- reactjs - 如何使用 reactjs 验证一些输入?
- flutter - Flutter TextFormFiled inside the Card with elevation