I'm parsing the xml file with TSQL to build a table for further analysis. Using great advises from xquery-lab-61-writing-a-recursive-cte-to-process-an-xml-document I use CTE but not getting the desire result. The problem is with value() function for nodes with childrens.
I have
DECLARE @x XML
SELECT @x = '
<books>
<book id="101">
<title>my book</title>
<author>Myself</author>
</book>
<book id="202">
text before
<title>your book</title>
in the middle
<author>you</author>
text after
</book>
</books>'
;WITH cte AS (
SELECT
1 AS lvl,
x.value('local-name(.)','VARCHAR(MAX)') AS FullPath,
x.value('text()[1]','VARCHAR(MAX)') AS Value,
x.query('.') AS CurrentNode,
CAST(CAST(1 AS VARBINARY(4)) AS VARBINARY(MAX)) AS Sort
FROM @x.nodes('/*') a(x)
UNION ALL
SELECT
p.lvl + 1 AS lvl,
CAST(
p.FullPath
+ '/'
+ c.value('local-name(.)','VARCHAR(MAX)') AS VARCHAR(MAX)
) AS FullPath,
CAST( c.value('text()[1]','VARCHAR(MAX)') AS VARCHAR(MAX) ) AS Value,
c.query('.') AS CurrentNode,
CAST(
p.Sort
+ CAST( (lvl + 1) * 1024
+ (ROW_NUMBER() OVER(ORDER BY (SELECT 1)) * 2) AS VARBINARY(4)
) AS VARBINARY(MAX) ) AS Sort
FROM cte p
CROSS APPLY CurrentNode.nodes('/*/*') b(c)
), cte2 AS (
SELECT
FullPath,
Value,
Sort
FROM cte
UNION ALL
SELECT
p.FullPath + '/@' + x.value('local-name(.)','VARCHAR(MAX)'),
x.value('.','VARCHAR(MAX)'),
Sort
FROM cte p
CROSS APPLY CurrentNode.nodes('/*/@*') a(x)
)
SELECT FullPath, value
FROM cte2
WHERE Value IS NOT NULL
ORDER BY Sort
which results in
FullPath Value
-------------------- ------------------------------
books\book\@id 101
books\book\title my book
books\book\author Myself
books\book text before
books\book\@id 202
books\book\title your book
books\book\author you
and I need something like:
FullPath Value
-------------------- ------------------------------
books\book\@id 101
books\book\title my book
books\book\author Myself
books\book text before
books\book\@id 202
books\book\title your book
books\book in the middle
books\book\author you
books\book text after
I would prefer to find a solution using TSQL if possible. I will be extremely grateful for any good solutions/advises.