【问题标题】:Parse XML data and append a new element using XML::Simple使用 XML::Simple 解析 XML 数据并附加一个新元素
【发布时间】:2015-10-16 12:17:17
【问题描述】:

我正在使用XML::SimpleXML::Dumper。我很清楚围绕前一个模块的问题。如果我可以使用其他库,我会的。

我想要实现的是加载 XML,然后将行附加到它。这是我在脚本运行之前的 XML 结构。

<person>
  <appearance>
     <param name="height" value="6,3"/>
  </appearence>
</person>

脚本,或者我打算编写的代码,应该从文件中加载这个 XML,然后将 &lt;param&gt; 元素附加到 &lt;appearence&gt; 上。我已经尝试使用此代码:

use warnings;

use XML::Simple;
use XML::Dumper;

my $xml = XMLin('xml_import.xml');

$xml->{appearence} .= qq{<param name="age" value="22" />};
my $new_xml = XMLout($xml, noattr => 1, NoEscape => 1);

open(FILE, ">xml_import.xml");
print FILE $new_xml;
close FILE;

不幸的是输出是这样的:

<opt>
  <appearence>HASH(0x1722190)<param name="age" value="22" /></appearence>
</opt>

我不仅将原来的&lt;person&gt; 标签丢失为&lt;opt&gt;,而且HASH 字符串替换了我假设的现有&lt;param&gt; 元素。我已经阅读了XML::Simple 的文档,但我不知道应该使用什么参数来防止这种情况发生。

【问题讨论】:

  • 我想不出为什么您无法使用更好的 XML 模块,除非有人挟持您的家人。你想解释一下这个问题吗?
  • 不是特别的。在此问题中无法使用替代库的原因有很多。从什么时候开始,stackoverflow 成为了审讯网站?
  • 注意:虽然 XML::Simple 在解析 XML 方面非常糟糕,但在编写 XML 方面却非常糟糕。它将生成与您读入的 XML 不同的 XML。避免使用这个已弃用的模块。

标签: xml perl xml-simple


【解决方案1】:

使用XML::Simple 的目的是在代码中使用 Perl 数据结构,而不是 XML。

您的问题正是不鼓励使用该模块的原因。您必须使用ForceArray 才能轻松更改父元素中的元素数量,并且您必须清除KeyAttr 以阻止对name 属性的特殊处理。

#!/usr/bin/perl
use warnings;
use strict;

use XML::Simple;

my $xml = << '__XML__';
<person>
  <appearance>
     <param name="height" value="6,3"/>
  </appearance>
</person>
__XML__

my $simple = XMLin($xml, ForceArray => 1,
                         KeepRoot   => 1,
                         KeyAttr    => [],
                  );

push @{ $simple->{person}[0]{appearance}[0]{param} }, { name  => 'age',
                                                        value => 22,
                                                      };
print XMLout($simple, KeepRoot => 1);

为了比较,XML::XSH2 中的相同任务,对XML::LibXML 的包装:

open file.xml ;
my $p := insert element param append /person/appearance ;
set $p/@name 'age' ;
set $p/@value 22 ;
save :b ;

【讨论】:

  • 这确实是 XML::Simple 中最糟糕的一点——我们看到的大多数请求都非常简单,并带有其他解析器提供的各种选项。
【解决方案2】:

1.您丢失标签的原因是“XMLin() 通常会丢弃根元素名称。将 'KeepRoot' 选项设置为 '1' 将导致保留根元素名称。”

2.从文件中读取xml后,应将变量作为perl数据结构进行操作。

#! /usr/bin/perl

use strict;
use XML::Simple qw(:strict);
use Data::Dumper;

my $xml = XMLin('xml_import.xml', KeepRoot => 1, KeyAttr => ["param"], ForceArray => ["param"]);
print '-----$xml-----', "\n", Dumper($xml), "\n";

my $new_node = {'name' => 'age', 'value' => '22'};
push $xml->{person}->{appearance}->{param}, $new_node;
print '-----Insert a new node to $xml-----', "\n", Dumper($xml), "\n";

my $new_xml = XMLout($xml, NoAttr => 1, NoEscape => 1, KeepRoot => 1, KeyAttr => []);
print '-----$new_xml-----', "\n", $new_xml, "\n";

或者

#! /usr/bin/perl

use strict;
use XML::Simple qw(:strict);
use Data::Dumper;

my $xml = XMLin('xml_import.xml', KeepRoot => 1, KeyAttr => {param => "+name"}, ForceArray => ["param"]);
print '-----$xml-----', "\n", Dumper($xml), "\n";

my $new_node = {'name' => 'age', 'value' => '22'};
$xml->{person}->{appearance}->{param}->{age} = $new_node;
print '-----Insert a new node to $xml-----', "\n", Dumper($xml), "\n";

my $new_xml = XMLout($xml, NoAttr => 1, NoEscape => 1, KeepRoot => 1, KeyAttr => {param => "+name"});
print '-----$new_xml-----', "\n", $new_xml, "\n";

【讨论】:

    猜你喜欢
    • 2015-10-09
    • 2012-02-11
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    • 2022-10-24
    • 2011-10-05
    • 2021-04-30
    • 1970-01-01
    相关资源
    最近更新 更多