SQL Server XML add attribute if non-existent

落爺英雄遲暮 提交于 2019-12-23 16:55:07

问题


I am trying to add an attribute if it does not exist. It should be simple, but I am new to XML XPath/XQuery/etc., so excuse my ignorance.

I want to be able to pass XML data and modify it...

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>

I would like

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

</something>

And not :

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

回答1:


You can do

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

This will however only change the first xxx descendant not having a runat attribute, at least with SQL Server 2005 you can only modify one node at a time.

Maybe combining the above with a WHILE helps e.g.

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

I don't have access to SQL Server 2008 R2 but I think the modify is still limited to one node at a time so you could try

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


来源:https://stackoverflow.com/questions/6550115/sql-server-xml-add-attribute-if-non-existent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!