I have an xml as show in the code below
I want to iterate though each node and insert one node after each TextReadingName node
DECLARE @XML XML =
N'<Steplist>
<Step>
<StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
<Rank>1</Rank>
<IsComplete>false</IsComplete>
<TextReadingName>bug-8588_Updated3</TextReadingName>
</Step>
<Step>
<StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
<Rank>2</Rank>
<TextReadingName>reading1</TextReadingName>
</Step>
</Steplist>';
--SELECT x.XmlCol.value('(StepId)[1]', 'nvarchar(max)') as StepId
--FROM @xml.nodes('/Steplist/Step') x(XmlCol)
This is how I want my new xml to look
N'<Steplist>
<Step>
<StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
<Rank>1</Rank>
<IsComplete>false</IsComplete>
<TextReadingName>bug-8588_Updated3</TextReadingName>
<TextReadingId>1</TextReadingId>
</Step>
<Step>
<StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
<Rank>2</Rank>
<TextReadingName>reading1</TextReadingName>
<TextReadingId>2</TextReadingId>
</Step>
</Steplist>';
I am able to select nodes as shown below but not able to iterate through each node and modify the data
--SELECT x.XmlCol.value('(StepId)[1]', 'nvarchar(max)') as StepId
--FROM @xml.nodes('/Steplist/Step') x(XmlCol)
I am looking same function as above but for inserting nodes
This is how I want my new xml to look with new node named TextReadingId after TextReading name
N'<Steplist>
<Step>
<StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
<Rank>1</Rank>
<IsComplete>false</IsComplete>
<TextReadingName>bug-8588_Updated3</TextReadingName>
<TextReadingId>1</TextReadingId>
</Step>
<Step>
<StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
<Rank>2</Rank>
<TextReadingName>reading1</TextReadingName>
<TextReadingId>2</TextReadingId>
</Step>
</Steplist>';
CodePudding user response:
You can use modify
with insert
, but the main drawback seems to be that SQL server only allows insert
into a single node, I couldn't combine it with a FLOWR expression, so I had to use an SQL WHILE loop to perform various modify
calls:
DECLARE @XML XML =
N'<Steplist>
<Step>
<StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
<Rank>1</Rank>
<IsComplete>false</IsComplete>
<TextReadingName>bug-8588_Updated3</TextReadingName>
</Step>
<Step>
<StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
<Rank>2</Rank>
<TextReadingName>reading1</TextReadingName>
</Step>
</Steplist>';
BEGIN
DECLARE @i int;
SELECT @i = @XML.value('count(Steplist/Step)', 'int');
WHILE @i > 0
BEGIN
SET @XML.modify('insert <TextReadingId>{sql:variable("@i")}</TextReadingId> as last into (/Steplist/Step[sql:variable("@i")])[1]');
SET @i = @i - 1;
END
END
SELECT @XML;