我已经使用了XML :: Simple十多年了,它已经完成了我需要的一切,而且我几乎不再触及Perl了。虽然现在我需要解析一个简单的XML字符串:获取所有作为根的子元素的元素,并为每个元素获取它们的元素类型,属性和内容(我不在乎是否有任何嵌套元素,只是以字符串形式阅读内容是完美的)。我可以用XML实现所有这些:简单除了我还需要保持顺序,当有多种元素类型时,Simple不能这样做。
我刚刚安装了Twig,它看起来非常强大,我希望这是一个快速的脚本。在此之后我不太可能再次使用Twig,这是Twig可以轻松做到的事情吗?
答案 0 :(得分:3)
在一个简单的层面 - XML::Twig
- 遍历孩子:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig -> new -> parsefile ( 'myxml.xml' );
foreach my $element ( $twig -> root -> children ) {
print $element -> text; #element content.
}
提取元素属性可以通过以下方式完成:
$element -> att('attributename');
或者您可以使用atts
获取哈希引用:
my $attributes = $element -> atts();
foreach my $key ( keys %$attributes ) {
print "$key => ", $attributes -> {$key}, "\n";
}
我特别喜欢的是,对于XML,您需要处理很长的相似元素列表,您可以定义一个处理程序 - 它们分别称为处理程序解析器遇到的时间并交给XML的子集。
sub process_book {
my ( $twig, $book ) = @_;
print $book -> first_child ('title');
$twig -> purge; #discard anything we've already seen.
}
my $twig = XML::Twig -> new ( twig_handlers => { 'book' => \&process_book } );
$twig -> parsefile ( 'books.xml' );
示例XML:
<XML>
<BOOK>
<title>Elements of style</title>
<author>Strunk and White</author>
</BOOK>
</XML>
答案 1 :(得分:1)
下面的代码应该为您提供足够的信息以便开始使用。
一些注意事项:
parsefile
代替parse
'level(1)'
代替'/root/*'
process_elt
和{{1成为全局变量,你可以写$atts
,并使用twig和元素作为参数调用处理程序$strings
位用于释放刚处理过的元素所使用的内存,如果文件太大而无法放入内存中,则非常有用,否则您不需要使用它< / LI>
$atts
是$strings
,它只是检查输出,您可以使用任何其他方式执行此操作('/root/*' => \&process_elt
,$t->purge
,打印......)以下是代码:
DDP
答案 2 :(得分:0)
我更喜欢XML::LibXML。它的Reader
不需要将整个结构保存在内存中,因此它可以处理大文件:
#!/usr/bin/perl
use warnings;
use strict;
use XML::LibXML::Reader;
my $reader = 'XML::LibXML::Reader'->new( location => 'file.xml' );
while ($reader->read) {
if (1 == $reader->depth
and XML_READER_TYPE_ELEMENT == $reader->nodeType
) {
my @info = ($reader->name);
my $inner = $reader->readInnerXml;
for my $idx (0 .. $reader->attributeCount - 1) {
$reader->moveToAttributeNo($idx);
push @info, $reader->name . '=' . $reader->value;
}
push @info, $inner;
print "@info\n";
}
}