Search code examples
sqlsql-serverxmlsqlxml

SQL convert multi level xml with attribute into table


I've the xml below which I'm trying to convert into a table.

declare @X xml = 
'<root>
<items>
    <item ItemID="100">
        <obj ObjID="0001" value="val1"/>
        <obj ObjID="0002" value="val2"/>
        <obj ObjID="0003" value="val3"/>
        <obj ObjID="0004" value="val4"/>
    </item>
    <item ItemID="200">
        <obj ObjID="0001" value="val1"/>
        <obj ObjID="0002" value="val2"/>
        <obj ObjID="0003" value="val3"/>
        <obj ObjID="0004" value="val4"/>
    </item>
</items>
</root>'

How can I transform the above xml into a table structure like below:

ItemID    ObjID
100       0001
100       0002
100       0003
100       0004
200       0001
200       0002
200       0003
200       0004

I've tried the statement below but it keeps on coming with NULL values for both (ItemID, ObjID) columns.

select 
    t.col.value('(/item/@ItemID)[1]', 'nvarchar(16)') as [ItemID],
    t.col.value('(/item/obj/@ObjID)[1]', 'nvarchar(16)') as [ObjID]
from 
@X.nodes('/root/items') as t(col)

Solution

  • Try this Query

      SELECT 
        Tbl.Col.value('../@ItemID', 'nvarchar(16)') as [ItemID],  
        Tbl.Col.value('@ObjID', 'nvarchar(16)') as [ObjID]   
      FROM 
        @x.nodes('root/items/item/obj') Tbl(Col);