Efter timers desperation og hundredvis af forsøg og fejl har jeg fundet nedenstående løsning.
Jeg havde det samme problem, da jeg ville have bare én xmlns
attribut, på roden kun node . Men jeg havde også en meget vanskelig forespørgsel med masser af underforespørgsler og FOR XML EXPLICIT
metoden alene var bare for besværlig. Så ja, jeg ønskede bekvemmeligheden ved FOR XML PATH
i underforespørgslerne og også for at indstille mine egne xmlns
.
Jeg lånte venligst koden til 8kb'er svar, fordi det var så hyggeligt. Jeg tilpassede det lidt for bedre forståelse. Her er 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>
Hvis du valgte @xml
alene, ville du se, at den indeholder rodnode dummyTag
. Vi har ikke brug for det, så vi fjerner det ved at bruge direktivet xmltext
i FOR XML EXPLICIT
forespørgsel:
,@xml AS [xml!1!!xmltext]
Selvom forklaringen i MSDN lyder mere sofistikeret, men praktisk talt fortæller den parseren at vælge indholdet af XML
rodknude.
Ikke sikker på, hvor hurtig forespørgslen er, men i øjeblikket slapper jeg af og drikker skotsk som en herre, mens jeg fredeligt kigger på koden...