Search code examples
sqlsql-serverxmlnestedfor-xml-path

SQL Server : nesting elements with FOR XML PATH


I want to nest each of my XML elements.

Take the following example:

DECLARE @TempTable TABLE
(
    [Column1] char(10),
    [Column2] char(10)
);

INSERT INTO @TempTable([Column1], [Column2]) VALUES
('some value', 'some value'),
('some value', 'some value'),
('some value', 'some value'),
('some value', 'some value')

SELECT (
    SELECT * FROM @TempTable
FOR XML PATH('Row'), TYPE)
FOR XML PATH('ParentRow'), ROOT('Root')

Which will return the following XML:

  <Root>
    <ParentRow>
      <Row>
        <Column1>some value</Column1>
        <Column2>some value</Column2>
      </Row>
      <Row>
        <Column1>some value</Column1>
        <Column2>some value</Column2>
      </Row>
      <Row>
        <Column1>some value</Column1>
        <Column2>some value</Column2>
      </Row>
      <Row>
        <Column1>some value</Column1>
        <Column2>some value</Column2>
      </Row>
    </ParentRow>
  </Root>

Which is not the way I want the XML to be formatted. Rather I want each <Row> element to be wrapped with a <ParentRow> element like below:

  <Root>
    <ParentRow>
      <Row>
        <Column1>some value</Column1>
        <Column2>some value</Column2>
      </Row>
    </ParentRow>
    <ParentRow>
    <Row>
      <Column1>some value</Column1>
      <Column2>some value</Column2>
    </Row>
    </ParentRow>
    <ParentRow>
      <Row>
        <Column1>some value</Column1>
        <Column2>some value</Column2>
      </Row>
    </ParentRow>
    <ParentRow>
      <Row>
        <Column1>some value</Column1>
        <Column2>some value</Column2>
      </Row>
    </ParentRow>
  </Root>    

Any help with this guys?


Solution

  • Okay here is the code.

    DECLARE @TempTable TABLE
    (
        [Column1] char(10),
        [Column2] char(10)
    );
    
    INSERT INTO @TempTable([Column1], [Column2]) VALUES
    ('some value', 'some value'),
    ('some value', 'some value'),
    ('some value', 'some value'),
    ('some value', 'some value')
    
    SELECT (
            SELECT (
                    SELECT T1.*
                    FOR XML path('')
                        ,root('Row')
                        ,type
                    )
            FROM @TempTable AS T1
            FOR XML path('ParentRow')
                ,type
            )
    FOR XML path('Root')
    

    and here is the output.

    <Root>
      <ParentRow>
        <Row>
          <Column1>some value</Column1>
          <Column2>some value</Column2>
        </Row>
      </ParentRow>
      <ParentRow>
        <Row>
          <Column1>some value</Column1>
          <Column2>some value</Column2>
        </Row>
      </ParentRow>
      <ParentRow>
        <Row>
          <Column1>some value</Column1>
          <Column2>some value</Column2>
        </Row>
      </ParentRow>
      <ParentRow>
        <Row>
          <Column1>some value</Column1>
          <Column2>some value</Column2>
        </Row>
      </ParentRow>
    </Root>
    

    good luck...