2

I have following example table

enter image description here

Code here

CREATE TABLE XMLData
(
    NodeName NVARCHAR(255),
    AttributA NVARCHAR(255),
    AttributB NVARCHAR(255),
    AttributC NVARCHAR(255),
) 

INSERT INTO XMLData VALUES 
('RowA','','abcd','efgh'),
('RowB','wxyz',NULL,NULL),
('RowC',NULL,'qwer','tyui'),
('RowD','stuv','erty','fghj')

SELECT * FROM dbo.XMLData

How can I get following XML ?

<NodeA>
  <NodeB />
  <NodeC AttributeX="">
    <RowA AttributeA="" AttributeB="abcd" AttributeC="efgh" />
    <RowB AttributeA="wxyz" />
    <RowC AttributeB="qwer" AttributeC="tyui" />
    <RowD AttributeA="stuv" AttributeB="erty" AttributeC="fghj" />
  </NodeC>
</NodeA>

I am beginner with XML, but I tried to play with something like this

SELECT
    (
    SELECT
        (
        SELECT '' AS '@AttributeX' FOR XML PATH('NodeC'),TYPE
        -- How to get table rows here ?
        )
    FOR XML PATH('NodeB'),TYPE -- Here it creates additional end NodeB tag
    )
FOR XML PATH('NodeA'),TYPE
5
  • 1
    Are you sure, that you really want exactly this output? It is not possible without dynamic SQL to set the Element's names dynamically. Normally I'd think of an Element "Row" with an attribut "RowID" which gets the values "RowA", "RowB" ... With this structure you could not analyse this with .nodes() ... Commented Feb 18, 2016 at 15:42
  • 1
    Btw: This is a really good question: Well articulated, clearly explained, sample data for copy and paste, expected output and own attempt. Cannot be better! +1 Commented Feb 18, 2016 at 15:50
  • HI Muflix! Is this question solved? Do you need further help? Commented Feb 19, 2016 at 18:15
  • Hi Muflix, might be interesting for you: I placed a question myself how one could get the desired XML more easily: stackoverflow.com/q/35523127/5089204 Commented Feb 20, 2016 at 12:19
  • ... and there is a great answer alredy! Commented Feb 20, 2016 at 14:02

1 Answer 1

2

This is - almost - what you wanted. As told in my comment you will not be able to create your Element's names (<RowA> etc.) dynamically. For this you'd have to use dynamic SQL and I assume this is not what you want actually...

Here's my suggestion:

SELECT '' AS [NodeB]
      ,'' AS [NodeC/@AttributeX]
      ,(
          SELECT x.NodeName AS [@NodeName]
                ,x.AttributA AS [@AttributeA]
                ,x.AttributB AS [@AttributeB]
                ,x.AttributC AS [@AttributeC]
          FROM XMLData AS x
          FOR XML PATH('Row'),TYPE
       ) AS NodeC
FOR XML PATH(''),ROOT('NodeA')

The result

<NodeA>
  <NodeB></NodeB>
  <NodeC AttributeX="">
    <Row NodeName="RowA" AttributeA="" AttributeB="abcd" AttributeC="efgh" />
    <Row NodeName="RowB" AttributeA="wxyz" />
    <Row NodeName="RowC" AttributeB="qwer" AttributeC="tyui" />
    <Row NodeName="RowD" AttributeA="stuv" AttributeB="erty" AttributeC="fghj" />
  </NodeC>
</NodeA>

This was an XSLT to get "dynamic" element names out of the XML above

Credits to Tim C

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*[@NodeName]">
        <xsl:element name="{@NodeName}">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="@NodeName" />
</xsl:stylesheet>

And this was the result Test it here

<NodeA>
  <NodeB/>
  <NodeC AttributeX="">
    <RowA AttributeA="" AttributeB="abcd" AttributeC="efgh"/>
    <RowB AttributeA="wxyz"/>
    <RowC AttributeB="qwer" AttributeC="tyui"/>
    <RowD AttributeA="stuv" AttributeB="erty" AttributeC="fghj"/>
  </NodeC>
</NodeA>
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much, unfortunately I really need to have element name same as the NodeName column but I will try to handle this with replace function. Dynamic SQL seems complicated to me, I will let you know.
@Muflix, I hope that this qestion is solved now... If so, it would be very kind to accept my answer, thx!

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.