Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Perl中从XML文件提取和保存值?_Xml_Perl_Shell - Fatal编程技术网

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

如何在Perl中从XML文件提取和保存值?,xml,perl,shell,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->

以下是我试图在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}} .... .... .... } } 这与预期完全一样,但每次获取变量时,我都需要读取XML文件。有没有一种方法可以跨shell调用“保留”
$data
?我的想法是只读取XML文件一次。如果没有,有没有更简单的方法?这些是我无法改变的:

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

您可以通过两个步骤完成此操作。如果您还没有创建存储的Perl数据结构,那么您需要创建存储的Perl数据结构,当您创建了存储的Perl数据结构时,您可以创建存储的版本,这样就不必再次解析它

有很多方法可以实现这一点,但这里有一个版本使用:

<>你也可以考虑翻转你的概念。让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检索的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.
#!/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>
    <param name="star">Sun</param>
    <param name="planet">Earth</param>
</config>
readcfg

#!/bin/bash
BINDIR=`dirname $0`
CONFIG=$BINDIR/config.xml
eval `$BINDIR/readcfg $CONFIG`
echo Running on the $planet near the $star.
#!/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>
    <param name="star">Sun</param>
    <param name="planet">Earth</param>
</config>
config.xml

#!/bin/bash
BINDIR=`dirname $0`
CONFIG=$BINDIR/config.xml
eval `$BINDIR/readcfg $CONFIG`
echo Running on the $planet near the $star.
#!/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>
    <param name="star">Sun</param>
    <param name="planet">Earth</param>
</config>

太阳
土

您只需将值存储在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可以多次采购

请注意,Switch.pm已被弃用。:)谢谢,我测试过了,成功了。但是,在每次读取变量时,它都将从存储的文件中读取。但是谢谢,我不知道你可以用perl来做这件事。谢谢,它肯定会有用的。但是,有人提出了一种更优雅的方法,基本上在shell端使用eval做同样的事情,而不是加载文件。每次都会读取XML文件,这是我认为您不想做的。不,您只读取XML一次,之后,所有XML标记都只是shell变量,可以在shell脚本中使用,而无需再次调用readcfg。