I am using XML:twig to extract some attributes from an XML file using Perl;
Here is my code:

use XML::Twig;
my $file = $ARGV[0];
$file =~ /(.+)\.xml/;
my $outfile = $1.".snp" ;
open my $out,'>',$outfile or die "Could not open file '$outfile' $!";
my $twig = XML::Twig->new
(
twig_handlers => 
    {
        'Rs/MergeHistory' => \&MergeHistory,
    }
);
 $twig -> parsefile( "$file");
sub MergeHistory 
    {
        my ($twig, $elt) = @_;
        print $out "\t";
        print $out "rs";
                print $out $elt->att('rsId'), ",";
        print $out "b";
        print $out $elt->att('buildId'), ",";
    }

This print the following results:

rs56546490,b130, rs386588736,b142
rs56546490,b130, rs386588736,b142

What I want is to print each MergeHistory rsId and buildId together as the following:

rs56546490,rs386588736, b130,b142
rs56546490,rs386588736, b130,b142

Here is a part of the XML file which contains on two MergeHistory tags :

<Rs>
<MergeHistory rsId="56546490" buildId="130">
<MergeHistory rsId="386588736" buildId="142">
</Rs>
<Rs>
<MergeHistory rsId="56546490" buildId="130">
<MergeHistory rsId="386588736" buildId="142">
</Rs>

Recommended Answers

All 2 Replies

It's been a while since I've written anything in Perl, but one way of doing it would be to use two arrays--storing all of the "rsId" values in one array and all of the "buildId" values in the other array. Then print all of the "rsId" values separated by a comma and then all of the "buildId" values separated by a comma.

The following may be useful:
Perl string array - How to create and use an array of strings
See "Perl string array - another way to create a list of pizzas"

Hi Ahmed_65 ,

Getting your desired result is not difficult. Only that you have to write the data structure for what you wanted.
Please see perldsc. You will be glad you did eventually.
Since you could use XML::Twig half of the job is done. What you could do, is making something like putting an ARRAY OF ARRAY into an HASH like so:

{         # HASH 
    1   [   # ARRAY
        [0] [ # ARRAY
            [0] 56546490,
            [1] 386588736
        ],
        [1] [
            [0] 130,
            [1] 142
        ]
    ],
    3   [
        [0] [
            [0] 56546490,
            [1] 386588736
        ],
        [1] [
            [0] 130,
            [1] 142
        ]
    ]
}

Then, you can display your result as you deem fit.
Here is the code that produce that:

#!/usr/bin/perl -w
use strict;

use XML::Twig;

my %data = ( count => 0, );
my ( $rs, $build ) = ( [], [] ); # note here

my $twig =
  XML::Twig->new( twig_handlers => { 'li/MergeHistory' => \&merge_history } );

$twig->parsefile('doc.xml');   # or any name you want

sub merge_history {
    my ( $twig, $Rs ) = @_;

    push @{$rs},    $Rs->att('rsId');
    push @{$build}, $Rs->att('buildId');

    if ( $data{count} % 2 ) {
        my $value = $data{count};
        push @{ $data{$value} } => $rs, $build;
        ( $rs, $build ) = ( [], [] );
    }

    ++$data{count};
}

delete $data{count};
print join ' ' => map { @{$_} }
  map { @{ $data{$_} } } sort { $a <=> $b } keys %data;

Lastly, the desired display of the final result is left for the OP. Need I say, that your XML is not properly formed. You might have to look into that also. You might you a foreach loop instead of map has i have used.

Cheers.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.