我在文件夹“c:\ srini \ perl \ in \”中有多个XML文件...所有这些文件的结构是相同的...我需要在每个XML中搜索两个标记,如果是TAG值中包含“@@@”...必须替换为“&” ...它必须检查两个标签值SHORT_DESC和XXX_NAME ...如果任何TAG值中有“@@@”,则必须将其替换为“&”.. 下面是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 :(得分:2)
您意识到您的输出不是有效的XML吗? &amp;需要在XML中进行转义。希望这只是一个例子而不是真正的价值。
那就是说,我想要这样做“XML way”™,例如使用XML :: Twig,这非常简单:
#!/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 & LTD</SHORT_DESC>
)。如果你确实需要&amp;如果不进行转义,则sub中的行应为$elt->subs_text( qr/@@@/, '&')->set_asis( 1)->print;
,对set_asis
的调用会阻止元素的文本转义。
确保您的原始XML格式正确,或者不会被处理(尽管您不会丢失数据)。
答案 1 :(得分:0)
使用opendir
/ readdir
/ closedir
函数可以遍历directoy的文件系统对象:
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);