如果Target xml包含默认命名空间,则无法使用.modify添加xml节点

时间:2014-03-10 07:57:51

标签: sql sql-server xml insert

这里我需要使用SQL Server中的.modify函数将源xml节点插入到目标xml中。当我拥有所有命名空间时,一切都很顺利。片刻我将其中一个命名空间更改为默认值,它会停止插入节点。

以下是我的问题的代码

Declare @sourceXML xml
Declare @TargetXML xml
Declare @tempXML xml

Set @TargetXML = '<?xml version="1.0"?>
<Message>
<MainBody>
</MainBody>
<Part>
<InnerBody xmlns:ac="http://www.example.org/Standards/1" xmlns:rlc="http://www.example.org/Standards/Standard" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
</InnerBody>
</Part>
</Message>';


set @sourceXML = '<rlc:Movement xmlns:rlc="http://www.example.org/Standards/Standard" Type="outstanding">
  <rlc:Amt Ccy="GBP" >500000.00</rlc:Amt>
</rlc:Movement>
<rlc:Movement xmlns:rlc="http://www.example.org/Standards/Standard" Type="previous">
  <rlc:Amt Ccy="GBP" >0.00</rlc:Amt>
</rlc:Movement>
<rlc:Movement xmlns:rlc="http://www.example.org/Standards/Standard" Type="loss">
  <rlc:Amt Ccy="GBP" >1000000.00</rlc:Amt>
</rlc:Movement>
<rlc:Movement xmlns:rlc="http://www.example.org/Standards/Standard" Type="current">
  <rlc:Amt Ccy="GBP" >500000.00</rlc:Amt>
</rlc:Movement>
'


SET @TargetXML.modify('
declare namespace rlc= "http://www.example.org/Standards/Standard";
declare namespace ac="http://www.example.org/Standards/1" ;
declare namespace xsi="http://www.w3.org/2001/XMLSchema-instance";

insert sql:variable("@sourceXML") as first into (/Message/Part/InnerBody)[1]')
Select @TargetXML
go

这给出了如下结果

<Message>
  <MainBody />
  <Part>
    <InnerBody xmlns:ac="http://www.example.org/Standards/1" xmlns:rlc="http://www.example.org/Standards/Standard" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <rlc:Movement xmlns:rlc="http://www.example.org/Standards/Standard" Type="outstanding">
        <rlc:Amt Ccy="GBP">500000.00</rlc:Amt>
      </rlc:Movement>
      <rlc:Movement xmlns:rlc="http://www.example.org/Standards/Standard" Type="previous">
        <rlc:Amt Ccy="GBP">0.00</rlc:Amt>
      </rlc:Movement>
      <rlc:Movement xmlns:rlc="http://www.example.org/Standards/Standard" Type="loss">
        <rlc:Amt Ccy="GBP">1000000.00</rlc:Amt>
      </rlc:Movement>
      <rlc:Movement xmlns:rlc="http://www.example.org/Standards/Standard" Type="current">
        <rlc:Amt Ccy="GBP">500000.00</rlc:Amt>
      </rlc:Movement>
    </InnerBody>
  </Part>
</Message>

如果我删除了rlc前缀并将源xml更改为

Set @TargetXML = '<?xml version="1.0"?>
<Message>
<MainBody>
</MainBody>
<Part>
<InnerBody xmlns:ac="http://www.example.org/Standards/1" xmlns="http://www.example.org/Standards/Standard" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
</InnerBody>
</Part>
</Message>';

我得到了

<Message>
  <MainBody />
  <Part>
    <InnerBody xmlns="http://www.example.org/Standards/Standard" xmlns:ac="http://www.example.org/Standards/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
  </Part>
</Message>

任何人都可以看一下吗?

1 个答案:

答案 0 :(得分:3)

以前,InnerBody位于空命名空间中。根据您的更改,您现在声明它位于http://www.abc.org/Standards/Standard命名空间中,因此,XPath /Message/Part/InnerBody不再匹配它。但是,/Message/Part/rlc:InnerBody会:

SET @TargetXML.modify('
declare namespace rlc= "http://www.abc.org/Standards/Standard";
declare namespace ac="http://www.abc.org/Standards/1" ;
declare namespace xsi="http://www.w3.org/2001/XMLSchema-instance";

insert sql:variable("@sourceXML") as first into (/Message/Part/rlc:InnerBody)[1]')
Select @TargetXML
go

您还应该注意,名称空间前缀可以是任何内容,因此此查询也可以起作用:

SET @TargetXML.modify('
declare namespace a= "http://www.abc.org/Standards/Standard";
declare namespace b="http://www.abc.org/Standards/1" ;
declare namespace c="http://www.w3.org/2001/XMLSchema-instance";

insert sql:variable("@sourceXML") as first into (/Message/Part/a:InnerBody)[1]')
Select @TargetXML
go