Как добавить атрибут xml ко всем узлам xml-документа?

#sql #xml #tsql #xpath #dml

Вопрос:

У меня есть таблица бд под названием XmlDocument с полем XML, которая используется для хранения xml. И это пример сохраненного xml:

 <ol type="decimal" id="id-a4bb3b6d-9908-4972-8b02-72e286795b7a">
    <item id="id-92332716-4561-4874-d353-39fdf993fa89">
        <para id="id-a3fae837-59d8-4702-b689-f869137a92a7">Item1</para>
    </item>
    <item id="id-d8031e83-5b68-47cb-f535-41bee9682f4a">
        <para id="id-8746fe56-3160-4543-bf28-5f1e1de83ec0">Item2</para>
    </item>
</ol>
 

Моя цель-написать сценарий tsql, который добавит атрибут revNumber ко всем узлам документа, у которого этого атрибута нет. Вот как это должно выглядеть:

 <ol revNumber="1.1" type="decimal" id="id-a4bb3b6d-9908-4972-8b02-72e286795b7a">
    <item revNumber="1.2" id="id-92332716-4561-4874-d353-39fdf993fa89">
        <para revNumber="1.3" id="id-a3fae837-59d8-4702-b689-f869137a92a7">Item1</para>
    </item>
    <item revNumber="1.0" id="id-d8031e83-5b68-47cb-f535-41bee9682f4a">
        <para revNumber="1.2" id="id-8746fe56-3160-4543-bf28-5f1e1de83ec0">Item2</para>
    </item>
</ol>
 

Если у узла уже есть этот атрибут, мы должны пропустить его. Мы можем использовать что-то подобное, но это работает только для одного узла:

 SET @requestXML.modify(
'insert 
(        
    attribute revNumber {sql:variable("@revNum") }
)
into (/ol)[1]')
 

Но структура документа может быть другой. Каков наилучший способ сделать это?

Комментарии:

1. Вы не можете легко сделать это в SQL Server, потому .modify что одновременно работает только на одном узле. Лучше просто извлечь его в клиентское приложение и обработать там. Или, возможно, функция SQLCLR.

Ответ №1:

Наконец я нашел решение:

 declare @xml XML = '
<root>
    <text>test</text>
    <text>test</text>
    <text>test</text>
    <text>test</text>
</root>
'
while @xml.exist('//*[not(@TEST)]') = 1
begin
    set @xml.modify('
        insert attribute TEST {"value"}
        into (//*[not(@TEST)])[1]
    ')
end
select @xml
 

Комментарии:

1. Хороший ответ, 1 с моей стороны!