你已经标记了perl,所以我会提供一个perl解决方案。我可以提供的最好的建议一般是使用解析器,因为XML是一种可解析的语言,存在很好的解析器。对于这类工作,我特别喜欢XML::Twig
(XML::LibXML
也很不错,但不会进行就地编辑)。
我强烈建议您避免使用正则表达式 - XML
is not well suited to parsing via regex, because it's contextual and regex isn't。
这里有一堆对XML可以做出的完全有效的更改,比如一元标记,缩进和行分割等,它们在语义上相同,但是混乱地打破了正则表达式。因此,未来人们做出的改变 - 就他们所关心的是重新格式化XML而言是有效的/微不足道的 - 将因为脚本无法正确处理而打破“下游”。此外 - xpath
是很像正则表达式,但是上下文,因此非常适合解析/处理XML
。
#!/usr/bin/env perl
use warnings;
use strict;
use XML::Twig;
my $twig = XML::Twig -> parse (\*DATA);
my $to_insert = XML::Twig::Elt -> new ( 'entry', {key => "requestable"});
$to_insert -> insert_new_elt ('value') -> insert_new_elt('Boolean', "true");
print "Generated new XML:\n";
$to_insert -> print;
my $insert_this = $to_insert -> cut;
my $insert_after = $twig -> findnodes ('//entry[@key="mergeTemplates"]',0);
$to_insert -> paste (after => $insert_after);
print "Generated XML:\n";
$twig -> set_pretty_print('indented');
$twig -> print;
__DATA__
<xml>
<entry key="mergeTemplates" value="false"/>
<entry key="sysDescriptions"/>
</xml>
这可以适于使用XML::Twig
的parsefile_inplace
方法相当轻易:
#!/usr/bin/env perl
use warnings;
use strict;
use XML::Twig;
sub insert_merge {
my ($twig, $insert_after) = @_;
my $to_insert = XML::Twig::Elt->new('entry', { key => "requestable" });
$to_insert->insert_new_elt('value')->insert_new_elt('Boolean', "true");
$to_insert->paste(after => $insert_after);
$twig -> flush;
}
my $twig =
XML::Twig->new(
twig_handlers => { '//entry[@key="mergeTemplates"]' => \&insert_merge },
pretty_print => 'indented');
#glob finds files, if you want something more extensive then File::Find::Rule
foreach my $filename (glob ("/path/to/dir/*xml")) {
$twig->parsefile_inplace($filename);
}
代码工作就像一个魅力!我正在sed,perl,java试图让它正确!谢谢。 – jatinshetty
我很高兴这很有帮助。你可以接受答案,如果你愿意的话) –