我有一个可以登录并返回会话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秒执行一次。
这是怎么做的?
不要使用 XML::Simple。这两个XML ::的libxml和XML ::嫩枝要好得多,至少可以这样说。
由于未显示第一个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最为相关的文档用于Text,Element和Node类。另请参阅解析器和文档的页面。这是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
如果节点具有子节点,则此函数将返回子列表中的第一个节点。
并setData从XML :: LibXML :: Text
此功能设置或替换文本内容到节点。节点的类型必须为“文本”,“ cdata”或“注释”。
这适用于那个孩子,“ 孩子列表中的第一个节点 ”。
如果元素有子元素,我们也可以通过获取文本节点findnodes('//sessionid/text()')并setData直接使用(在那个子元素上)。您可能想要按照答案中的方法进行操作。