Как я могу извлечь и сохранить значения из файла XML в Perl? - PullRequest
4 голосов
/ 26 апреля 2010

Вот что я пытаюсь сделать в скрипте 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, но мне нужно получить эти переменные с помощью сценария оболочки. Итак, вот что я использую:

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

Это работает точно так, как ожидалось, но мне нужно читать XML-файл каждый раз, когда я получаю переменную. Есть ли способ, которым я мог бы "сохранить" $data через вызовы оболочки? Идея в том, что я прочитал XML-файл только один раз. Если нет, есть ли более простой способ сделать это? Это то, что я не могу изменить:

  • Файл конфигурации представляет собой XML
  • Нужны переменные в скрипте оболочки

Ответы [ 3 ]

5 голосов
/ 26 апреля 2010

Когда мне нужна некоторая информация, полученная Perl, в сценарии оболочки, я генерирую сценарий оболочки Perl и задаю переменные среды с помощью 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>
2 голосов
/ 26 апреля 2010

Вы можете сделать это в два этапа. Вы хотите создать сохраненную структуру данных 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-скрипт, пусть ваш Perl-скрипт вызывает ваш сценарий оболочки:

 # 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'
1 голос
/ 26 апреля 2010

Вы можете просто сохранить значения в исполняемом файле оболочки. Предполагается, что скрипт 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 может быть получен много раз

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...