I need to iterate in child element called 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>';
I posted this problem in MSDN forum and Mr Yitzhak Khabinsky answer there for my scenario. Which is working but when there is nested group then code is not inserting nested group data.
My XML will have Sheet, Group, Lineitem and BM element. Only group can be nested. A group can have multiple nested child group and those child group may have Lineitem or BM element.
So the hierarchy is:
- Sheet may have multiple groups. sheet will not be nested.
- Group can have lineitems and also group can have multiple child group.
- lineitem will have BM element as child.
So only Group may have nested Nth child element.
Now here I am sharing a code which I got from MSDN forum which is working but when there is nested group then those nested group data is not getting inserted. My xquery
knowledge is not good. I assume little change in code will make the code working for Nested Group.
Sample code
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;
Please some one tell me what to change in code as a result it should work to handle nested group element.
EDIT
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;
--select * from Sheets
@Shnugo when i test your code with nested group then it could not consider those nested group. there is nested group in xml called 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"/>
A Group can have a as many as nested group and each nested group can have lineitem or not and each lineitem can have BM element or not.