XML使用perl搜索和替换值

时间:2013-04-29 06:59:13

标签: xml perl

我有一个XML,它有一个“ - ”以及它下面的标题和标记值开头的一个空格。我需要将“_”替换为空(NULL)并删除XML的第二行这是<HEADER ASOF_DATE="2/15/2013" CREATE_DATE="2/17/2013" RECORDS="5">

并且在每个XML记录的NAME列或SHORT_DESC列下可能有或可能不是“&amp;” ..如果它存在于NAME列中,则必须将其替换为“$$$”并保存文件...

以下是XML文件..

- <HEADER>
- <HEADER ASOF_DATE="2/15/2013" CREATE_DATE="2/17/2013" RECORDS="5">
- <TAG>
<SHORT_DESC>XXX & CO MTN RegS</SHORT_DESC> 
<NAME>XXX & CO</NAME> 
</TAG>
- <TAG>
<SHORT_DESC>XYZ & DEV</SHORT_DESC> 
<NAME>XYZ & DEVELOP</NAME> 
</TAG>
- <TAG>
<SHORT_DESC>AB&C INC</SHORT_DESC> 
<NAME>AB&C INC</NAME> 
</TAG>
- <TAG>
<SHORT_DESC>AAA BBB & COMPANY</SHORT_DESC> 
<NAME>AAA BBB & COMPANY</NAME> 
</TAG>
- <TAG>
<SHORT_DESC>ABC XYZ</SHORT_DESC> 
<NAME>ABC XYZ</NAME> 
</TAG>
- </HEADER>

o / p应该是..

<HEADER>
<TAG>
<SHORT_DESC>XXX $$$ CO MTN RegS</SHORT_DESC> 
<NAME>XXX $$$ CO</NAME> 
</TAG>
<TAG>
<SHORT_DESC>XYZ $$$ DEV</SHORT_DESC> 
<NAME>XYZ $$$ DEVELOP</NAME> 
</TAG>
<TAG>
<SHORT_DESC>AB$$$C INC</SHORT_DESC> 
<NAME>AB$$$C INC</NAME> 
</TAG>
<TAG>
<SHORT_DESC>AAA BBB $$$ COMPANY</SHORT_DESC> 
<NAME>AAA BBB $$$ COMPANY</NAME> 
</TAG>
<TAG>
<SHORT_DESC>ABC XYZ</SHORT_DESC> 
<NAME>ABC XYZ</NAME> 
</TAG>
</HEADER>

下面是代码......但它没有保存带有更改的xml文件

#!/usr/bin/perl

use strict;
use warnings;

my $tag = 'SHORT_DESC';

open my $fh, '<test.xml' or die $!;

foreach (<$fh>) {
  s/&/@@@/g;
  s/- //g;
  print $_;
}
close $fh;

1 个答案:

答案 0 :(得分:0)

您没有更改文件,因为您只是打开它进行阅读。

您需要打开另一个文件来编写输出:

#!/usr/bin/perl

use strict;
use warnings;

my $tag = 'SHORT_DESC';

open my $input_file, '<', 'test.xml' or die $!;
open my $output_file, '>', 'test_out.xml' or die $!;

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;
$input =~ s/^- (?=<)//gm;
$input =~ s/<header[^>]*>\K\s*<header[^>]*>//gis;
print {$output_file} $input;

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

注意:可以在Perl中就地编辑文件。但在大多数情况下,我建议写入另一个文件。它更方便测试和更安全 - 您不会有丢失原件的风险。

我修改了你的正则表达式:

s/^- (?=<)//g

我添加了一个^,因此您只能在该行的开头删除它,并预测(?=<),以确保它仅在标记之前删除它

删除第二个<header>标记有点复杂。这取决于你究竟想做什么。这是一种方法:

s/<header[^>]*>\K\s*<header[^>]*>//gis;

每当它找到两个仅由空格分隔的标题标记时,它会删除第二个标记标记。 \K保留之前匹配的内容;因此,只删除第二个。

只要将XML文件转换为有效的表单,就应该使用XML解析模块进行任何进一步的操作。 XML::Twig is a good one