0

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

在每条 XML 记录的 NAME 列或 SHORT_DESC 列下,可能有也可能没有“&”。如果它存在于 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;
4

1 回答 1

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是一个很好的

于 2013-04-29T10:37:26.843 回答