Frage

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',
        );
}

Above script is making the default.xml as 0kb file, where as printing on screen works good.

default.xml snippet

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

versioned.xml snippet

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

Also please let me know if I can do something to reduce the lines of code.

War es hilfreich?

Lösung

Check out the following documentation: XML::Twig - Processing an XML document chunk by chunk. Apparently, one needs to call the flush inside any of your handlers to indicate that you're done with that section whenever doing inplace.

I applied this technique to the data in the previous thread you posted: Updating xml attribute value based on other with Perl and it appeared to work.

Applying it to one of your handlers in this code:

sub update_default_branch_name {
    my ($twig, $default) = @_;
    $default->set_att( revision => $BRANCH_NAME );
    $twig->flush;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top