【问题标题】:Inserting an attribute in multiple XML Nodes using XML.modify() in SQL 2005在 SQL 2005 中使用 XML.modify() 在多个 XML 节点中插入一个属性
【发布时间】:2010-10-06 21:37:33
【问题描述】:

我有一个从单个 select 语句创建的 @XML 文档。

<root>
 <node>
  <node1>
   <targetNode>
   </targetNode>
  </node1>
  <node1>
   <targetNode>
   </targetNode>
  </node1>
  <node1>
   <targetNode>
   </targetNode>
  </node1>
 </node>
 <node>
  ......
 </node>
</root>

我想插入 xsi:nil 作为该文档的“targetNode”属性。

@XML.modify( 'insert attribute xsi:nil {"true"} into (root/node/node1/targetNode) [1]') 

上面将属性插入到@XML 文档中targetNode 的第一次出现。但是,插入语句仅适用于单个节点。有什么方法可以将此属性插入到@XML 文档中的所有 targetNode 实例中。

【问题讨论】:

    标签: sql-server xml sql-server-2005 xml-dml


    【解决方案1】:

    修改功能无法做到这一点。它只适用于单个节点。

    您可以将其作为字符串进行操作,尽管在某些情况下这绝对是丑陋的并且可能是错误的,具体取决于您的 XML 的实际结构。

    像这样:

    declare @xml as xml
    set @xml = '<root>
     <node>
      <node1>
       <targetNode>
       </targetNode>
      </node1>
      <node1>
       <targetNode>
       </targetNode>
      </node1>
      <node1>
       <targetNode>
       </targetNode>
      </node1>
     </node>
    </root>
    '
    
    set @xml = replace(cast(@xml as nvarchar(max)), '<targetNode/>', '<targetNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />')
    select @xml
    

    【讨论】:

      【解决方案2】:

      您可以在用于创建 xml 的选择中执行此操作,使用 XSINILL 参数。

      http://msdn.microsoft.com/en-us/library/ms178079.aspx

      (这里是一个非常粗略的例子)

      --create 2 tables and put some data in them
      create table node
      (
         id int identity(1,1) primary key,
         node int
      )
      GO
      create table node1
      (
         id int identity(1,1) primary key,
         nodeid int foreign key references node(id),
         targetnode int
      )
      GO
      
      insert into node
      select 1
      GO 5
      
      insert into node1
      select 1,2
      union 
      select 2,null
      union 
      select 3,2
      union 
      select 4,null
      --
      
      --select statement to generate the xml
      SELECT TOP(1)
         (SELECT
            (  SELECT targetnode
               FROM    node1
               WHERE   nodeid = node.id 
               FOR XML AUTO,
               ELEMENTS XSINIL,
               TYPE
            )
         FROM    node FOR XML AUTO,
         ELEMENTS,
         TYPE
         )
      FROM   node FOR XML RAW('root'),
             ELEMENTS
      

      【讨论】:

        【解决方案3】:

        我在多节点上的DML操作中找到了一个简单而优雅的解决方案 http://blogs.msdn.com/b/denisruc/archive/2005/09/19/471562.aspx

        思路是统计有多少节点,并一一修改:

        DECLARE @iCount int
        SET @iCount = @var.value('count(root/node/node1/targetNode)','int')
        
        DECLARE @i int
        SET @i = 1
        
        WHILE (@i <= @iCount)
        BEGIN
           @xml.modify('insert attribute xsi:nil {"true"} into (root/node/node1/targetNode)[sql:variable("@i")][1]')
           SET @i = @i + 1
        END
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-03-16
          • 2018-11-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多