Sau hàng giờ tuyệt vọng và hàng trăm lần thử và sai, tôi đã đưa ra giải pháp bên dưới.
Tôi đã gặp vấn đề tương tự, khi tôi muốn chỉ một xmlns
thuộc tính trên root nút chỉ . Nhưng tôi cũng gặp phải một truy vấn rất khó với rất nhiều truy vấn con và FOR XML EXPLICIT
một mình phương pháp đã quá cồng kềnh. Vì vậy, có, tôi muốn sự tiện lợi của FOR XML PATH
trong các truy vấn con và cũng để đặt xmlns
của riêng tôi .
Tôi vui lòng mượn mã của 8kb's câu trả lời, bởi vì nó rất hay. Tôi đã chỉnh sửa nó một chút để hiểu rõ hơn. Đây là mã:
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
Kết quả:
<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>
Nếu bạn đã chọn @xml
một mình, bạn sẽ thấy rằng nó chứa nút gốc dummyTag
. Chúng tôi không cần nó, vì vậy chúng tôi xóa nó bằng cách sử dụng chỉ thị xmltext
trong FOR XML EXPLICIT
truy vấn:
,@xml AS [xml!1!!xmltext]
Mặc dù lời giải thích trong MSDN nghe có vẻ phức tạp hơn, nhưng trên thực tế, nó yêu cầu trình phân tích cú pháp chọn nội dung của XML
nút gốc.
Không chắc truy vấn nhanh đến mức nào, nhưng hiện tại tôi đang thư giãn và uống Scotch như một người bạn trong khi yên tâm xem mã ...