Efter timmar av desperation och hundratals försök och misstag har jag kommit fram till lösningen nedan.
Jag hade samma problem när jag ville ha bara en xmlns
attribut, på roten endast nod . Men jag hade också en mycket svår fråga med många underfrågor och FOR XML EXPLICIT
Bara metoden var alldeles för besvärlig. Så ja, jag ville ha bekvämligheten med FOR XML PATH
i underfrågorna och även för att ställa in mina egna xmlns
.
Jag lånade koden för 8kb's svar, för det var så fint. Jag justerade det lite för bättre förståelse. Här är koden:
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
Resultat:
<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>
Om du valde @xml
ensam skulle du se att den innehåller rotnoden dummyTag
. Vi behöver det inte, så vi tar bort det genom att använda direktivet xmltext
i FOR XML EXPLICIT
fråga:
,@xml AS [xml!1!!xmltext]
Även om förklaringen i MSDN låter mer sofistikerad, men praktiskt taget säger den till parsern att välja innehållet av XML
rotnod.
Jag är inte säker på hur snabb frågan är, men för närvarande slappar jag av och dricker Scotch som en herre medan jag lugnt tittar på koden...