Nach Stunden der Verzweiflung und Hunderten von Versuchen und Irrtümern bin ich auf die folgende Lösung gekommen.
Ich hatte das gleiche Problem, als ich nur einen wollte xmlns
-Attribut im Stamm Knoten nur . Aber ich hatte auch eine sehr schwierige Abfrage mit vielen Unterabfragen und FOR XML EXPLICIT
Methode allein war einfach zu umständlich. Also ja, ich wollte den Komfort von FOR XML PATH
in den Unterabfragen und auch um meine eigenen xmlns
zu setzen .
Ich habe mir freundlicherweise den Code von 8kb ausgeliehen Antwort, weil es so schön war. Ich habe es zum besseren Verständnis etwas angepasst. Hier ist der 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
Ergebnis:
<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>
Wenn Sie @xml
ausgewählt haben allein würden Sie sehen, dass es den Root-Knoten dummyTag
enthält . Wir brauchen es nicht, also entfernen wir es mit der Direktive xmltext
in FOR XML EXPLICIT
Abfrage:
,@xml AS [xml!1!!xmltext]
Die Erklärung in MSDN klingt zwar anspruchsvoller, aber praktisch weist sie den Parser an, die Inhalte auszuwählen von XML
Root-Knoten.
Ich bin mir nicht sicher, wie schnell die Abfrage ist, aber derzeit entspanne ich mich und trinke Scotch wie ein Gentleman, während ich friedlich auf den Code schaue ...