【问题标题】:Extract a variable and add it to a separate XML file提取变量并将其添加到单独的 XML 文件中
【发布时间】:2017-04-24 04:23:46
【问题描述】:

我有一个登录并返回会话 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'};

...

我需要把那个 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>

我知道我可以将plant_root_add XML 放在同一个脚本中,但我认为这个脚本会随着时间的推移而增长,所以我可能需要一个脚本来删除机房。这是为了监控,每 60 秒执行一次。

这样做的方法是什么?

【问题讨论】:

    标签: xml perl


    【解决方案1】:

    Do not useXML::SimpleXML::LibXMLXML::Twig 都好得多,至少可以这么说。

    我无法展示如何从第一个 XML 中提取数据,因为它没有显示,但这里是如何使用 XML::LibXML 编辑其他 XML 文件。我建议也用这个模块重写第一个操作。

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

    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 上与此最相关的文档适用于 TextElementNode 类。另请参阅 ParserDocument 页面。这是XPathspecificationtutorial (w3schools)


    几厘米。

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

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

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

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

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

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

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

    setData 来自XML::LibXML::Text

    此函数将文本内容设置或替换到节点。节点必须是“text”、“cdata”或“comment”类型。

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

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

    【讨论】:

      猜你喜欢
      • 2023-01-03
      • 2011-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-13
      • 2016-03-18
      相关资源
      最近更新 更多