[英]Insert node into XML without using sql:variable
I have looked throughout the interwebs (including SO but I have probably missed it) for a way to insert a node into existing XML which is contained in a variable without first creating as XML in a variable a string of the node which I would like to insert and using "set @XMLVariable01.modify('insert sql:variable("@XMLVariable02") as ...". 我遍历了整个网络(包括SO,但我可能会错过它)寻找一种方法,可以将节点插入到包含在变量中的现有XML中,而无需先在变量中创建XML作为我想要的节点字符串插入并使用“设置@ XMLVariable01.modify('插入sql:variable(“ @ XMLVariable02”)作为...”。
From the example below I would like to get as the final result: 从下面的示例中,我想得到最终结果:
<P xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<L01>
<A xsi:nil="true" />
<B xsi:nil="true" />
<C xsi:nil="true" />
</L01>
<L02>
<A>2</A>
<B xsi:nil="true" />
<C>x</C>
</L02>
</P>
Example: 例:
declare
@P xml;
declare
@A varchar,
@B varchar,
@C varchar;
select
@P = (
select
@A as [A],
@B as [B],
@C as [C]
for xml path(N'L01'), root('P'), type, elements xsinil
);
select @P; --Initial result
select
@A = '2',
@B = NULL,
@C = 'x';
--select @P = ...?
select @P; --Final result
I did the following: 我做了以下事情:
select
@P = (
select (
select
v.query('.')
from @P.nodes('P/L01') as t (v)),
(
select
@A as [A],
@B as [B],
@C as [C]
for xml path(N'L02'), type, elements xsinil
)
for xml path(N'P'), type, elements xsinil
);
Which comes close but I don't want the 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' anywhere other than in the initial/top line of the XML: 接近了,但是我不想在XML的开头/顶部以外的任何地方使用“ xmlns:xsi =“ http://www.w3.org/2001/XMLSchema-instance”“:
<P xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<L01>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
<B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
<C xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
</L01>
<L02 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<A>2</A>
<B xsi:nil="true" />
<C>x</C>
</L02>
</P>
Edit (2018Dec14~1343): Based on Schnugo's helpful insight (Yes, I need/want the NULL values for the purpose of documentation that the indicated elements were accounted for but that no value was received. Also, I apologize but I am not able to fully grasp all that is being suggested in 1-5.), I have come up with the following: 编辑(2018Dec14〜1343):基于Schnugo的有用见解(是的,我需要/希望使用NULL值来记录所指出的元素但未收到任何值的文档。此外,我很抱歉但我无法为了完全掌握1-5中建议的所有内容),我提出了以下建议:
select
@P = (
select
cast(replace(replace(cast(([XML].[Value]) as nvarchar(max)), cjR.Old01, cjR.New01), cjR.Old02, cjR.New02) as xml)
from (
select (
select
v.query('.')
from @P.nodes(N'P/L01') as t (v)),
(
select
@A as [A],
@B as [B],
@C as [C]
for xml path(N'L02'), type, elements xsinil
)
for xml path(N'P'), type, elements xsinil
) as [XML] ([Value])
cross join (
select
Value02 as Old01,
N'' as New01,
quotename(Value01, N'<>') as Old02,
quotename(Value01 + Value02, N'<>') as New02
from (
select
N'P',
N' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
) as R (Value01, Value02)
) as cjR
);
It seems like such a hacky way to produce what should be such a simple operation but apparently it is not. 看起来像是一种骇人听闻的方式来产生应该如此简单的操作,但显然并非如此。 I welcome any further advice to improve on this.
我欢迎任何进一步的建议以改善此情况。
You hit various flaws of SQL Server's XML support here... 您在这里遇到了SQL Server XML支持的各种缺陷...
With nested XML there's no other way then to use sub-queries. 使用嵌套的XML,便没有其他方法可以使用子查询。 But the repeating namespaces in sub-queries are a very annoying issue.
但是子查询中重复的名称空间是一个非常烦人的问题。 The XML produced is perfeclty okay, but the repeated namespace declarations can really bloat your XML enormously.
生成的XML完全可以,但是重复的名称空间声明确实会极大地膨胀您的XML。 This is discussed (and begged for a better solution) for centuries.
讨论了几个世纪(并寻求更好的解决方案)。 There was a Connect-Ticket for more than 10 years with a lot of votes.
有十多年的Connect-Ticket,获得了很多票。 But this disappeared together with Connect.
但这与Connect一起消失了。
Do you really need NULL
values to show off with xsi:nil
? 您是否真的需要
NULL
值才能通过xsi:nil
进行展示? The default is to omit them... 默认是忽略它们...
Very often you'll see ugly workarounds 很多时候,您会看到丑陋的解决方法
All of them use a CAST
to NVARCHAR(MAX)
, manipulate the namespaces with string methods ( STUFF
, SUBSTRING
, ...) and do a re-cast to XML at the end. 它们全部使用
CAST
到NVARCHAR(MAX)
,使用字符串方法( STUFF
, SUBSTRING
,...)操纵名称空间,并在最后将其重铸为XML。
REPLACE
) to correct this ( look at this answer ) REPLACE
)对此进行更正( 请看此答案 ) xsi:nil
to enforce NULL
values not to be omited. xsi:nil
来强制执行NULL
值,以免被忽略。 This is even worse... You can create the XML as you do it and then use string methods, to throw away the wrong declarations. FOR XML EXPLICIT
. FOR XML EXPLICIT
。 This is a weird and hard-to-learn format. I'm sorry, but this is exactly the kind of XML SQL-Server cannot build easily... 很抱歉,但这正是XML SQL Server无法轻松构建的那种...
If you need help with one of the provided options, you might start a new question with a sepcific question on this. 如果您需要有关所提供选项之一的帮助,则可以使用一个特殊的问题来开始一个新问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.