Is there a way to search through XML Nodes using SQL to see if Parent Nodes have ChildNodes and Grandchildren? I'm trying to test some XML files to see if there are any unknown children:
<form>
<ItemType>New Regular</ItemType>
<FirstBuyDate>02/01/2007</FirstBuyDate>
<FirstShipDate>02/05/2007</FirstShipDate>
<ItemBrand>Gillette Blade/Razors</ItemBrand>
<ItemDescription>...</ItemDescription>
<Size>8.00</Size>
<InnerOffInvoice />
<MasterOffInvoice />
<PalletItems>
<ID>908402</ID>
<PalletShipDate>04/03/13</PalletShipDate>
</PalletItems>
<ReviewComments />
</form>
In this example, I know that PalletItems has children. So I am able to make tables, insert that data accordingly. But how can I be sure I've gotten all of the grandchildren of <form>
? What if there are unknown children like with <ItemDescription>
- how do I find the children I don't know about? How can I test all of these nodes to see if <form>
has any grandchildren?
This code here showed me how many children had:
SELECT distinct Parent.Items.value('local-name(.)', 'varchar(100)') as 'Item'
FROM dbo.FormResults
CROSS APPLY xmlformfields.nodes('/form/*') as Parent(Items)
Do any of you have suggestions to find the grandchildren? Thanks!
Also as a side note - does anyone know how to have this SELECT statement put the children in the order they appear in the xml? Currently when the code grabs the children it will display them in the column in random order:
Items
1. FirstBuyDate
2. Size
3. ItemType
4. PalletItems... etc.
I would like them to be displayed like this:
Items:
1. ItemType
2. FirstBuyDate
3. FirstShipDate
4. ItemBrand... etc.
---------------------UPDATE----------------------
Now that we know that (/form//*) will get the children and grandchild thanks to valex
How can I put the children in one column and the grandchildren in the next? Would it be something like this:
SELECT distinct Parent.Items.value('local-name(.)', 'varchar(100)') as 'Child of Form',
CASE when child.items.value('local-name(.)', 'varchar(100)') IS NULL then NULL ELSE 'Has Child' end as 'Grandchild of Form'
FROM dbo.FormResults
CROSS APPLY xmlformfields.nodes('/form/*') as Parent(Items)
Cross Apply parent.items.nodes('/form//*') as child(items)