2011-10-13 46 views
2

考虑下面的SQL默认命名空间:与FOR XML PATH

;WITH XMLNAMESPACES(DEFAULT 'http://www.mynamespace.co.uk') 
,CTE_DummyData AS (
    select id=1 
) 
select TOP 1 
    [@ID]=1, 
    (select top 1 [@ID] = 1 FROM CTE_DummyData FOR XML PATH ('Child'), TYPE) 
from CTE_DummyData 
FOR XML PATH ('Parent') 

Thie返回XML:

<Parent xmlns="http://www.mynamespace.co.uk" ID="1"> 
    <Child xmlns="http://www.mynamespace.co.uk" ID="1" /> 
</Parent> 

我需要的仅仅是根元素上的xmlns声明返回XML 。例如:

<Parent xmlns="http://www.mynamespace.co.uk" ID="1"> 
    <Child ID="1" /> 
</Parent> 

有没有办法做到这一点?

注意: 上面的SQL是实际代码的极度简化,它产生了一个复杂的文档,所以从FOR XML PATH中改变并不是一个真正的选择,没有给我几天的额外工作。要在整个文件的顶层明确要求有NS,并且所有的孩子都应该没有。

+0

我找不到方法,但他们应该有相同的含义 - 为什么你不能使用第一种形式? –

+0

@Damien:这是数据迁移过程的一部分。虽然第一个文档意味着相同(如您所说),但当我们将其传递到(第三方)导入Web服务时,它不起作用。我认为问题在于它使用了子查询。如果您使用单个查询并使用'[Child/@ ID]'定义Child元素,那么它可以正常工作,但这需要对代码进行一些重新思考(我已继承) –

回答

2

可以使用"query from hell"

;with CTE_DummyData AS (
    select id=1 
) 
select 1 as tag, 
     0 as parent, 
     'http://www.mynamespace.co.uk' as [Parent!1!xmlns], 
     id as [Parent!1!ID], 
     null as [Child!2!ID] 
from CTE_DummyData  
union all 
select top 1 
     2, 
     1, 
     null, 
     null, 
     id 
from CTE_DummyData  
for xml explicit 
+0

+1 aargh - 在我的真实情况下尝试和实施会很糟糕!这个想法很好,但我有一种方法来解决我的问题。 –

1

你可以使用UDF来生成子节点。例如。

ALTER FUNCTION [dbo].[udf_get_child_section] (
    @serviceHeaderId INT 
) 
RETURNS XML 

BEGIN 

    DECLARE @result XML; 

    SELECT @result = 
    (
     SELECT 1 AS 'ChildElement' 
     FOR XML PATH('Child') 
    ) 

    RETURN @result 

END 


GO 

DECLARE @Ids TABLE 
( 
    ID int 
) 

INSERT INTO @Ids 
SELECT 1 AS ID 
UNION ALL 
SELECT 2 AS ID 

;WITH XMLNAMESPACES (DEFAULT 'http://www...com/content') 
SELECT 
    [dbo].[udf_get_child_section](ID) 
FROM 
    @Ids 
FOR XML PATH('Parent') 
+0

原来的事情是,虽然这是一个更复杂的文件的简化,所以这个想法是只有顶层元素显示NS,并且所有的孩子(在所有级别)都没有。如果解决方案可以转向,那么您的解决方案将非常出色,以便顶层元素由UDF生成,其他则不会。你认为你可以这样工作吗? –