2

I have this XML in a SQL Server table:

<root>
  <meetings>
    <meeting>
      <id>111</id>
      <participants>
        <participant><name>Smith</name></participant>
        <participant><name>Jones</name></participant>
        <participant><name>Brown</name></participant>
      </participants>
    </meeting>
    <meeting>
      <id>222</id>
      <participants>
        <participant><name>White</name></participant>
        <participant><name>Bloggs</name></participant>
        <participant><name>McDonald</name></participant>
      </participants>
    </meeting>
  </meetings>
</root>

And want a result set like this:

MeetingID    Name
111          Smith
111          Jones
111          Brown
222          White
222          Bloggs
222          McDonald

This is easy using select from openxml but I failed using XQuery. Can someone help me there, and maybe also give pros and cons for either method?

2 Answers 2

5

Once you've fixed your invalid XML (the <name> elements need to be ended with a </name> end tag), you should be able to use this:

SELECT 
    Meetings.List.value('(id)[1]', 'int') AS 'Meeting ID',
    Meeting.Participant.value('(name)[1]', 'varchar(50)') AS 'Name'
FROM
    @input.nodes('/root/meetings/meeting') AS Meetings(List)
CROSS APPLY
    Meetings.List.nodes('participants/participant') AS Meeting(Participant)

Basically, the first call to .nodes() gives you a pseudo-table of all <meeting> nodes, from which I extract the meeting ID.

The second .nodes() call on that <meeting> tag digs deeper into the <participants>/<participant> list of subnodes and extracts the name from those nodes.

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

2 Comments

Thanks, exactly what I needed. I do find openXML syntax easier to understand though.
@Graeme: really? I find OpenXML very unintuitive and quite messy, actually.
1

This may give you the XQuery based Table based output.

(: Assume $x is your Xml Content. so :)
let $x := Assign your Xml Content.
let $d1:= <table border="1"><tr><td>Meeting</td><td> Participant</td></tr>
  { for $p in $x//meeting/participants/participant 
              return element{'tr'} {
                    element{'td'} {$p/parent::*/parent::*/id/text()},
                    element{'td'} {data($p)}                        
                }
          }

   </table>

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.