经过几个小时的绝望和数百次试验和错误后,我想出了以下解决方案。
当我想要时,我遇到了同样的问题just one xmlns
属性,在root node only。但我也有一个非常困难的查询,有很多子查询和FOR XML EXPLICIT
单纯的方法太麻烦了。所以是的,我想要方便FOR XML PATH
在子查询中,也可以设置我自己的xmlns
.
我好心借用了代码8kb's回答,因为它太好了。为了更好地理解,我对其进行了一些调整。这是代码:
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
Result:
<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>
如果您选择了@xml
单独来看,你会看到它包含根节点dummyTag
。我们不需要它,所以我们使用以下方法删除它指示 https://msdn.microsoft.com/en-us/library/ms189068.aspx#Anchor_1 xmltext
in FOR XML EXPLICIT
query:
,@xml AS [xml!1!!xmltext]
虽然MSDN中的解释听起来比较复杂,但实际上它告诉解析器选择contents of XML
根节点。
不确定查询有多快,但目前我正在放松,像绅士一样喝着苏格兰威士忌,同时平静地看着代码......