Após horas de desespero e centenas de tentativas e erros, encontrei a solução abaixo.
Eu tive o mesmo problema, quando eu queria apenas um
xmlns atributo, na raiz nó somente . Mas eu também tive uma consulta muito difícil com muitas subconsultas e FOR XML EXPLICIT método sozinho era muito complicado. Então, sim, eu queria a conveniência de FOR XML PATH nas subconsultas e também para definir meus próprios xmlns . Eu gentilmente peguei emprestado o código de 8kb's resposta, porque era tão bom. Ajustei um pouco para melhor compreensão. Aqui está o código:
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]
,'https://test.com/order' AS [xml!1!xmlns]
FOR XML EXPLICIT
Resultado:
<xml xmlns="https://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>
Se você selecionou
@xml sozinho, você verá que ele contém o nó raiz dummyTag . Não precisamos dele, então o removemos usando a diretiva xmltext em FOR XML EXPLICIT consulta:,@xml AS [xml!1!!xmltext]
Embora a explicação no MSDN pareça mais sofisticada, mas praticamente diz ao analisador para selecionar o conteúdo de
XML nó raiz. Não tenho certeza de quão rápida é a consulta, mas atualmente estou relaxando e bebendo uísque como um cavalheiro enquanto olho pacificamente para o código ...