Reputation: 2687
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?
Upvotes: 2
Views: 2500
Reputation: 2166
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>
Upvotes: 1
Reputation: 754348
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.
Upvotes: 5