提取变量并将其添加到单独的XML文件中 [英] Extract a variable and add it to a separate XML file

查看:126
本文介绍了提取变量并将其添加到单独的XML文件中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a script that logs in and returns a session ID. I need the session ID so that I can populate an XML file to do stuff with it, for example create a plant room for a nursery.

#!/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'};

...

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

I need to take that sessionid variable and insert into another xml file that looks like this:

<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>

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

I know that I can put the plant_root_add XML in the same script, but I think this script is growing to grow over time so I might need a script to delete the plant room. This is for monitoring and it will be executed every 60 seconds.

这是怎么做的?

推荐答案

XML :: LibXML

Do not use XML::Simple. Both XML::LibXML and XML::Twig are far better, to say the least.

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

I can't show how to pull data from the first XML since it's not shown, but here is how to edit that other XML file using XML::LibXML. I suggest to rewrite the first operation with this module as well.

通过 XPath 表达式查找节点并替换元素的文本节点子节点:删除并添加.

Find the node via an XPath expression and replace element's text-node children: remove and 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

与此最相关的 XML :: LibXML 上的文档是用于文本解析器文档.这是XPath 规范教程(w3schools).

Documentation on XML::LibXML most relevant to this is for Text, Element, and Node classes. See also pages for Parser and Document. Here is XPath specification and a tutorial (w3schools).

一些评论.

我们可以直接创建解析器对象,而不是直接加载文件

Instead of loading the file directly we can create the parser object first

my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($filename);

有了解析器,我们可以使用 ="nofollow noreferrer">其配置在构造函数之外(在解析前为stilll),提供了更大的灵活性.

With the parser on hand we can use methods for its configuration outside of the constructor (while stilll before parsing), what provides more flexibility.

还有其他更改数据的方法,具体取决于您的目的.例如

There are other ways to change data, depending on your purpose. For example

$node->firstChild->setData($session_id);

更具体.它使用 XML ::中的firstChild LibXML :: Node

is more specific. It uses firstChild from XML::LibXML::Node

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

If a node has child nodes this function will return the first node in the child list.

setData来自 XML :: LibXML :: Text

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

This function sets or replaces text content to a node. The node has to be of the type "text", "cdata" or "comment".

这适用于那个孩子,"孩子列表中的第一个节点."

This works for that one child, "the first node in the child list."

如果元素有子元素,我们还可以通过findnodes('//sessionid/text()')获取文本节点,并直接使用setData(在那个子元素上).不过,您可能希望按照答案中的步骤进行操作.

We can also get the text node by findnodes('//sessionid/text()') and use setData (on that one child) directly, if the element has children. You probably want to do as in the answer though.

这篇关于提取变量并将其添加到单独的XML文件中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆