Après des heures de désespoir et des centaines d'essais et d'erreurs, j'ai trouvé la solution ci-dessous.
J'ai eu le même problème, alors que je voulais un seul xmlns
attribut, sur la racine nœud uniquement . Mais j'ai aussi eu une requête très difficile avec beaucoup de sous-requêtes et FOR XML EXPLICIT
méthode seule était tout simplement trop lourde. Alors oui, je voulais la commodité de FOR XML PATH
dans les sous-requêtes et aussi pour définir mon propre xmlns
.
J'ai gentiment emprunté le code de 8kb réponse, parce que c'était si agréable. Je l'ai un peu modifié pour mieux comprendre. Voici le 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
Résultat :
<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>
Si vous avez sélectionné @xml
seul, vous verriez qu'il contient le nœud racine dummyTag
. Nous n'en avons pas besoin, nous le supprimons donc en utilisant la directive xmltext
dans FOR XML EXPLICIT
requête :
,@xml AS [xml!1!!xmltext]
Bien que l'explication dans MSDN semble plus sophistiquée, mais en pratique, elle indique à l'analyseur de sélectionner le contenu de XML
nœud racine.
Je ne sais pas à quelle vitesse la requête est rapide, mais actuellement je me détends et je bois du scotch comme un gentleman tout en regardant paisiblement le code...