解析 XML 数据并使用 XML::Simple 附加新元素
Parse XML data and append a new element using XML::Simple
我正在使用 XML::Simple
and XML::Dumper
。我很清楚围绕前一个模块的问题。如果我可以使用替代库,我会的。
我想要实现的是加载 XML,然后向其附加行。这是脚本具有 运行.
之前我的 XML 结构
<person>
<appearance>
<param name="height" value="6,3"/>
</appearence>
</person>
脚本,或者我打算编写的代码,应该从文件中加载这个 XML,然后将 <param>
元素附加到 <appearence>
上。我已经尝试使用此代码:
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>
不仅我原来的 <person>
标签丢失为 <opt>
,而且 HASH
字符串替换了我假设的现有 <param>
元素。我已经阅读了 XML::Simple
的文档,但我无法确定应该使用什么参数来防止这种情况发生。
使用 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, a wrapper around XML::LibXML中的相同任务:
open file.xml ;
my $p := insert element param append /person/appearance ;
set $p/@name 'age' ;
set $p/@value 22 ;
save :b ;
1.The 您丢失标签的原因是 "XMLin() normally discards the root element name. Setting the 'KeepRoot' option to '1' will cause the root element name to be retained."
2.After 从文件中读取 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";
我正在使用 XML::Simple
and XML::Dumper
。我很清楚围绕前一个模块的问题。如果我可以使用替代库,我会的。
我想要实现的是加载 XML,然后向其附加行。这是脚本具有 运行.
之前我的 XML 结构<person>
<appearance>
<param name="height" value="6,3"/>
</appearence>
</person>
脚本,或者我打算编写的代码,应该从文件中加载这个 XML,然后将 <param>
元素附加到 <appearence>
上。我已经尝试使用此代码:
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>
不仅我原来的 <person>
标签丢失为 <opt>
,而且 HASH
字符串替换了我假设的现有 <param>
元素。我已经阅读了 XML::Simple
的文档,但我无法确定应该使用什么参数来防止这种情况发生。
使用 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, a wrapper around XML::LibXML中的相同任务:
open file.xml ;
my $p := insert element param append /person/appearance ;
set $p/@name 'age' ;
set $p/@value 22 ;
save :b ;
1.The 您丢失标签的原因是 "XMLin() normally discards the root element name. Setting the 'KeepRoot' option to '1' will cause the root element name to be retained."
2.After 从文件中读取 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";