我有一个格式为的XML文件:
<outer1>
<inner1>
<name>Stonecold</name>
<profession>warrior</profession>
<org>wwf</org>
</inner1>
<inner1>
<name>Shanebond</name>
<profession>Bowler</profession>
<org>newzealand</org>
</inner1>
<inner1>
<name>brain schemidit</name>
<profession>Chairman</profession>
<org>Google</org>
</inner1>
</outer1>
我想将Shanebond
的值更改为Shane Bond
。
我使用的是XML::Simple
,但结果是哈希。
我想要与输入文件相同的格式。例如:输出文件应如下所示:
<outer1>
<inner1>
<name>Stonecold</name>
<profession>warrior</profession>
<org>wwf</org>
</inner1>
<inner1>
<name>Shane Bond</name>
<profession>Bowler</profession>
<org>newzealand</org>
</inner1>
<inner1>
<name>brain schemidit</name>
<profession>Chairman</profession>
<org>Google</org>
</inner1>
</outer1>
请告知如何做到这一点。
提前致谢。
我希望将输出文件保存在同一目录中,如果可能的话,使用相同的名称。有可能吗?
答案 0 :(得分:8)
在阅读或操作XML文件时,XML::Twig通常是我希望使用的第一个工具。
起初我认为这可能对你的要求有些过分但后来我发现它确实附带了一个parsefile_inplace()选项:
use strict;
use warnings;
use XML::Twig;
XML::Twig->new(
pretty_print => 'indented',
twig_handlers => {
name => sub {
$_->set_text( 'Shane Bond' )->flush if $_->text eq 'Shanebond'
},
},
)->parsefile_inplace( 'data.xml', 'bak_*' );
NB。如果您不想保留备份文件,请删除第二个arg('bak _ *')。
答案 1 :(得分:5)
为什么还要把它当作XML来处理呢?为什么不做一个regexp-replace?
perl -pi -e 's/Shanebond/Shane Bond/' filename.xml
这将替换到位,保持相同的文件名和所有内容。
答案 2 :(得分:4)
XML::Simple
有一些选项,允许您指定如何将输入转换为Perl数据结构以及如何输出该结构:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Simple;
my $xml_file = 'b.xml';
my $xml = XMLin(
$xml_file,
KeepRoot => 1,
ForceArray => 1,
);
$xml->{outer1}->[0]->{inner1}->[1]->{name} = 'Shane Bond';
XMLout(
$xml,
KeepRoot => 1,
NoAttr => 1,
OutputFile => $xml_file,
);
如果你做任何有趣的事情, XML::Simple
确实有点毛茸茸,因为它的目的不是成为通用的XML库,而是提供一种简单的方法来处理用XML编写的配置文件。
CPAN有过多的XML related modules。除非这是一个你必须处理的一次性问题,否则值得研究一些功能更强大,更适合的模块。
答案 3 :(得分:3)
您是否尝试过XMLout with OutputFile
来自XML :: Simple的文档:
XMLout()的默认行为是将XML作为字符串返回。如果您希望将XML写入文件,只需使用“OutputFile”选项提供文件名即可 此选项还接受IO句柄对象 - 在Perl 5.8.0及更高版本中使用UTF-8以外的编码进行输出尤其有用,例如:
open my $fh, '>:encoding(iso-8859-1)', $path or die "open($path): $!";
XMLout($ref, OutputFile => $fh);