2013-05-09 46 views
1

我在一個文件夾「c:\ srini \ perl \ in \」中有多個XML文件...所有這些文件的結構都是一樣的......我需要在每個XML中搜索兩個標籤,並且如果該TAG值在其中包含「@@@」......則必須替換爲「&」...它必須檢查兩個標籤值SHORT_DESC和XXX_NAME ...如果任何一個變量值中有「@@@」 ..它必須與「&」取代.. 下面是XML文件....使用perl替換一個文件夾中的多個XML文件的值

<TOPHEADER> 
<HEADER> 
<NAME>ABC LTD</NAME> 
<SHORT_DESC>ABC COMPY @@@ LTD</SHORT_DESC> 
<XXX_NAME>ABC COMPANY FOR XXX AND YYY </XXX_NAME> 
</HEADER> 
<HEADER> 
<NAME>XYZ LTD</NAME> 
<SHORT_DESC>XYZ COMPY @@@ LTD</SHORT_DESC> 
<XXX_NAME>XYZ COMPANY FOR @@@</XXX_NAME> 
</HEADER> 
<HEADER> 
<NAME>DEF LTD</NAME> 
<SHORT_DESC>DEF COMPY AND LTD</SHORT_DESC> 
<XXX_NAME>DEF COMPANY FOR @@@</XXX_NAME> 
</HEADER> 
</TOPHEADER> 

我用下面的代碼來替換單個文件的標籤值..但想知道是否有更好的方法來處理多個文件....

open (my $input_file, '<', 'c:\srini\perl\in\test1.xml') or die "unable to open $input_file $!\n"; 
open (my $output_file, '>', 'c:\srini\perl\in\test1_out.xml') or die "unable to open $output_file $!\n"; 

my $input; 
{ 
local $/;    #Set record separator to undefined. 
$input = <$input_file>; #This allows the whole input file to be read at once. 
} 
$input =~ s/@@@/&/g; 

print {$output_file} $input; 

close $input_file or die $!; 
close $output_file or die $!; 
+0

也有一種方法,我們可以編輯同一個文件,並替換值..我不希望用_out擴展名創建新文件... – Srini 2013-05-09 07:10:16

回答

2

你意識到你的輸出不會是有效的XML吧?需要在XML中轉義&。希望這僅僅是一個例子,而不是真正的價值。

這麼說,我希望使用XML ::嫩枝要做到這一點「的XML方式」™,例如,這是非常簡單的:

#!/usr/bin/perl 

use strict; 
use warnings; 

use XML::Twig; 

my $dir= shift @ARGV or die "usege: $0 <dir>\n"; 

foreach my $file (glob("$dir/*.xml")) 
    { XML::Twig->new(twig_roots => { SHORT_DESC => \&replace, # only those elements will be checked 
            XXX_NAME => \&replace, 
            }, 
        twig_print_outside_roots => 1,   # the rest will be output as-is 
        keep_spaces => 1, 
       ) 
      ->parsefile_inplace($file);     # the original file will be updated 
    } 

exit; 

sub replace 
    { my($t, $elt)= @_; 
    $elt->subs_text(qr/@@@/, '&')->print; 
    } 

輸出將被良好的XML(即it will look like <SHORT_DESC>ABC COMPY &amp; LTD</SHORT_DESC> )。如果您確實需要不要轉義&,則子文件中的行應爲$elt->subs_text(qr/@@@/, '&')->set_asis(1)->print;,撥打set_asis可防止元素的文本被轉義。

請確保您的原始XML格式良好,否則將不會被處理(儘管您不會丟失數據)。

+0

感謝您的更新和代碼的mirod ..我跑的代碼與實際的XMl和「&」值被替換爲「&」...有沒有一種方法,我可以代替「&」,而不是「&」 – Srini 2013-05-09 08:47:41

+1

得到它謝謝 !!!我用$ elt-> subs_text(qr/@@@ /,'&') - > set_asis(1) - > print; – Srini 2013-05-09 08:53:39

0

opendir/readdir/closedir功能讓我們通過遍歷directoy的文件systemobjects:

my $dir = ***dir goes here***; 
my $d = opendir(); 
map { 
    if (
     -f "$dir/$_" 
     && ($_ =~ "\.xml$") 
    ) { 
     open (my $input_file, '<',) or die "unable to open $input_file $!\n"; 

     my $input; 
     { 
      local $/;    #Set record separator to undefined. 
      $input = <$input_file>; #This allows the whole input file to be read at once. 
     } 
     close $input_file; 

     $input =~ s/@@@/&/g; 

     open (my $output_file, '>', "$dir/$_") or die "unable to open $output_file $!\n"; 
     print {$output_file} $input; 

     close $output_file or die $!; 
    } 
} readdir($d); 
closedir($d); 
+0

嗨...代碼的Thx ...但我在執行代碼時遇到下面的錯誤..沒有足夠的參數在replace2.pl行2附近的opendir,在$ dir或「 Final $附近應該是\ $或$ name在replace2.pl行6,字符串 語法錯誤在replace2.pl第20行,在「}〜」處附近出現語法錯誤「}」 由於編譯錯誤,執行replace2.pl中止。 – Srini 2013-05-09 08:31:27

相關問題