消除嵌套 FOR XML PATH 查询中的冗余命名空间声明
在使用 WITH XMLNAMESPACES 声明默认命名空间的 FOR XML PATH 查询中,常见的是在嵌套查询中遇到重复的命名空间声明。本文解决了这个问题并提供了最佳解决方案。
当子查询使用 FOR XML 并从外部查询继承默认命名空间时,就会出现此问题。这会导致子查询的节点有多个命名空间声明。虽然网上有各种解决方案,但都没有完全解决这个问题。
最佳解决方案
经过大量实验,以下解决方案被认为是最有效的:
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) -- 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
此解决方案利用 FOR XML EXPLICIT 查询来包装 FOR XML PATH 查询结果,有效删除不需要的命名空间声明。
结果
此查询的输出将是:
<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>
命名空间声明现在仅存在于根节点,正如预期的那样。
以上是如何消除嵌套 FOR XML PATH 查询中的冗余命名空间声明?的详细内容。更多信息请关注PHP中文网其他相关文章!