我该如何使用Perl创建XML?

29
我需要在Perl中创建XML。根据我的了解,XML::LibXML非常适合解析和使用来自其他地方的XML。请问有没有关于XML Writer的建议?XML::Writer仍在维护吗?有人喜欢/使用它吗?
除了功能完整性之外,我还对易于使用的语法感兴趣,请在您的答案中描述语法以及其他任何您喜欢该模块的原因。
请每个回答只提供一个建议,如果已经有人回答了您喜欢的内容,请投票支持该答案。希望最受欢迎的答案能够很容易地被看到。
谢谢!
6个回答

37

仅供参考,这是一个使用XML::LibXML的代码片段。

#!/usr/bin/env perl

#
# Create a simple XML document
#

use strict;
use warnings;
use XML::LibXML;

my $doc = XML::LibXML::Document->new('1.0', 'utf-8');

my $root = $doc->createElement('my-root-element');
$root->setAttribute('some-attr'=> 'some-value');

my %elements = (
    color => 'blue',
    metal => 'steel',
);

for my $name (keys %elements) {
    my $tag = $doc->createElement($name);
    my $value = $elements{$name};
    $tag->appendTextNode($value);
    $root->appendChild($tag);
}

$doc->setDocumentElement($root);
print $doc->toString();

并且这个输出结果为:

<?xml version="1.0" encoding="utf-8"?>
<my-root-element some-attr="some-value">
    <color>blue</color>
    <metal>steel</metal>
</my-root-element>

22

XML::Writer仍在维护中(至少截至今年2月),它确实是最受欢迎的Perl XML编写器之一。

至于描述语法,最好查看模块文档(链接已包含在问题中)。如下:

use XML::Writer;

my $writer = new XML::Writer();  # will write to stdout
$writer->startTag("greeting", 
                  "class" => "simple");
$writer->characters("Hello, world!");
$writer->endTag("greeting");
$writer->end();

# produces <greeting class='simple'>Hello world!</greeting>

谢谢,我确实查看了XML::Writer的文档。我希望有一个更清晰的语法,所以我会等一段时间,看看是否有其他人提出任何建议,但如果这似乎是最受欢迎的选择,那我就会选择它。 - pkaeding
2
语法“可能”有点老了,但XML::Writer在过去8年中一直为我服务得很好。当需要从Perl创建XML时,这是我首选的工具。如果想要更加“性感”的东西,请查看XML::Class(但请注意,它自2005年以来就没有更新过)。 - draegtun
3
关于“更简洁的语法”,上面例子中的“greeting”标签可以这样写:$writer->dataElement("greeting", "Hello, world!", "class"=>"simple")。我认为这已经非常简单了。 - R. Hill
XML::Writer得到了维护 - 这也是我使用的。不幸的是,它仍然可以更好。据我所知,它不执行自封闭标记。另外,在写入标记后无法添加属性(它不是真正的基于对象)。 - vol7ron

9
如果你想把Perl中的数据结构转化为XML,XML::Simple可以很好地完成这项工作。
简单来说:
my $hashref = { foo => 'bar', baz => [ 1, 2, 3 ] };
use XML::Simple;
my $xml = XML::Simple::XMLout($hashref);
正如它的名字所示,它的基本用法很简单;但如果你需要,它也提供了许多功能。
当然,它也可以轻松解析XML。
编辑:我在2008年10月写下了这篇文章,今年已经过去了14年。事情已经发生了变化。XML::Simple自己的文档提出了明确的警告:
强烈不建议在新代码中使用此模块。还有其他可用的模块,它们提供更直接和一致的接口。特别是,强烈推荐使用XML::LibXML,你可以参考其教程介绍。另一个优秀的替代方案是XML::Twig
现在,我强烈建议检查这些替代方案,而不是在新代码中使用XML::Simple。

1
XML::Simple在解析XML方面表现得相当糟糕,但在生成XML方面则更是可怕的。有太多的事情超出了你的控制。即使在你的小例子中,输出结果也不清楚。 (这意味着它可能会因运行而异。)为什么不建议使用XML::Simple? - ikegami

8
我对XML并不是很熟悉,但XML::Smart似乎可以实现你想要的功能。请查看文档中的Creating XML Data部分,它看起来非常简单易用。
文档概述:
use XML::Smart;

## Create a null XML object:
my $XML = XML::Smart->new() ;

## Add a server to the list:
$XML->{server} = {
    os => 'Linux' ,
    type => 'mandrake' ,
    version => 8.9 ,
    address => [ '192.168.3.201', '192.168.3.202' ] ,
} ;

$XML->save('newfile.xml') ;

这将把以下内容放入newfile.xml中:

<server os="Linux" type="mandrake" version="8.9">
  <address>192.168.3.201</address>
  <address>192.168.3.202</address>
</server>

很棒,我要试着使用一下 :)

2
XML::Smart看起来不错,但我记得在很多年前使用XML::Simple时它还没有出现。它有一个好的接口,并且在读写XML方面表现良好。

它在生成XML方面实际上非常糟糕。为什么不建议使用XML::Simple? - ikegami

1

我喜欢XML::TreeBuilder,因为它符合我的思维方式。历史上,我更多地使用它来解析而不是发射。

在发布这个问题几周后,我有机会从Perl生成一些XML。我调查了这里列出的其他模块,假设它们中的一个比XML::TreeBuilder更好地工作,但是对于我想要的东西,TreeBuilder仍然是最佳选择。

其中一个缺点是无法在XML :: TreeBuilder对象中表示处理指令和声明的方法。


我同意你的观点,Brian。在我的情况下,我决定尝试使用XML::LibXML来进行编写,因为我正在修改的代码片段已经在其他任务中使用了XML::LibXML。 - Cosimo
3
布莱恩只是添加了链接的编辑,我才是发表评论的人。 :) - skiphoppy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接