SQL Server XML добавить атрибут, если он не существует

Я пытаюсь добавить атрибут, если он не существует. Это должно быть просто, но я новичок в XML XPath/XQuery/и т. д., так что извините за мое невежество.

Я хочу иметь возможность передавать данные XML и изменять их...

ALTER FUNCTION [dbo].[ConvertXmlData](@xmlData XML)
RETURNS XML
AS
BEGIN
  RETURN @xmlData.<something here>
END

If I pass data like:

<something> 
   this is sample data <xxx id="1"/> and <xxx id="2" runat="server" />. More <yyy id="3" />
</something>

я бы хотел

<something>
this is sample data <xxx id="1" runat="server" /> and <xxx id="2" runat="server" />. More <yyy id="3" />

</something>

И нет :

<something>
this is sample data <xxx id="1" runat="server" /> and <xxx id="2" runat="server" runat="server"/>. More <yyy id="3" />
</something>

person Outside the Box Developer    schedule 01.07.2011    source источник
comment
SQL 2008 R2, к вашему сведению, если это поможет   -  person Outside the Box Developer    schedule 01.07.2011


Ответы (1)


Ты можешь сделать

SET @xmlData.modify('insert attribute runat { "server" } into descendant::xxx[not(@runat)][1]');

Однако это изменит только первого потомка xxx, не имеющего атрибута runat, по крайней мере, с SQL Server 2005 вы можете изменять только один узел за раз.

Возможно, объединение вышеизложенного с WHILE помогает, например.

WHILE @xmlData.exist('descendant::xxx[not(@runat)]') = 1
BEGIN
  SET @xmlData.modify('insert attribute runat { "server" } into descendant::xxx[not(@runat)][1]');
END

У меня нет доступа к SQL Server 2008 R2, но я думаю, что изменение по-прежнему ограничено одним узлом за раз, поэтому вы можете попробовать

ALTER FUNCTION [dbo].[ConvertXmlData](@xmlData XML)
RETURNS XML
AS
BEGIN
    WHILE @xmlData.exist('descendant::xxx[not(@runat)]') = 1
    BEGIN
      SET @xmlData.modify('insert attribute runat { "server" } into descendant::xxx[not(@runat)][1]');
    END
  RETURN @xmlData
END
person Martin Honnen    schedule 01.07.2011