一段时间以来,我一直在使用您的知识,但是这次我没有找到问题的答案。 我是自学成才的,所以请原谅我任何错误。
我需要生成XML,但是我从未使用SQL来完成,因此存在一些问题。 我已经生成了核心,但是我需要添加架构和版本,但是我无法创建它。
我准备了一个快速示例,它必须是相同的体系结构。 现在的样子:
<s:headers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s="http://www.example.com">
<warehouse_iss type="T">
<idn>wareh</idn>
</warehouse_iss>
<iss_id type="T">
<id>1</id>
</iss_id>
<date>2018-10-15T21:48:36.220</date>
<items xmlns:s="http://www.example.com">
<prod_index type="T">
<idn>abc</idn>
</prod_index>
<qty>1.230000000000000e+002</qty>
<parameters xmlns:s="http://www.example.com">
<parameter>
<par_id type="T">
<id>1</id>
</par_id>
<par_value type="T">
<id>abcdef</id>
</par_value>
</parameter>
</parameters>
</items>
</s:headers>
应如何显示:
<?xml version="1.0" encoding="UTF-8"?>
<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 ">
<warehouse_iss type="T">
<idn>wareh</idn>
</warehouse_iss>
<iss_id type="T">
<id>1</id>
</iss_id>
<date>2018-10-15T21:48:36.220</date>
<items>
<prod_index type="T">
<idn>abc</idn>
</prod_index>
<qty>1.230000000000000e+002</qty>
<parameters>
<parameter>
<par_id type="T">
<id>1</id>
</par_id>
<par_value type="T">
<id>abcdef</id>
</par_value>
</parameter>
</parameters>
</items>
</s:headers>
因此,我需要添加所有架构和元素,并且不应在子节点中重复它。 我还需要添加版本。
我准备帮助您的代码(MyFunction当然是将“ @type”添加到输出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')
WITH XMLNAMESPACES ('http://www.example.com' as s)
select
dbo.MyFunction(1,'T') as "warehouse_iss/@type",
warehouse_iss as "warehouse_iss/idn",
dbo.MyFunction(1,'T') as "iss_id/@type",
iss_id as "iss_id/id", --- iss_id
GETDATE() date, --- date
(select
dbo.MyFunction(1,'T') as "prod_index/@type",
prod_index as "prod_index/idn",
qty,
(select
dbo.MyFunction(1,'T') as "par_id/@type",
par_id as "par_id/id",
dbo.MyFunction(1,'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 ('s:headers'), ELEMENTS XSINIL
谢谢。
答案 0 :(得分:0)
这是一个非常烦人的问题,已经有十年了,但是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 blah?>
默认情况下,您的XML编码为NVARCHAR(MAX)
(即UCS-2
,几乎是utf-16)
。如果您添加了一个声明以告知使用者嘿,我是{{1 }}!,这不是事实,该声明不是作为XML的一部分,而是作为预先来告知消费者如何解码内容的声明。服务器甚至不允许您将其存储为本地XML。
但是-当然-您可以在字符串中添加任何字符串。因此,您可以将声明添加到强制转换的XML中(但不要将其强制转换回XML!)。如果将此内容写到光盘上的文件中,则应确保该文件实际上是utf-8
编码的。否则您的文件将是骗子;-)