2013-04-29 87 views
0

我有一个XML,它有一个“ - ”以及在它的头部和标签值的开头一个空格..我需要替换“_”没有(NULL)和删除XML的第二行即<HEADER ASOF_DATE="2/15/2013" CREATE_DATE="2/17/2013" RECORDS="5">XML搜索和替换值使用perl

并且在每个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; 
+0

[参考](http://stackoverflow.com/questions/2052179/how-can-i-find-and-replace-text-in-xml-using-perl) – gks 2013-04-29 08:26:24

+0

显示您完成的Perl代码至今。 – 2013-04-29 09:28:28

+0

同意上面提到的第一个答案,XML :: Twig是好的 – Vorsprung 2013-04-29 09:33:40

回答

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

+0

谢谢丹的投入...该脚本现在按预期工作,格式良好......但xml的第二行仍然没有被删除......我的目的是解析这个格式化的xml来执行一些其他操作..所以我想删除第二行,因为它只有信息字段...请帮助.. – Srini 2013-04-29 11:35:00

+0

@Srini,对不起原代码中的错误。问题是模式需要在多行上匹配,但代码一次只读取一行文件。我改变了代码将整个文件读入一个变量。 – 2013-04-29 12:17:32

+0

谢谢Dan ...我在运行代码..syntax时出现语法错误,在test1.pl第22行附近出现“$; 关闭” 执行test1.pl时因编译错误而中止。 – Srini 2013-04-29 12:52:40