Это очень раздражающая проблема, известная в течение десятилетия, но Microsoft не желает ее менять.Пространства имен повторяются в подзапросах снова и снова.Ищите это, и вы найдете сотни вопросов об этом.В течение более десяти лет существовала проблема с подключением со многими сторонниками, но подключение исчезло, и проблема исчезла - но пространства имен остаются ...
Кстати: Ваш запрос великолепен!
Однако решение возможно, но оно безобразно.Вы должны создать свой XML без пространств имен и в конце добавить его на уровне строки:
create table #temp_headers (warehouse_iss varchar(5), iss_id int, date datetime)
create table #temp_items (prod_index varchar(10), qty float)
create table #temp_parameter (par_id int, par_value varchar(10), prod_index varchar(10))
insert into #temp_headers values ('wareh',1,getdate())
insert into #temp_items values ('abc',123)
insert into #temp_parameter values (1, 'abcdef','abc');
- спасибо за тестовый сценарий!
DECLARE @intermediateXML XML=
(
select
'Dummy T' as "warehouse_iss/@type",
warehouse_iss as "warehouse_iss/idn",
'Dummy T' as "iss_id/@type",
iss_id as "iss_id/id", --- iss_id
GETDATE() date, --- date
(select
'Dummy T' as "prod_index/@type",
prod_index as "prod_index/idn",
qty,
(select
'Dummy T' as "par_id/@type",
par_id as "par_id/id",
'Dummy T' as "par_value/@type",
par_value as "par_value/id"
from #temp_parameter para
where para.prod_index = items.prod_index
FOR XML PATH ('parameter'), ROOT ('parameters'), type
)
from #temp_items items
for xml path ('items'), type
)
from #temp_headers head
for xml path ('DummyHeaders')
);
- приведите его к NVARCHAR(MAX)
...
DECLARE @XML_as_String NVARCHAR(MAX)=CAST(@intermediateXML AS NVARCHAR(MAX));
--... и добавьте заголовок на строковом уровне строковыми методами
DECLARE @Header NVARCHAR(MAX)=
N'<s:headers xmlns:s="http://www.example.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com/example ../../Schema/example.xsd ">';
DECLARE @finalXML XML=
(
REPLACE(
(SELECT @Header +
(
SELECT SUBSTRING(@XML_as_String,CHARINDEX(N'<warehouse_iss',@XML_as_String),LEN(@XML_as_String))
)
),'</DummyHeaders>','</s:headers>')
);
SELECT @finalXML
GO
DROP TABLE #temp_headers
DROP TABLE #temp_items
DROP TABLE #temp_parameter
Подсказка: одно замечание по поводу xml-объявления <?xml blah?>
Ваш XML по умолчанию закодирован как NVARCHAR(MAX)
(что составляет UCS-2
, почти utf-16)
. Если вы добавите объявление, сообщающее потребителю Привет, яutf-8
! , это не правда. Это объявление не подразумевается как часть XML, а как нечто заранее , сообщающее потребителю, как декодировать контент. SQL-Serverдаже не позволит вам сохранить это как собственный XML.
Но - конечно - вы можете добавить любую строку в строку. Таким образом, вы можете добавить свое объявление в приведенный XML (но не приводите его обратнов XML!). Если вы записываете это в файл на диске, вы должны быть уверены, что этот файл действительно закодирован utf-8
. В противном случае ваш fИль был бы лжецом; -)