下面是一个基本的XML文档示例
<book_reviewers>
<results>
<reviewer>
<name>Anne</name>
<profession>Catfish wrangler</profession>
</reviewer>
<reviewer>
<name>Bob</name>
<profession>Beer taster</profession>
</reviewer>
<reviewer>
<name>Charlie</name>
<profession>Gardener</profession>
</reviewer>
</results>
</book_reviewers>
我想加上这个:
<reviewer>
<name>Joan</name>
<profession>Jett</profession>
</reviewer>
我已经尝试了许多解决方案的组合,这里有一个,至少,不会抛出错误,但是,它也不起作用。
#!/usr/bin/perl
use XML::LibXML;
use strict;
my $filename = "cr.xml";
my $parser = XML::LibXML->new();
my $critic_details = $parser->parse_file("$filename") or die;
my $new_reviewer = $critic_details->documentElement;
my $reviewer_name = $critic_details->documentElement;
my $reviewer_prof = $critic_details->documentElement;
my $newnode = $critic_details->documentElement;
for my $reviewers($critic_details->findnodes("book_reviewers/results/reviewers")){
$new_reviewer = $reviewers->createElement("reviewer");
$reviewer_name = $new_reviewer->addChild("name");
$reviewer_name->appendText("Joan");
$reviewer_prof = $new_reviewer->addChild("profession");
$reviewer_prof->appendText("Jett");
$newnode = $reviewers->addSibling($new_reviewer); #also tried addChild
}
print $critic_details->toString;
我得到的输出是:
<?xml version="1.0"?>
<book_reviewers>
<results>
<reviewer>
<name>Anne</name>
<profession>Catfish wrangler</profession>
</reviewer>
<reviewer>
<name>Bob</name>
<profession>Beer taster</profession>
</reviewer>
<reviewer>
<name>Charlie</name>
<profession>Gardener</profession>
</reviewer>
</results>
</book_reviewers>
就是原始数据
非常感谢任何帮助-我对Perl和XML都很陌生欢呼声
有很多方法可以做到这一点
这种方式分别创建节点并将其放在一起。它还没有为生产做好准备,因为它假设有一个
节。#!/usr/bin/perl
use XML::LibXML;
use strict;
my $filename = "cr.xml";
my $parser = XML::LibXML->new();
my $critic_details = $parser->parse_file("$filename") or die;
my $reviewer = $critic_details->findnodes("book_reviewers/results")->[0];
my $node = XML::LibXML::Element->new("reviewer");
my $p = XML::LibXML::Element->new("profession");
my $pn = XML::LibXML::Text->new("Jett");
$p->addChild($pn);
my $n = XML::LibXML::Element->new("name");
my $nn = XML::LibXML::Text->new("Joan");
$n->addChild($nn);
$node->addChild($p);
$node->addChild($n);
$reviewer->addChild($node);
print $critic_details->toString;
给出
<?xml version="1.0"?>
<book_reviewers>
<results>
<reviewer>
<name>Anne</name>
<profession>Catfish wrangler</profession>
</reviewer>
<reviewer>
<name>Bob</name>
<profession>Beer taster</profession>
</reviewer>
<reviewer>
<name>Charlie</name>
<profession>Gardener</profession>
</reviewer>
<reviewer><profession>Jett</profession><name>Joan</name></reviewer></results>
</book_reviewers>
只是为了帮助您了解XML::LibXML
的一些更整洁的东西,并让您更容易地理解XML是如何工作的,我在这里发布了另一个答案。也许你也能从中找到一些有用的线索:
use strict;
use warnings;
use utf8;
use XML::LibXML;
my $filename = "cr.xml";
my $parser = XML::LibXML->new();
my $critic_details = $parser->parse_file("$filename") or die;
# find ALL the <book_reviewers><results> nodes
my @results = $critic_details->findnodes("book_reviewers/results");
die "no result node in xml-file" unless @results;
my ($name, $profession) = ("Joan", "Jett");
#
# Here gets the work done, put this in a loop for more entries
#
# add a new <reviewer> node to the LAST <results>
my $reviewer_node_child;
my $reviewer_node = $results[-1]->addNewChild(undef, "reviewer");
# create a child node
$reviewer_node_child = $reviewer_node->addNewChild(undef, "name");
$reviewer_node_child->appendTextNode($name);
# create a child node
$reviewer_node_child = $reviewer_node->addNewChild(undef, "profession");
$reviewer_node_child->appendTextNode($profession);
#
# Done the heavy power lifting
#
use XML::LibXML::PrettyPrint;
my $pretty = XML::LibXML::PrettyPrint->new(
indent_string => ' ' x4,
element => {
compact => [qw| name profession | ],
}
);
$pretty->pretty_print($critic_details);
print $critic_details->toString;
__END__
这里需要addNewChild
方法中的undef
。它们用于设置xml名称空间,这里不需要,但在大型xml文档中确实是这样做的。
另外,我添加XML::LibXML::PrettyPrint
只是为了向您展示如何回到漂亮的语法。请原谅我在脚本末尾添加了use…
。
产生如下结果:
<?xml version="1.0"?>
<book_reviewers>
<results>
<reviewer>
<name>Anne</name>
<profession>Catfish wrangler</profession>
</reviewer>
<reviewer>
<name>Bob</name>
<profession>Beer taster</profession>
</reviewer>
<reviewer>
<name>Charlie</name>
<profession>Gardener</profession>
</reviewer>
<reviewer>
<name>Joan</name>
<profession>Jett</profession>
</reviewer>
</results>
</book_reviewers>
享受XML和Perl,一个非常强大但令人畏惧的工具组合!
可以使用XML::LibXML
将节点从一个XML文档导入到另一个XML文档。这很有用,因为您不必使用对象显式地构建新数据,而只需使用标准的XML表示法即可。
下面的代码演示了这一点。通过在新文档中设置根节点,然后遍历找到的节点,而不是只选择第一个,可以很容易地扩展到重要的多个新审阅者。
#!/usr/bin/perl
use strict;
use warnings;
use XML::LibXML;
my $dom = XML::LibXML->load_xml(IO => *DATA);
my $newnode = XML::LibXML->load_xml(string => <<'END_STRING')->findnodes('//*')->[0];
<reviewer>
<name>Joan</name>
<profession>Jett</profession>
</reviewer>
END_STRING
$dom->findnodes("book_reviewers/results")->[0]->addChild($newnode);
print $dom->toString;
__DATA__
<book_reviewers>
<results>
<reviewer>
<name>Anne</name>
<profession>Catfish wrangler</profession>
</reviewer>
<reviewer>
<name>Bob</name>
<profession>Beer taster</profession>
</reviewer>
<reviewer>
<name>Charlie</name>
<profession>Gardener</profession>
</reviewer>
</results>
</book_reviewers>
输出:
<?xml version="1.0"?>
<book_reviewers>
<results>
<reviewer>
<name>Anne</name>
<profession>Catfish wrangler</profession>
</reviewer>
<reviewer>
<name>Bob</name>
<profession>Beer taster</profession>
</reviewer>
<reviewer>
<name>Charlie</name>
<profession>Gardener</profession>
</reviewer>
<reviewer>
<name>Joan</name>
<profession>Jett</profession>
</reviewer></results>
</book_reviewers>