Na uren van wanhoop en honderden proeven en fouten, heb ik de onderstaande oplossing bedacht.
Ik had hetzelfde probleem, toen ik slechts één . wilde xmlns
attribuut, op de root knooppunt alleen . Maar ik had ook een zeer moeilijke vraag met veel subquery's en FOR XML EXPLICIT
methode alleen was gewoon te omslachtig. Dus ja, ik wilde het gemak van FOR XML PATH
in de subquery's en ook om mijn eigen xmlns
. in te stellen .
Ik heb zo vriendelijk de code geleend van 8kb's antwoord, omdat het zo leuk was. Ik heb het een beetje aangepast voor een beter begrip. Hier is de code:
DECLARE @Order TABLE (OrderID INT, OrderDate DATETIME)
DECLARE @OrderDetail TABLE (OrderID INT, ItemID VARCHAR(1), Name VARCHAR(50), Qty INT)
INSERT @Order VALUES (1, '2010-01-01'), (2, '2010-01-02')
INSERT @OrderDetail VALUES (1, 'A', 'Drink', 5),
(1, 'B', 'Cup', 2),
(2, 'A', 'Drink', 2),
(2, 'C', 'Straw', 1),
(2, 'D', 'Napkin', 1)
-- Your ordinary FOR XML PATH query
DECLARE @xml XML = (SELECT OrderID AS "@OrderID",
(SELECT ItemID AS "@ItemID",
Name AS "data()"
FROM @OrderDetail
WHERE OrderID = o.OrderID
FOR XML PATH ('Item'), TYPE)
FROM @Order o
FOR XML PATH ('Order'), ROOT('dummyTag'), TYPE)
-- Magic happens here!
SELECT 1 AS Tag
,NULL AS Parent
,@xml AS [xml!1!!xmltext]
,'http://test.com/order' AS [xml!1!xmlns]
FOR XML EXPLICIT
Resultaat:
<xml xmlns="http://test.com/order">
<Order OrderID="1">
<Item ItemID="A">Drink</Item>
<Item ItemID="B">Cup</Item>
</Order>
<Order OrderID="2">
<Item ItemID="A">Drink</Item>
<Item ItemID="C">Straw</Item>
<Item ItemID="D">Napkin</Item>
</Order>
</xml>
Als u @xml
heeft geselecteerd alleen zou je zien dat het root node dummyTag
. bevat . We hebben het niet nodig, dus we verwijderen het met behulp van de richtlijn xmltext
in FOR XML EXPLICIT
vraag:
,@xml AS [xml!1!!xmltext]
Hoewel de uitleg in MSDN ingewikkelder klinkt, maar in de praktijk vertelt het de parser om de inhoud te selecteren van XML
hoofdknooppunt.
Ik weet niet zeker hoe snel de vraag is, maar momenteel ontspan ik en drink ik whisky als een heer terwijl ik vredig naar de code kijk...