Détruisez le code XML en une table avec une ligne pour chaque noeud. La table a besoin d'un identifiant qui correspond à la position du nœud dans le XML déchiqueté pour pouvoir écrire les changements. Ayez vos mots vides dans une table et pour chaque mot, utilisez replace
pour les supprimer de la table avec les valeurs de nœuds.
Enfin, vous parcourez les valeurs nettoyées et les réécrivez sur le nœud XML à la fois pour les nœuds qui ont été réellement modifiés.
-- A table to hold the bad words
declare @BadWords table
(
ID int identity,
Value nvarchar(10)
)
-- These are the bad ones.
insert into @BadWords values
('one'),
('three'),
('five'),
('hold')
-- XML that needs cleaning
declare @XML xml = '
<root>
<itemone ID="1one1">1one1</itemone>
<itemtwo>2two2</itemtwo>
<items>
<item>1one1</item>
<item>2two2</item>
<item>onetwothreefourfive</item>
</items>
<hold>We hold these truths to be self evident</hold>
</root>
'
-- A helper table to hold the values to modify
declare @T table
(
ID int identity,
Pos int,
OldValue nvarchar(max),
NewValue nvarchar(max),
Attribute bit
)
-- Get all attributes from the XML
insert into @T(Pos, OldValue, NewValue, Attribute)
select row_number() over(order by T.N),
T.N.value('.', 'nvarchar(max)'),
T.N.value('.', 'nvarchar(max)'),
1
from @XML.nodes('//@*') as T(N)
-- Get all values from the XML
insert into @T(Pos, OldValue, NewValue, Attribute)
select row_number() over(order by T.N),
T.N.value('text()[1]', 'nvarchar(max)'),
T.N.value('text()[1]', 'nvarchar(max)'),
0
from @XML.nodes('//*') as T(N)
declare @ID int
declare @Pos int
declare @Value nvarchar(max)
declare @Attribute bit
-- Remove the bad words from @T, one bad word at a time
select @ID = max(ID) from @BadWords
while @ID > 0
begin
select @Value = Value
from @BadWords
where ID = @ID
update @T
set NewValue = replace(NewValue, @Value, '')
set @ID -= 1
end
-- Write the cleaned values back to the XML
select @ID = max(ID) from @T
while @ID > 0
begin
select @Value = nullif(NewValue, OldValue),
@Attribute = Attribute,
@Pos = Pos
from @T
where ID = @ID
print @Attribute
if @Value is not null
if @Attribute = 1
set @XML.modify('replace value of ((//@*)[sql:variable("@Pos")])[1]
with sql:variable("@Value")')
else
set @XML.modify('replace value of ((//*)[sql:variable("@Pos")]/text())[1]
with sql:variable("@Value")')
set @ID -= 1
end
select @XML
Remarque: Dans certains cas, le code ci-dessus ne traitera pas des valeurs où la modification crée elle-même la mauvaise valeur.
<item>fioneve</item>
sera modifié pour
<item>five</item>
Quelle version de SQL Server? Si ce n'est pas fortement typé, est-ce au moins dans une colonne de type 'xml'? –
2008 R2. oui, la colonne est de type de données XML – user1873604
Donc, quand vous dites que ce n'est pas fortement typé, vous voulez dire qu'il n'a aucun ensemble de schémas associés? –