提取变量并将其添加到单独的XML文件中

Bio*_*Rod 1 xml perl

我有一个可以登录并返回会话ID的脚本。我需要会话ID,以便可以填充XML文件来处理它,例如,为苗圃创建工厂房间。

#!/usr/bin/perl -w

use strict;

use LWP::UserAgent;
use Data::Dumper;
use XML::Simple;

my $authenticate = do {
    open my $fh, '<', '/tmp/login.xml' or die "Could not open file: $!";
    local $/;
    <$fh>;
};

my $webpage = "https://www.example.com/api";

my $ua = LWP::UserAgent->new;
my $response = $ua->post($webpage, Content_Type => 'text/xml',
                                        Content => $authenticate);


if ( $response->is_success) {

    my $xml = new XML::Simple;
    my $x = $response->decoded_content;

    # read XML file
    my $data = $xml->XMLin($x);

    my $sessionid =  $data->{'sessionid'};

...
Run Code Online (Sandbox Code Playgroud)

我需要使用该sessionid变量并将其插入另一个如下所示的xml文件中:

<xml>
  <API>4.0</API>
  <action>plant_room_add</action>
  <enforce_rules_training>0</enforce_rules_training>
  <id>3</id>
  <location>123456</location>
  <name>Test1</name>
  <sessionid>$sessionid</sessionid>
  <signature>Hello World</signature>
  <terminal_id>xxxxxxx</terminal_id>
  <training>1</training>
</xml>
Run Code Online (Sandbox Code Playgroud)

我知道我可以将plant_root_addXML放在相同的脚本中,但是我认为该脚本会随着时间的增长而增长,因此我可能需要一个脚本来删除工厂空间。这是用于监视,它将每60秒执行一次。

这是怎么做的?

zdi*_*dim 5

不要使用 XML::Simple。这两个XML ::的libxmlXML ::嫩枝要好得多,至少可以这样说。

由于未显示第一个XML,因此我无法显示如何从中提取数据,但是这里是如何使用来编辑其他XML文件的方法XML::LibXML。我建议也用此模块重写第一个操作。

通过XPath表达式查找节点,并替换元素的text-node子节点:remove和add。

use warnings;
use strict;    
use XML::LibXML;

# ... your code that establishes the $session_id variable ...
my $session_id = 'SAMPLE_ID';
my $filename = 'another.xml';

my $doc = XML::LibXML->load_xml(location => $filename);

my ($node) = $doc->findnodes('//sessionid');
$node->removeChildNodes();
$node->appendText($session_id);    

# print $doc->toString;
$doc->toFile('edited_' . $filename);  # or just $filename to overwrite
Run Code Online (Sandbox Code Playgroud)

XML :: LibXML最为相关的文档用于TextElementNode类。另请参阅解析器文档的页面。这是XPath 规范教程(w3schools)


一些评论。

无需直接加载文件,我们可以先创建解析器对象

my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($filename);
Run Code Online (Sandbox Code Playgroud)

有了解析器,我们可以在构造函数之外(在解析之前为stilll)使用配置方法,这提供了更大的灵活性。

根据您的目的,还有其他更改数据的方法。例如

$node->firstChild->setData($session_id);
Run Code Online (Sandbox Code Playgroud)

更具体。它使用firstChild来自XML :: LibXML :: Node

如果节点具有子节点,则此函数将返回子列表中的第一个节点。

setDataXML :: LibXML :: Text

此功能设置或替换文本内容到节点。节点的类型必须为“文本”,“ cdata”或“注释”。

这适用于那个孩子,“ 孩子列表中的第一个节点 ”。

如果元素有子元素,我们也可以通过获取文本节点findnodes('//sessionid/text()')setData直接使用(在那个子元素上)。您可能想要按照答案中的方法进行操作。