根据列表修改多个xml属性

时间:2011-07-07 13:43:44

标签: sql xml

来自上一篇文章: SQL Server XML add attribute if non-existent

我想要做的是能够修改多个标签。下面的代码显示了我想要做什么,但不能,因为我收到错误: XML数据类型方法“exists”的参数1必须是字符串文字。是否有使用变量而不是文字修改XML的方法?

ALTER FUNCTION [dbo].[ConvertXmlData](@xmlData XML)
RETURNS XML
AS
BEGIN

    DECLARE @tags TABLE (
      ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
      TAG VARCHAR(25)
    )

    INSERT INTO @tags
    SELECT 'xxx' UNION   
    SELECT 'yyy'

    DECLARE @counter INT
    DECLARE @count   INT
    DECLARE @id      INT
    DECLARE @tag     VARCHAR(25)
    DECLARE @exist   VARCHAR(100)
    DECLARE @insert  VARCHAR(100)
    DECLARE @existX  VARCHAR(100)
    DECLARE @insertX VARCHAR(100)

    SET @exist   = 'descendant::{0}[not(@runat)]'
    SET @insert  = 'insert attribute runat { "server" } into descendant::{0}[not(@runat)][1]'
    SET @counter = 1
    SELECT @count = COUNT(*) FROM @tags

    WHILE @counter <= @count BEGIN

      SELECT @tag = TAG FROM @tags WHERE ID = @counter
      SET @existX = REPLACE(@existX,   '[0]', @tag)
      WHILE @xmlData.exist(@existX) = 1 BEGIN
        SET @xmlData.modify(REPLACE(@insertX, '[0]', @tag));
      END

      SET @counter = @counter + 1
    END    

  RETURN @xmlData
END

1 个答案:

答案 0 :(得分:2)

您不能将变量用作xml函数的参数,但可以在文字表达式中使用变量(和表列)。

我想这可以做你想要的。至少它应该让你知道你能做些什么。

declare @xmlData xml
set @xmlData = 
'<something>
   <xxx id="1"/>
   <xxx id="2" runat="server" />
   <xxx id="3"/>
   <yyy id="3" />
   <zzz id="1"/>
 </something>'

declare @tags table
(
  id int identity(1,1) primary key,
  tag varchar(25)
)

insert into @tags
select 'xxx' union   
select 'yyy'

declare @tag varchar(25)
declare @id int

select top 1
       @id = id,
       @tag = tag
from @tags
order by id

while @@rowcount > 0
begin
  while @xmlData.exist('descendant::*[local-name() = sql:variable("@tag") and not(@runat)]') = 1 
  begin
    set @xmlData.modify('insert attribute runat { "server" } into descendant::*[local-name() = sql:variable("@tag") and not(@runat)][1]');
  end

  select top 1
       @id = id,
       @tag = tag
  from @tags
  where id > @id
  order by id
end    

select @xmlData

结果:

<something>
  <xxx id="1" runat="server" />
  <xxx id="2" runat="server" />
  <xxx id="3" runat="server" />
  <yyy id="3" runat="server" />
  <zzz id="1" />
</something>