您已将其标记为 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);
}