DECLARE @x xml CREATE TABLE #t (LibraryID int identity(1, 1), Library xml) SET @X = (SELECT CONVERT(xml, BulkColumn, 2) FROM OPENROWSET (BULK N'C:\Library.xml', SINGLE_BLOB) AS Document) INSERT INTO #t (library) SELECT T.C.query('.') AS SongInfo FROM @x.nodes('/plist[1]/dict[1]/dict[1]/dict') AS T(C) ;WITH kvps AS (SELECT library.value('/dict[1]/integer[1]', 'int') AS [ID], t.c.value('local-name(.)', 'varchar(255)') AS [type], t.c.value('.', 'varchar(255)') AS [value], t.c.value('for $s in . return count(../*[. << $s]) + 1', 'int') AS RowNum FROM #t CROSS APPLY library.nodes('/dict/*') AS T(C)) , final AS (SELECT k.id, k2.RowNum / 2 AS [RowNum], k.value AS [Key], CASE WHEN k2.[value] IS NOT NULL AND k2.[value] != '' THEN k2.[value] ELSE k2.type END AS [Value], CASE WHEN k2.[value] IS NOT NULL AND k2.[value] != '' THEN k2.[type] ELSE 'bit' END AS [Type] FROM kvps AS k INNER JOIN kvps AS k2 ON k.rownum + 1 = k2.rownum AND k.id = k2.id WHERE k2.rownum > 1 AND k2.rownum % 2 = 0) SELECT * INTO #t2 FROM final ;WITH t2 AS (SELECT [id], [key], [value] FROM #t2) SELECT [id], [Name], [Artist], [Album Artist], [Album], [Genre], [Kind], [Size], [Total Time], IsNull([Disc Number], 1) AS [Disc Number], IsNull([Disc Count], 1) AS [Disc Count], IsNull([Track Number], 1) AS [Track Number], [Track Count], [Year], [Date Modified], [Date Added], [Bit Rate], [Sample Rate] INTO #t3 FROM t2 PIVOT (MAX([Value]) FOR [key] IN ([Name], [Artist], [Album Artist], [Album], [Genre], [Kind], [Size], [Total Time], [Disc Number], [Disc Count], [Track Number], [Track Count], [Year], [Date Modified], [Date Added], [Bit Rate], [Sample Rate]) ) AS pvt SELECT * FROM #t3 ORDER BY [Artist], [Album], [Disc Number], [Track Number] --DROP TABLE #t --DROP TABLE #t2 --DROP TABLE #t3