Search code examples
sql-serverxmlxpathfor-xml-pathfor-xml

sql server FOR XML xpath mode: how to generate nested XML id 1 and 2


I am a xml string as below. I want to use sql server for xml xpath to generate this xml string. I have trouble to get id="IP1" and id="IP2". Would you please help me with it? Thank you very much.

    <root>
    <InsuredOrPrincipal id="IP1">
    <GeneralPartyInfo>
    <NameInfo>
    <PersonName>
    <Surname>A </Surname>
    <GivenName>B</GivenName>
    </PersonName>

    </NameInfo>

    </GeneralPartyInfo>

    </InsuredOrPrincipal>


    <InsuredOrPrincipal id="IP2">
    <GeneralPartyInfo>
    <NameInfo>
    <PersonName>
    <Surname>A </Surname>
    <GivenName>B</GivenName>
    </PersonName>

    </NameInfo>

    </GeneralPartyInfo>

    </InsuredOrPrincipal>
    </root>

Solution

  • This should do what you need. You can run the code in SSMS to see it in action.

    -- create table variable
    DECLARE @table TABLE ( id VARCHAR(10), Surname VARCHAR(50), GivenName VARCHAR(50) );
    
    -- insert test data
    INSERT INTO @table ( 
        id, Surname, GivenName 
    )
    VALUES
    ( 'IP1', 'A1', 'B1' )
    , ( 'IP2', 'A2', 'B2' );
    
    -- return xml results from test data as per required schema
    SELECT
        id AS 'InsuredAsPrincipal/@id'
        , Surname AS 'InsuredAsPrincipal/GeneralPartyInfo/NameInfo/PersonName/Surname'
        , GivenName AS 'InsuredAsPrincipal/GeneralPartyInfo/NameInfo/PersonName/GivenName'
    FROM @table
    FOR XML PATH ( '' ), ROOT( 'root' );
    

    The resulting XML returned is:

    <root>
      <InsuredAsPrincipal id="IP1">
        <GeneralPartyInfo>
          <NameInfo>
            <PersonName>
              <Surname>A1</Surname>
              <GivenName>B1</GivenName>
            </PersonName>
          </NameInfo>
        </GeneralPartyInfo>
      </InsuredAsPrincipal>
      <InsuredAsPrincipal id="IP2">
        <GeneralPartyInfo>
          <NameInfo>
            <PersonName>
              <Surname>A2</Surname>
              <GivenName>B2</GivenName>
            </PersonName>
          </NameInfo>
        </GeneralPartyInfo>
      </InsuredAsPrincipal>
    </root>
    

    I believe this is what you are looking to do. The real "magic" here is in aliasing your column data.