1

私はXMLの初心者です。とはいえ、私の問題は、XMLデータを作成するSQL Serverがあり、それをファイルに配置して、セキュリティゲートを通過して別のサーバーに移動する必要があることです。ゲートには、ファイルが含まれている場合にファイルが失敗する原因となるいくつかの「汚い」単語のリストがあります。私が必要としているのは、SQLがXMLデータ、すべてのノードを検索する方法であり、「ダーティ」値が存在する場合は、それを取り除きます(空白に置き換えます)。XMLは強く型付けされておらず、「ダーティ」な単語はより長い文字列の一部である可能性があります。その場合、文字列の残りの部分はそのままにしておく必要があります。

たとえば、「汚い」という言葉が「保持」である場合、「私たちはこれらの真実を自明であると保持します」という文字列は「私たちこれらの真実は自明である」になります。

繰り返しますが、この「ダーティ」な単語はどのノードにも存在する可能性があり、タグは常に同じであるとは限りません。ダーティワードリストに基づいてXML値を分析してクリーンアップするプロシージャまたはトリガーを作成する必要があります。

4

1 に答える 1

0

XMLをノードごとに1行のテーブルに細断します。テーブルには、変更を書き戻すことができるように、細断されたXML内のノードの位置に対応するIDが必要です。

悪い言葉をテーブルに入れ、単語ごとreplaceにノード値を使用してテーブルからそれらを削除します。

最後に、クリーンアップされた値をループして、実際に変更されたノードに対して一度に1ノードずつXMLに書き戻します。

-- 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

注:場合によっては、上記のコードは、変更自体が不正な値を作成する値を処理しません。

<item>fioneve</item>

に変更されます

<item>five</item>
于 2013-03-01T06:48:00.703 に答える