代码之家  ›  专栏  ›  技术社区  ›  PJ.

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

  •  5
  • PJ.  · 技术社区  · 16 年前

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

    请告诉我怎么做。

    事先谢谢。

    我希望输出文件保存在同一目录中,如果可能的话,使用相同的名称。有可能吗?

    4 回复  |  直到 8 年前
        1
  •  4
  •   Sinan Ünür    16 年前

    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:简单 如果您做一些有趣的事情,会有点麻烦,因为它的目的不是成为通用的XML库,而是提供一种处理用XML编写的配置文件的简单方法。

    CPAN过多 XML related modules . 除非这是您必须处理的一次性问题,否则值得研究一些功能更强、更适合的模块。

        2
  •  8
  •   AndyG    9 年前

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

    铌。如果不想保留备份文件,请删除第二个arg(“bak_*”)。

        3
  •  4
  •   Peter Kovacs    16 年前

    为什么要把它作为XML来处理呢?为什么不直接用regexp替换呢?

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

    这将完成替换,保持相同的文件名和所有内容。

        4
  •  3
  •   Nifle Hassan Syed    16 年前

    你试过了吗? XMLout with OutputFile

    从XML::Simple的文档中:

    xmlout()的默认行为是以字符串形式返回XML。如果要将XML写入文件,只需使用“outputfile”选项提供文件名。
    此选项还接受一个IO句柄对象-在Perl5.8.0和更高版本中特别有用,用于使用UTF-8以外的编码输出,例如:

    open my $fh, '>:encoding(iso-8859-1)', $path or die "open($path): $!";
    XMLout($ref, OutputFile => $fh);