I am new to Perl, and am trying to apply a filter condition on XML files using the XML::Twig
module.
Following is my code:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my $SOURCEFILE = $ARGV[0];
my $FILELOCATIONIN = $ARGV[1];
my $twig = new XML::Twig( twig_handlers => { 'STOCKEXT/STOCK' => \&STOCK } );
$twig->parsefile($FILELOCATIONIN.'/'.$SOURCEFILE.'.xml');
$twig->set_pretty_print('indented');
$twig->print_to_file($FILELOCATIONIN.'/'.$SOURCEFILE.'out.xml');
sub TRADE {
my ( $twig, $STOCK ) = @_;
foreach my $c ($STOCK)
{
$c->delete($STOCK)
unless
$c->att('origin') eq "HIGH_TRADE"
;
}
}
Following is my XML :
<STOCKEXT>
<STOCK origin = "HIGH_TRADE"/>
<STOCK origin = "HIGH_TRADE"/>
<STOCK origin = "HIGH_TRADE"/>
<STOCK origin = "LOW_TRADE"/>
<STOCK origin = "LOW_TRADE"/>
<STOCK origin = "AVERAGE_TRADE"/>
</STOCKEXT>
Filtered Output XML:
<STOCKEXT>
<STOCK origin = "HIGH_TRADE"/>
<STOCK origin = "HIGH_TRADE"/>
<STOCK origin = "HIGH_TRADE"/>
</STOCKEXT>
Now I am stuck, as I want to pass comma-separated argument in the command line so that HIGH_TRADE
as well as AVERAGE_TRADE
become legitimate STOCK
.
As can be seen, in my current code, I pass two arguments. But I want to pass three arguments, third should be the filter condition in comma-separated format.
Hence, I am expecting my code to be invoked as
perl stock_filter.pl file_name.xml /opt/XML HIGH_TRADE,AVERAGE_TRADE
The third argument will be split and checked against the origin
attribute of each STOCK
element to declare it as legitimate.
This will help in future to change the filter conditions. Any addition or subtraction of filter condition will not change the code.
One way to do this is to store the values that you want to keep in a hash.
Create the hash at the top of the script:
my @origins_to_keep= split /,/, $ARGV[2];
my %keep= map { $_ => 1 } @origins_to_keep;
Use it in the handler:
$c->delete($STOCK) unless $keep{$c->att('origin')}