Пространство имен по умолчанию с FOR XML PATH

Рассмотрим следующий SQL:

;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')

Тай возвращает xml:

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

Мне нужно вернуть xml с объявлением xmlns только для корневого элемента. например:

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

Есть ли способ сделать это?

Примечание. Вышеприведенный SQL-код является экстремальным упрощением фактического кода, который создает сложный документ, поэтому изменение FOR XML PATH на самом деле не вариант, не требующий пары дней дополнительной работы. Для ясности на верхнем уровне весь документ должен иметь NS, а все дочерние должны быть без него.


person Jon Egerton    schedule 13.10.2011    source источник
comment
Я не могу найти способ, но они должны иметь одинаковое значение - почему вы не можете использовать первую форму?   -  person Damien_The_Unbeliever    schedule 13.10.2011
comment
@Damien: это часть процесса переноса данных. Хотя первый документ означает то же самое (как вы говорите), он не работает, когда мы передаем его в (стороннюю) веб-службу импорта. Я думаю, проблема в том, что он использует подзапросы. Если вы используете один запрос и определяете дочерний элемент с помощью [Child/@ID], он работает нормально, но для этого потребуется немного переосмыслить код (который я унаследовал)   -  person Jon Egerton    schedule 13.10.2011


Ответы (2)


Вы можете использовать "запрос из ада"

;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
person Mikael Eriksson    schedule 13.10.2011
comment
+1 аааа - было бы ужасно попробовать реализовать в моей реальной ситуации! Идея хороша, и у меня есть способ использовать это для решения моей проблемы. - person Jon Egerton; 14.10.2011

Вы можете использовать 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')
person Maxim Eliseev    schedule 12.08.2014
comment
Первоначально это было упрощение более сложного документа, поэтому идея состоит в том, что только элемент верхнего уровня показывает NS, а все дочерние элементы (на всех уровнях) его не имеют. Ваше решение было бы отличным, если бы его можно было перевернуть так, чтобы элемент верхнего уровня создавался UDF, а остальные нет. Как вы думаете, вы можете работать таким образом? - person Jon Egerton; 13.08.2014