在Perl中,如何在不改变XML格式的情况下改变XML文件中元素的内容?

lhcgjxsq  于 8个月前  发布在  Perl
关注(0)|答案(4)|浏览(83)

我有一个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>

请建议如何做到这一点。
先谢了。
我希望输出文件被保存在同一个目录中,如果可能的话,使用相同的名称。可以吗?

htrmnn0y

htrmnn0y1#

当涉及到阅读或操作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_*' );

注意:如果你不想保留备份文件,那么删除第二个参数('bak_bak')。

rsaldnfx

rsaldnfx2#

为什么要麻烦地把它作为XML来处理呢?为什么不直接做一个regexp-replace呢?

perl -pi -e 's/Shanebond/Shane Bond/' filename.xml

这将在适当的位置进行替换,保持相同的文件名和所有内容。

zte4gxcn

zte4gxcn3#

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。除非这是一个一次性的问题,你必须处理,这将是值得研究一些更强大和更适合的模块。

46scxncf

46scxncf4#

你有没有尝试过XMLout和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);

相关问题