如何从Perl中的XML文件中提取和保存值?

时间:2010-04-26 18:43:54

标签: xml perl shell

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

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

sub GetVariable()
{
     ($FriendlyName) = @_;
     switch($FriendlyName)
     {
         case "My Friendly Name" {print $data->{my_xml_tag_name}}
         ....
         ....
         ....
      }
}

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

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

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

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

3 个答案:

答案 0 :(得分:5)

当我需要一些由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>

答案 1 :(得分:2)

您可以分两步完成此操作。如果尚未创建存储的Perl数据结构,则需要创建存储的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'

答案 2 :(得分:1)

您只需将值存储在shell-executable文件中即可。 假设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可以多次获取