Perl twig,从一个xml获取属性值并更新其他值

时间:2014-03-26 22:06:12

标签: xml perl xml-twig

use strict;
use warnings;
use Data::Dumper;
use XML::Twig;
use Getopt::Long;
use Pod::Usage;
my %VERSION_HASH;
my $BRANCH_NAME;
my $HELP;
my $DEFAULT_XML;
my $VERSIONED_XML;
GetOptions(
   "help"            => \$HELP,
   "branch=s"        => \$BRANCH_NAME,
   "defaultxml=s"    => \$DEFAULT_XML,
   "versionedxml=s"  => \&VERSIONED_XML,
) or pod2usage( { -verbose => 1 } );
if (defined $HELP) {
   pod2usage( { -verbose => 2 } );
}
my $UPDATE_XML= XML::Twig->new( 
    twig_handlers => {
        q{project[@path =~ /\bopensource\b/]} => \&fix_opensource_revision,
        q{default} => \&update_default_branch_name,
        q{project[@path !~ /\bopensource\b/]} => \&remove_revision_attribute,
        q{project[@path =~ /\bdocs\b/]} => \&fix_docs_to_master,
        q{remote[@name =~ /\bgit-rc\b/]} => sub { $_->delete; },
    },
);
my $REF_XML= XML::Twig->new(
    twig_handlers => {
        q{project[@path =~ /\bopensource\b/]} => \&read_version_into_hash,
    },
    pretty_print => 'indented',
);
$DEFAULT_XML = 'default.xml' if !($DEFAULT_XML);
$VERSIONED_XML = 'versioned.xml' if !($VERSIONED_XML);
$REF_XML->parsefile( $VERSIONED_XML );
#using "parsefile_inplace" is making default.xml as 0 byte.
$UPDATE_XML->parsefile_inplace( $DEFAULT_XML);
#below print works good
#$UPDATE_XML->parsefile( $DEFAULT_XML);
#$UPDATE_XML->print;
sub read_version_into_hash
{
    my ($twig, $project) = @_;
    $project->set_att(
        revision => $project->{att}{revision},
    );
        $VERSION_HASH{$project->{att}{path}}=$project->{att}{revision};
}
sub fix_opensource_revision {
    my ($twig, $project) = @_;

    if ($VERSION_HASH{$project->{att}{path}})
    {
        $project->set_att(
        revision => $VERSION_HASH{$project->{att}{path}},
        );
    }
    else
    {
        die "No revision found for $project->{att}{path}\n";
    }
}
sub update_default_branch_name {
    my ($twig, $default) = @_;
    $default->set_att(
        revision => $BRANCH_NAME,
        );
    }  
sub remove_revision_attribute {
    my ($twig, $project) = @_;
    $project->del_att(
        'revision'
        );
    }
sub fix_docs_to_master {
    my ($twig, $project) = @_;
    $project->set_att(
        revision => 'master',
        );
}

上面的脚本将default.xml设为0kb文件,因为在屏幕上打印效果很好。

default.xml片段

<project path="LINUX/opensource/utils" revision="apple" name="le/utils" x-ship="oss" x-quic-dist="le"/>

versioned.xml片段

<project path="LINUX/opensource/utils" revision="e10616sggf012"/>

如果我能做些什么来减少代码行,请告诉我。

1 个答案:

答案 0 :(得分:2)

查看以下文档:XML::Twig - Processing an XML document chunk by chunk。显然,需要在您的任何处理程序内部调用flush,以表明您在进行就位时已完成该部分。

我将此技术应用于您发布的上一个帖子中的数据:Updating xml attribute value based on other with Perl,它似乎有用。

在此代码中将其应用于您的一个处理程序:

sub update_default_branch_name {
    my ($twig, $default) = @_;
    $default->set_att( revision => $BRANCH_NAME );
    $twig->flush;
}