0

I have the following XML structure:

set @MailXML =
'<MailingCompany>
    <Mailman>
        <Name>Jamie</Name>
            <Age> 24 </Age>
            <Letter>
            <DestinationAddress> 440 Mountain View Parade </DestinationAddress>
            <DestinationCountry> USA </DestinationCountry>
                <OriginCountry> Australia </OriginCountry>
            <OriginAddress> 120 St Kilda Road </OriginAddress>
            </Letter>
    </Mailman>
</MailingCompany>'

My SQL currently looks like this:

-- Mail Insertion
INSERT INTO mailDB.dbo.Mailman
   SELECT
       m.value('Name[1]','varchar(50)') as Name,
       m.value('Age[1]','varchar(50)') as Age
   FROM 
       @MailXML.nodes('/MailingCompany/Mailman') as A(m)

SET @MailPersonFK = SCOPE_IDENTITY();

-- Letter Insertion
INSERT INTO mailDB.dbo.Letter
    SELECT 
        l.value('DestinationAddress[1]', 'varchar(50)') as DestinationAddress,
        l.value('DestinationCountry[1]', 'varchar(50)') as DestinationCountry,
        l.value('OriginCountry[1]', 'varchar(50)') as OriginCountry,
        l.value('OriginAddress[1]', 'varchar(50)') as OriginAddress
        @MailPersonFK as MailID
    FROM  
        @MailXML.nodes('MailingCompany/Mailman/Letter') as B(l)

I am trying to extract the Mailman and Letter data into their own respective tables. I have got that working however my issue is that the MailCompany node is dynamic. Sometimes it may be MailVehicle, for example, and I still need to read the corresponding Mailman and Letter node data and insert them into their own respective tables.

So both

FROM @MailXML.nodes('/MailingCompany/Mailman') as A(t)

and

FROM @MailXML.nodes('MailingCompany/Mailman/Letter') as B(l)

Will need to be changed to allow MailingCompany to be dynamic.

I have tried to extract the parent node and concatenate it into a string to put into the .nodes function like the following:

set @DynXML = '/' + @parentNodeVar + '/Mailman'

FROM @MailXML.nodes(@DynXML) as A(t)

However I get the following error:

The argument 1 of the XML data type method "nodes" must be a string literal.

How can I overcome this dynamic XML issue?

Thank you very much in advance

1
  • as per my understanding , you trying to say that Mailman and Letter is never changes but parent node of Mailman may be change . so you have difficulty to get data of Mailman and Letter .means you want to find Mailman and Letter node dynamically from xml .Am iI Right ? Commented Feb 7, 2017 at 6:22

1 Answer 1

3

Look at this reduced example:

DECLARE @xml1 XML=
N'<MailingCompany>
  <Mailman>
    <Name>Jamie</Name>
    <Letter>
      <DestinationAddress> 440 Mountain View Parade </DestinationAddress>
    </Letter>
  </Mailman>
</MailingCompany>';

DECLARE @xml2 XML=
N'<OtherName>
  <Mailman>
    <Name>Jodie</Name>
    <Letter>
      <DestinationAddress> This is the other address </DestinationAddress>
    </Letter>
  </Mailman>
</OtherName>';

SELECT @xml1.value(N'(*/Mailman/Name)[1]','nvarchar(max)') AS Mailman_Name
      ,@xml1.value(N'(*/Mailman/Letter/DestinationAddress)[1]','nvarchar(max)') AS DestinationAddress
SELECT @xml2.value(N'(*/Mailman/Name)[1]','nvarchar(max)') AS Mailman_Name
      ,@xml2.value(N'(*/Mailman/Letter/DestinationAddress)[1]','nvarchar(max)') AS DestinationAddress

You can replace a node's name with *.

Another trick is the deep search with // (same result as before):

SELECT @xml1.value(N'(//Name)[1]','nvarchar(max)') AS Mailman_Name
      ,@xml1.value(N'(//DestinationAddress)[1]','nvarchar(max)') AS DestinationAddress
SELECT @xml2.value(N'(//Name)[1]','nvarchar(max)') AS Mailman_Name
      ,@xml2.value(N'(//DestinationAddress)[1]','nvarchar(max)') AS DestinationAddress

The general rule: Be as specific as possible.

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

2 Comments

Awesome that's exactly what I wanted. Thank you @Shnugo!
I have the exact same problem but i need to select also the "OtherName"... how can i do this? Thanks @Shnugo

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.