如何通过从命令行传递参数在Perl中应用IN子句

如何通过从命令行传递参数在Perl中应用IN子句,perl,xml-twig,Perl,Xml Twig,我是Perl新手,正在尝试使用该模块对XML文件应用过滤条件 以下是我的代码: #!/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 } );

我是Perl新手,正在尝试使用该模块对XML文件应用过滤条件

以下是我的代码:

#!/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"

      ;
    }
}
以下是我的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>
第三个参数将被拆分并对照每个
STOCK
元素的
origin
属性进行检查,以声明其合法性


这将有助于将来更改过滤器条件。对筛选条件的任何加减都不会更改代码。

一种方法是将要保留的值存储在哈希中

在脚本顶部创建哈希:

my @origins_to_keep= split /,/, $ARGV[2];
my %keep= map { $_ => 1 } @origins_to_keep;
在处理程序中使用它:

$c->delete($STOCK) unless $keep{$c->att('origin')}

一种方法是将要保留的值存储在散列中

在脚本顶部创建哈希:

my @origins_to_keep= split /,/, $ARGV[2];
my %keep= map { $_ => 1 } @origins_to_keep;
在处理程序中使用它:

$c->delete($STOCK) unless $keep{$c->att('origin')}

对我来说最明显的解决方案是使用模块中的
any
功能

下面是您自己的代码版本,其中包括一些其他修改。最重要的是,我使用了模块中的
catfile
函数来更安全地组合路径和文件名

use strict;
use warnings;
use 5.014;    # For non-destructive substitution

use XML::Twig;
use File::Spec::Functions 'catfile';
use List::Util 'any';

my ($source_file, $file_location, $stock_origins) = @ARGV;

my $twig = XML::Twig->new(
    twig_handlers => { 'STOCKEXT/STOCK' => \&stock_handler },
    pretty_print  => 'indented',
);

my $full_input    = catfile($file_location, $source_file);
my @stock_origins = split /,/, $stock_origins;
my $full_output   = $full_input =~ s/(?=\.[^.]+\z)/_out/r;

$twig->parsefile($full_input);
$twig->print_to_file($full_output);

sub stock_handler {
  my ( $twig, $stock ) = @_;
  my $origin = $stock->att('origin');

  $stock->delete unless any { $origin eq $_ } @stock_origins;
}
输出

<STOCKEXT>
  <STOCK origin="HIGH_TRADE"/>
  <STOCK origin="HIGH_TRADE"/>
  <STOCK origin="HIGH_TRADE"/>
  <STOCK origin="AVERAGE_TRADE"/>
</STOCKEXT>

对我来说最明显的解决方案是使用模块中的
任何
功能

下面是您自己的代码版本,其中包括一些其他修改。最重要的是,我使用了模块中的
catfile
函数来更安全地组合路径和文件名

use strict;
use warnings;
use 5.014;    # For non-destructive substitution

use XML::Twig;
use File::Spec::Functions 'catfile';
use List::Util 'any';

my ($source_file, $file_location, $stock_origins) = @ARGV;

my $twig = XML::Twig->new(
    twig_handlers => { 'STOCKEXT/STOCK' => \&stock_handler },
    pretty_print  => 'indented',
);

my $full_input    = catfile($file_location, $source_file);
my @stock_origins = split /,/, $stock_origins;
my $full_output   = $full_input =~ s/(?=\.[^.]+\z)/_out/r;

$twig->parsefile($full_input);
$twig->print_to_file($full_output);

sub stock_handler {
  my ( $twig, $stock ) = @_;
  my $origin = $stock->att('origin');

  $stock->delete unless any { $origin eq $_ } @stock_origins;
}
输出

<STOCKEXT>
  <STOCK origin="HIGH_TRADE"/>
  <STOCK origin="HIGH_TRADE"/>
  <STOCK origin="HIGH_TRADE"/>
  <STOCK origin="AVERAGE_TRADE"/>
</STOCKEXT>


Global symbol“%keep”需要显式的包名..它抛出的错误…不明白为什么..明白了…不是我的$keep=map{$\u=>1}origins\u to\u keep,而是我的%keep=map{$\u=>1}@origins\u to\u keep,因为它是散列…谢谢…哦,在answerGlobal symbol“%keep”中修复了需要显式的包名..它抛出的错误…不理解为什么..得到了它…而不是我的$keep=map{$\=>1}origins\u to\u keep,它应该是我的%keep=map{$\=>1}@origins\u to\u keep,因为它是散列…谢谢…哦,答案中的“any”不是由List::Util模块导出的…这是我面临的错误…任何想法…先生..“any”列表::Util模块未导出…这是我面临的错误…有什么想法吗…先生。。