Not with a varying number of columns: SQL in general is fixed column
However, you can anticipate this somewhat
DECLARE @foo AS xml = '<root>
<r>
<data>"col1"</data>
<data>"col2"</data>
<data>"col3"</data>
</r>
<r>
<data>"data1"</data>
<data>""</data>
<data>"data3"</data>
</r>
<r>
<data>"data"</data>
<data>"data"</data>
<data>"data"</data>
</r>
</root>'
SELECT
REPLACE(x.item.value('(data)[1]', 'varchar(100)'), '"', '') AS col1,
REPLACE(x.item.value('(data)[2]', 'varchar(100)'), '"', '') AS col2,
REPLACE(x.item.value('(data)[3]', 'varchar(100)'), '"', '') AS col3,
REPLACE(x.item.value('(data)[4]', 'varchar(100)'), '"', '') AS col4,
REPLACE(x.item.value('(data)[5]', 'varchar(100)'), '"', '') AS col5,
REPLACE(x.item.value('(data)[6]', 'varchar(100)'), '"', '') AS col6,
REPLACE(x.item.value('(data)[7]', 'varchar(100)'), '"', '') AS col7,
REPLACE(x.item.value('(data)[8]', 'varchar(100)'), '"', '') AS col8,
REPLACE(x.item.value('(data)[9]', 'varchar(100)'), '"', '') AS col9,
REPLACE(x.item.value('(data)[10]', 'varchar(100)'), '"', '') AS col10
FROM
@foo.nodes('/root/r') x(item)
There is also no guarantee of node order evaluation by default which complicates extracting the first row column names.
Based on this answer:http://stackoverflow.com/q/1134075/27535, you can use this SQL to identify row 1
;WITH n(i) AS (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9),
o(i) AS (SELECT n3.i * 100 + n2.i * 10 + n1.i FROM n n1, n n2, n n3)
SELECT
REPLACE(x.item.value('(data)[1]', 'varchar(100)'), '"', '') AS col1,
REPLACE(x.item.value('(data)[2]', 'varchar(100)'), '"', '') AS col2,
REPLACE(x.item.value('(data)[3]', 'varchar(100)'), '"', '') AS col3,
REPLACE(x.item.value('(data)[4]', 'varchar(100)'), '"', '') AS col4,
REPLACE(x.item.value('(data)[5]', 'varchar(100)'), '"', '') AS col5,
REPLACE(x.item.value('(data)[6]', 'varchar(100)'), '"', '') AS col6,
REPLACE(x.item.value('(data)[7]', 'varchar(100)'), '"', '') AS col7,
REPLACE(x.item.value('(data)[8]', 'varchar(100)'), '"', '') AS col8,
REPLACE(x.item.value('(data)[9]', 'varchar(100)'), '"', '') AS col9,
REPLACE(x.item.value('(data)[10]', 'varchar(100)'), '"', '') AS col10,
o.i
FROM
o
CROSS APPLY
@foo.nodes('/root/r[sql:column("o.i")]') x(item)