3

以下は、私が使用する XML です。

<a>

<id>ABC</id>

<class />

<gender />

</a>

タグ「id」を検索し、値「ABC」を「DEF」に置き換える Perl コードを書きたいと思います。

ただし、上記の XML のネストは変更される可能性があります。そのため、正確な位置とは無関係にタグ「id」を検索する一般化されたコードを作成したいと考えています。

今まで、ABC の値を置き換えることができるロジックを取得できましたが、これにより、コードがタグ「id」の位置を静的にします。

#!usr/bin/perl
use warnings;
use XML::Simple;
use Spreadsheet::ParseExcel;
use Data::Dumper;
my $FileName = 'sample.xls';
my $xml_file = 'hello.xml';
$par=$ARGV[0];
my $xml = XMLin($xml_file,
    KeepRoot=>1,
    ForceArray=>1,);
$xml->{a}->[0]->{id}='DEF';
XMLout(
    $xml,
    KeepRoot =>1 ,
    NoAttr =>1,
    OutputFile => $xml_file,
        );
    }
4

3 に答える 3

7

XPathは、ツリー内の位置を知らなくてもノードを見つけることができます。

use strictures;
use XML::LibXML qw();
my $dom = XML::LibXML->load_xml(string => <<'XML');
<a>
<id>ABC</id>
<class />
<gender />
</a>
XML

for my $id ($dom->findnodes('//id[string()="ABC"]')) {
    $id->removeChildNodes;
    $id->appendText('DEF');
}

print $dom->toString
于 2012-07-14T09:25:33.090 に答える
4

単純な XML::Twig ソリューションは次のようになります。

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

my $FILE= 'id.xml';

XML::Twig->new( twig_handlers => { 'id[string()="ABC"]' => sub { $_->set_text( 'DEF'); } },
                keep_spaces => 1,
              )
          ->parsefile( $FILE)
          ->print_to_file( $FILE);

string()楽しみのために: 効率的な XML::Twig ソリューションは、主にで条件を使用できないため、もう少し複雑ですtwig_roots。それでも、非常にコンパクトで、ファイル全体をメモリにロードすることはありません。

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

XML::Twig->new( twig_roots =>    { id => sub { $_->flush }, },
                twig_handlers => { 'id[string()="ABC"]' => sub { $_->set_text( 'DEF'); } },
                twig_print_outside_roots => 1,
              )
          ->parsefile_inplace( 'id.xml');
于 2012-07-16T10:33:51.043 に答える