【问题标题】:How can I extract and save values from an XML file in Perl?如何在 Perl 中从 XML 文件中提取和保存值?
【发布时间】:2011-02-12 13:04:10
【问题描述】:

这是我在 Perl 脚本中尝试做的事情:

$data=""; 子 loadXMLConfig() { $filename="somexml.xml" $data = $xml->XMLin($filename); } 子 GetVariable() { ($FriendlyName) = @_; 开关($FriendlyName) { 案例“我的友好名称”{print $data->{my_xml_tag_name}} …… …… …… } }

问题是我使用 Perl 只是因为我从 XML 文件中读取,但我需要通过 shell 脚本获取这些变量。所以,这就是我正在使用的:

$ perl -e 'require "scrpt.pl"; loadConfigFile(); GetVariable("My Variable")' 

这完全符合预期,但每次获取变量时我都需要读取 XML 文件。有没有办法可以在 shell 调用中“保留”$data?我的想法是我只读取 XML 文件一次。如果没有,有没有更简单的方法可以做到这一点?这些是我无法改变的:

  • 配置文件是一个 XML
  • 需要 shell 脚本中的变量

【问题讨论】:

  • 请注意 Switch.pm 已弃用。 :)

标签: xml perl shell


【解决方案1】:

当我需要一些由 Perl 在 shell 脚本中检索到的信息时,我会通过 Perl 生成 shell 脚本并通过 eval 设置环境变量:

myscript

#!/bin/bash
BINDIR=`dirname $0`
CONFIG=$BINDIR/config.xml
eval `$BINDIR/readcfg $CONFIG`
echo Running on the $planet near the $star.

readcfg

#!/usr/bin/perl
use XML::Simple;
my $xml = XMLin('config.xml', VarAttr => 'name', ContentKey => '-content');
while (my ($k, $v) = each %{$xml->{param}}) {
    $v =~ s/'/'"'"'/g;
    $v = "'$v'";
    print "export $k=$v\n";
}

config.xml

<config>
    <param name="star">Sun</param>
    <param name="planet">Earth</param>
</config>

【讨论】:

  • 这每次都会读取XML文件,这是我以为你不想做的。
  • 不,您只读取 XML 一次,之后所有 XML 标记都只是 shell 变量,可以在您的 shell 脚本中使用,而无需再次调用 readcfg。
  • 我的意思是,每次运行 shell 脚本时它都会读取 XML。
【解决方案2】:

您可以分两步完成此操作。如果您还没有创建存储的 Perl 数据结构,那么您想创建一个存储的数据结构,并且当您创建存储版本时,您就不必再次解析它。

有很多方法可以做到这一点,但这里有一个使用Storable的版本:

 use Storable qw(nstore retrieve);

 my $stored_data_structure = 'some_file_name';

 my $data = do {
      # from the stored data structure if it is there
      if( -e $stored_data_structure ) {
           retrieve( $stored_data_structure );
           }
      # otherwise parse the xml and store it
      else {
           my $data = $xml->XMLin( $xml_filename );
           nstore( $data, $stored_data_structure );
           $data;
           }
      };

您也可以考虑颠倒您的概念。让你的 Perl 脚本调用你的 shell 脚本,而不是调用你的 Perl 脚本的 shell 脚本:

 # load the data, as before

 # set some environment variables
 $ENV{SomeThing} = $data->{SomeThing};

 # now that the environment is set up
 # turn into the shell script
 exec '/bin/bash', 'script_name'

【讨论】:

  • 谢谢,我测试过了,它成功了。但是,在读取每个变量时,它将从存储的文件中读取。但是谢谢,我不知道你可以在 perl 中做到这一点。
【解决方案3】:

您可以简单地将值存储在 shell 可执行文件中。 假设 bourne shell (sh) 脚本并且您事先知道您感兴趣的变量名称列表:

$data="";
sub loadXMLConfig()
{
     $filename="somexml.xml"
     $data = $xml->XMLin($filename);
}

sub GetVariable()
{
     ($FriendlyName) = @_;
     switch($FriendlyName)
     {
         case "My Friendly Name" {
             print "$FriendlyName='$data->{my_xml_tag_name}'; export $FriendlyName\n"
         } # Use "export var=value" form for bash
         ....
         ....
         ....
      }
}

sub storeVariables {
    # @variables list defined elsewhere - this is just a sketch
    foreach my $variable (@variables) { 
        GetVariable($variable);
    }
}

然后调用如下:

$ perl -e 'require "scrpt.pl"; loadConfigFile(); storeVariables();' > my_vars.sh
$ source my_vars.sh 

my_vars.sh 可以多次获取

【讨论】:

  • 谢谢,它肯定会工作。然而,有人提出了一种更优雅的方法,它基本上在 shell 端使用 eval 而不是加载文件来做同样的事情。
猜你喜欢
  • 1970-01-01
  • 2010-09-18
  • 1970-01-01
  • 1970-01-01
  • 2019-08-30
  • 1970-01-01
  • 2010-11-11
  • 2011-09-30
  • 1970-01-01
相关资源
最近更新 更多