我目前有以下代码在名为PARTY的父节点下创建XML。 PARTY节点内部是另一个名为ROLE的节点。我的问题是如何用xquery中的[SequenceNr]变量替换当前的ROLE节点,该节点只是说ROLE。
我曾尝试在@OutputXml中进行替换但是没有用,我认为在xquery中应该有一个我不知道的简单方法。
当前代码:
WITH [PartyNodes] AS
(
SELECT (
SELECT [dbo].[XmlA](@Id),
[dbo].[XmlB](@Id)
FOR XML PATH(''),TYPE
) AS [AllTogether]
)
,[NumberedSequences] AS
(
SELECT 'PARTY' + CONVERT(NVARCHAR, ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) + 10) + '_ROLE1' AS [PartySequenceNr], -- party label
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) + 10 AS [SequenceNr], -- party sequence
[T].[Party].[query]('.') AS [TheNode]
FROM [PartyNodes]
CROSS APPLY [AllTogether].[nodes]('/PARTY') AS T(Party)
)
SELECT @OutputXml = ( SELECT [TheNode].[query]('let $p:=/PARTY[1]
let $lbl:=sql:column("PartySequenceNr")
let $nr:=sql:column("SequenceNr")
return
<PARTY SequenceNumber="{$nr}" xlink_label="{$lbl}" >
{$p/*}
</PARTY>'
)
FROM [NumberedSequences]
FOR XML PATH(''),ROOT('PARTIES')
);
当前输出:
<PARTY SequenceNumber="1" xlink:label="PARTY1_ROLE1">
<INDIVIDUAL>
<NAME>
<FullName>Test</FullName>
</NAME>
</INDIVIDUAL>
<ROLES>
<ROLE>
<A>Test</A>
</ROLE>
</ROLES>
</PARTY>
期望的输出:
<PARTY SequenceNumber="1" xlink:label="PARTY1_ROLE1">
<INDIVIDUAL>
<NAME>
<FullName>Test</FullName>
</NAME>
</INDIVIDUAL>
<ROLES>
<ROLE SequenceNumber="1" xlink:label="PARTY1_ROLE1">>
<A>Test</A>
</ROLE>
</ROLES>
</PARTY>
答案 0 :(得分:2)
我试图跟随你的想法,但不能......
有两个函数XmlA
和XmlB
。首先,将结果合并到AllTogether
。稍后您使用.nodes('/PARTY')
来读取此内容,但您显示的XML只有一个PARTY
节点作为root。
您还可以使用FLWOR-XQuery
插入这两个属性。但我怀疑,xlink_label
会显示为xlink:label
。
您展示的XML不能是上述结果......或者我遗漏了某些东西......
我的第一个想法是:这似乎过于复杂......如果以下内容无效,请提供有关目标的更多详细信息,请尝试set up a MCVE
。这可能是the XY-problem
我从没有属性的XML开始,假设这是前面的结果:
DECLARE @xml XML=
N'<PARTY>
<INDIVIDUAL>
<NAME>
<FullName>Test</FullName>
</NAME>
</INDIVIDUAL>
<ROLES>
<ROLE>
<A>Test</A>
</ROLE>
</ROLES>
</PARTY>';
- 此查询会在PARTY
和ROLE
DECLARE @PartySequenceNr INT = 1;
DECLARE @SequenceNr VARCHAR(100)='PARTY1_ROLE1';
SELECT @xml.query
(N'
let $p:=/PARTY[1]
let $lbl:=sql:variable("@PartySequenceNr")
let $nr:=sql:variable("@SequenceNr")
return
<PARTY SequenceNumber="{$nr}" xlink_label="{$lbl}" >
{
for $nd in $p/*
return
if(local-name($nd)="ROLES") then
(
<ROLES><ROLE SequenceNumber="{$nr}" xlink_label="{$lbl}" >
{$nd/ROLE/*}
</ROLE></ROLES>
)
else $nd
}
</PARTY>
')
结果:
<PARTY SequenceNumber="PARTY1_ROLE1" xlink_label="1">
<INDIVIDUAL>
<NAME>
<FullName>Test</FullName>
</NAME>
</INDIVIDUAL>
<ROLES>
<ROLE SequenceNumber="PARTY1_ROLE1" xlink_label="1">
<A>Test</A>
</ROLE>
</ROLES>
</PARTY>
xlink
如果您需要命名空间
,请使用此选项SELECT @xml.query
(N' declare namespace xlink="DummyUrl";
let $p:=/PARTY[1]
let $lbl:=sql:variable("@PartySequenceNr")
let $nr:=sql:variable("@SequenceNr")
return
<PARTY SequenceNumber="{$nr}" xlink:label="{$lbl}" >
{
for $nd in $p/*
return
if(local-name($nd)="ROLES") then
(
<ROLES><ROLE SequenceNumber="{$nr}" xlink:label="{$lbl}" >
{$nd/ROLE/*}
</ROLE></ROLES>
)
else $nd
}
</PARTY>
')
结果
<PARTY SequenceNumber="PARTY1_ROLE1" xmlns:xlink="DummyUrl" xlink:label="1">
<INDIVIDUAL>
<NAME>
<FullName>Test</FullName>
</NAME>
</INDIVIDUAL>
<ROLES>
<ROLE SequenceNumber="PARTY1_ROLE1" xlink:label="1">
<A>Test</A>
</ROLE>
</ROLES>
</PARTY>