1

I have an XML variable that contains the following XML:

<Fruits>
  <Fruit>
    <Type>Apple</Type>
    <FruitID>1</FruitID>
    <MoreInfo>
      <Info Name="GreenApples" Value="3900" />
    </MoreInfo>
  </Fruit>
  <Fruit>
    <Type>Orange</Type>
    <FruitID>2</FruitID>
    <MoreInfo>
      <Info Name="Oranges" Value="1100" />
    </MoreInfo>
  </Fruit>
</Fruits>

I am trying to create a temp table that looks like that:

CREATE TABLE #XmlTable (
    email nvarchar(100),
    xmlNode XML
)

The output that I am aiming for is:

email | xmlNode

[email protected] | <Fruit><Type>Apple</Type><FruitID>1</FruitID><MoreInfo><Info Name="GreenApples" Value="3900" /></MoreInfo></Fruit>
[email protected] | <Fruit><Type>Orange</Type><FruitID>2</FruitID><MoreInfo><Info Name="Oranges" Value="1100" /></MoreInfo></Fruit>

The problem is that I don't know how to convert it to XML when I split it and insert it in the table.

I have the following SQL that is doing the job, but how do I convert it to XML?

INSERT INTO #XmlTable
SELECT  EOR.email, 
        xmlNode.Col.value('.', 'nvarchar(max)') AS XML
FROM @outputXML.nodes('/Fruits') xmlNode(Col)
CROSS APPLY @outputXML.nodes('/Fruits/Fruit/FruitID') xmlValue(i)
INNER JOIN #EmailsOfReceivers EOR
ON EOR.ID= xmlValue.i.value('.','nvarchar(max)')

It works fine, but of course the xmlNode column doesn't have the XML tags.

2 Answers 2

2

Here is one possible way :

INSERT INTO #XmlTable
SELECT  EOR.email, 
        fruit.x.query('.') AS XML
FROM @outputXML.nodes('/Fruits/Fruit') fruit(x)
INNER JOIN #EmailsOfReceivers EOR
ON EOR.ID = fruit.x.value('FruitID[1]','nvarchar(max)')

Fiddle demo

Basically, shred the XML on <Fruit> nodes, then you can use query() instead of value() to get the XML tags.

Side note: I'd return FruitID as int instead of nvarchar(max), if possible.

Sign up to request clarification or add additional context in comments.

5 Comments

@Apostrofix yes, it necessary to guarantee that there is maximum one element returned. There will be an error if you remove it.
What If the whole XML is wrapped in a ROOT tag? Would it be possible to get the Fruit nodes and do the join?
Not sure I understand this new problem you're asking now. If the entire XML structure remains the same other than the ROOT tag, simply change /Fruits/Fruit to /ROOT/Fruits/Fruit ..
Yes, that's exactly what I mean. But then the output is like: <Fruit><Type>Orange</Type><FruitID.... - Can I wrap it in the <Fruits> tag too?
like '<Fruits>' + CAST(fruit.x.query('.') AS varchar(max)) + '</Fruits>' ?
1

You can use .query('.') for your xml column:

DECLARE @outputXML XML

SELECT @outputXML = '<Fruits>
  <Fruit>
    <Type>Apple</Type>
    <FruitID>1</FruitID>
    <MoreInfo>
      <Info Name="GreenApples" Value="3900" />
    </MoreInfo>
  </Fruit>
  <Fruit>
    <Type>Orange</Type>
    <FruitID>2</FruitID>
    <MoreInfo>
      <Info Name="Oranges" Value="1100" />
    </MoreInfo>
  </Fruit>
</Fruits>'

INSERT INTO #XmlTable
SELECT  EOR.email, 
        xmlNode.Col.query('.') AS MyXML
FROM @outputXML.nodes('/Fruits/Fruit') xmlNode(Col)
INNER JOIN #EmailsOfReceivers EOR
ON EOR.ID = xmlNode.Col.value('FruitID[1]','nvarchar(max)')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.