XMLファイルからタグを削除する

XMLファイルからタグを削除する

私のファイルには識別できないデータが含まれています。次のように教えてください。

<?xml version="1.0" encoding="UTF-8" ?><ns0:collection
xmlns:ns0="http://namspace/Service/1.0"><Record>
.
.</Record></ns0:collection>

N個のファイルをマージして1つのファイルを作成する必要があります。したがって、次のことを行う必要があります。

  1. </ns0:collection>最初のファイルから閉じるタグを削除するだけです。
  2. 次の(n-1)個のファイルの<?xml version="1.0" encoding="UTF-8" ?><ns0:collection xmlns:ns0="http://namspace/Service/1.0">合計を削除する</ns0:collection>
  3. 最後のファイルのみを削除し、<?xml version="1.0" encoding="UTF-8" ?><ns0:collection xmlns:ns0="http://namspace/Service/1.0">すべてマージする必要があります。

コマンドを使用して最初のファイルを処理しようとしましたが、sed結果が出ませんでした。 "merged.xml"は空でした。

sed '/<\/ns0:collection>/d' $file1 > merged.xml

どんな提案がありますか?

答え1

useのみを指定していないsedため、アクセス権がある場合xml_grep(参照コマンドラインから複数のXMLファイルをマージする、2番目の答え)、これはあなたに多くの負担を与え、次の簡単なマージ操作を単一のコマンドで実行できるため、これをお勧めします。

xml_grep --cond Record --wrap "ns0:collection" --descr 'xmlns:ns0="http://namespace/Service/1.0"' --encoding "UTF-8" *.xml

テストファイル:

テスト.xml

<?xml version="1.0" encoding="UTF-8" ?><ns0:collection
xmlns:ns0="http://namespace/Service/1.0""><Record>
Test
</Record></ns0:collection>

テスト1.xml

<?xml version="1.0" encoding="UTF-8" ?><ns0:collection
xmlns:ns0="http://namespace/Service/1.0"><Record>
Test 1<a>a</a><b c="c">d</b>
</Record></ns0:collection>

結果

<?xml version="1.0" encoding="UTF-8" ?>
<ns0:collection xmlns:ns0="http://namespace/Service/1.0">
<Record>
Test 1<a>a</a><b c="c">d</b></Record><Record>
Test
</Record>
</ns0:collection>

XMLファイルを扱うときに構造を台無しにする可能性がsed非常に高く、誤った形式のXML文書になりやすいので、XML認識ツールを使用することをお勧めします!

答え2

sedXML処理に適していないusingを使用し、代わりにパーサーを使用することをお勧めします。

また、ここにXYの問題があることを示唆しています。タグを削除するのではなく、XMLファイルをマージすることです。

個人的に - 私はperl以下が好きですXML::Twig

#!/usr/bin/env perl
use strict;
use warnings;

#load the parser
use XML::Twig; 

#get our file list - we use the "first" file as the basis.
#can use sort on this list if desired. 
my ( $first_file, @other_files ) = glob ( 'C://tmp//xmltest/*.xml' ); 

#Our 'parent' document. 
my $doc = XML::Twig -> new -> parsefile ( $first_file ); 


foreach my $file ( @other_files ) { 
   my $mergedoc = XML::Twig -> new -> parsefile ( $file ); 

   #//Record means any <Record> node anywhere in the tree. 
   foreach my $record ( $mergedoc -> get_xpath ( '//Record' ) ) {
      $record -> cut;
      #paste it into our parent doc, as the last node. 
      $record -> paste ( after => $doc -> root -> last_child );
   }
}

#set output formatting (optional)
$doc -> set_pretty_print ('indented_a'); 

#print to STDOUT.
$doc -> print;

#write to output file too
open ( my $output, '>', 'combined.xml' ) or die $!;
print {$output} $doc -> sprint;
close ( $output );

これは、意図的にターゲットXMLから要素を抽出し、Record文書間でマージします。しかし、これはxpath非常に強力で正規表現と同じXMLのような柔軟なアプローチですが、正規表現はそうではありませんが、コンテキストを認識するので、より良いです。

答え3

解決策:

  1. 最初のファイルから閉じるタグのみを削除する必要があります。回避策:

    sed -i.bak -e 's/<\/ns0:collection>/ /' -e 's/<\/Record>/ /' n0
    
  2. 次の(n-1)ファイルの合計を削除します<?xml version="1.0" encoding="UTF-8" ?><ns0:collection xmlns:ns0="http://namspace/Service/1.0"></ns0:collection>

    sed -i.bak -e 's/<?xml version=1.0 encoding=UTF-8 ?>.*<ns0:collection/ /' -e 's/xmlns.*/ /' -e 's/<\/R.*>.*>/ /' n1
    
    • さまざまなファイル名に対して以下を実行します。

      find . -type f -name "n[1-3]" -exec sed i.bak -e 's/<?xml version=1.0 encoding=UTF-8 ?>.*<ns0:collection/ /' -e 's/xmlns.*/ /' -e 's/<\/R.*>.*>/ /' {} \;
      
  3. 最後のファイルのみを削除し、すべてマージする必要があります。

    sed i.bak -e 's/<?xml version=1.0 encoding=UTF-8 ?>.*<ns0:collection/ /' -e 's/xmlns.*/ /' ne
    

最後に参加してください:

cat n0 n[1-3] ne > joined

n0、、、n1およびn2。ファイルを使用しましたn3ne各コンテンツに次のテキストを追加しました。

<?xml version="1.0" encoding="UTF-8" ?><ns0:collection
xmlns:ns0="http://namspace/Service/1.0"><Record>
hello from nigeria
</Record></ns0:collection>

生成されたファイルはjoined次のとおりです。

<?xml version="1.0" encoding="UTF-8" ?><ns0:collection
xmlns:ns0="http://namspace/Service/1.0"><Record>
hello from nigeria



hello from nigeria



hello from nigeria



hello from nigeria



hello from nigeria
</Record></ns0:collection>

メモ:

  1. 最初の質問では、</Record></ns0:collection>両方だけでなく</ns0:collection></Record>

  2. すべてのファイルに対して1つのコマンドを実行できるように、ここのファイル名を変更する必要がありますn[1-3]。ここでは、最も適切な名前を選択しました。

  3. まず、テストを実行して結果を確認してください。、ここでは自動的にバックアップを作成するために使用しますi.baksed

関連情報