我有一个看起来像这样的XML文件
<booklist>
<book type="technical">
<author>Book 1 author 1</author>
<author>Book 1 author 2</author>
<title>Book 1 title</title>
<isbn>Book1ISBN</isbn>
</book>
<book type="fiction">
<author>Book 2 author 1</author>
<author>Book 2 author 2</author>
<title>Book 2 title</title>
<isbn>Book2ISBN</isbn>
</book>
<book type="technical">
<author>Book 3 author 1</author>
<author>Book 3 author 2</author>
<author>Book 3 author 3</author>
<title>Book 3 title</title>
<isbn>Book3ISBN</isbn>
</book>
</booklist>
Run Code Online (Sandbox Code Playgroud)
当我把文件放入翻斗机时 - 它看起来像这样:
#!/usr/bin/perl
use strict ;
use warnings ;
use XML::Simple ;
use Data::Dumper ;
my $book = ();
my $booklist = XMLin('book.xml_with_attrib');
print Dumper($booklist);
#foreach $book (@{$booklist->{author}} ) {
# print $book->{title} ;
# print "\n";
#}
Run Code Online (Sandbox Code Playgroud)
这是转储:
/tmp/walt $ /tmp/walt/bookparse_by_attrib.pl
$VAR1 = {
'book' => [
{
'isbn' => 'Book1ISBN',
'title' => 'Book 1 title',
'author' => [
'Book 1 author 1',
'Book 1 author 2'
],
'type' => 'technical'
},
{
'isbn' => 'Book2ISBN',
'title' => 'Book 2 title',
'author' => [
'Book 2 author 1',
'Book 2 author 2'
],
'type' => 'fiction'
},
{
'isbn' => 'Book3ISBN',
'title' => 'Book 3 title',
'author' => [
'Book 3 author 1',
'Book 3 author 2',
'Book 3 author 3'
],
'type' => 'technical'
}
]
};
Run Code Online (Sandbox Code Playgroud)
然而,当我尝试打印作者时 - 这就是我得到的.
foreach $book (@{$booklist->{book}} ) {
print $book->{author} ;
print "\n";
}
ARRAY(0x249a140)
ARRAY(0x249a098)
ARRAY(0x2499fc0)
Run Code Online (Sandbox Code Playgroud)
我该如何打印出作者?
在该数据结构中,作者指向数组引用.因此,您需要迭代数组或在打印前取消引用它:
foreach $book (@{$booklist->{book}} ) {
print "@{$book->{author}}\n";
}
Run Code Online (Sandbox Code Playgroud)
但是,我建议您使用比XML更好的XML解析模块XML::Simple.这是模块本身的建议:
这个模块的状态
不鼓励在新代码中使用此模块.其他模块可用,提供更直接和一致的接口.特别
XML::LibXML强烈推荐.该模块的主要问题是大量选项以及这些选项交互的任意方式 - 通常会产生意外结果.
修补程序包含错误修复和文档修复程序,但不太可能添加新功能.
目前,如果您只有一个作者的记录,它将引用标量而不是数组.这可以通过选项进行调整XML::Simple,但老实说,这不值得付出努力.
相反,我建议使用更好的模块,如XML::LibXML或XML::Twig,以避免解析中的不一致:
use strict;
use warnings;
use XML::LibXML;
my $data = do {local $/; <DATA>};
my $xml = XML::LibXML->load_xml(string => $data);
for my $book ($xml->findnodes('//book')) {
my $title = $book->findvalue('title');
print "Title = '$title'\n";
for my $author ($book->findnodes('author')) {
print " " . $author->textContent() . "\n";
}
}
__DATA__
<booklist>
<book type="technical">
<author>Book 1 author 1</author>
<title>Book 1 title</title>
<isbn>Book1ISBN</isbn>
</book>
<book type="fiction">
<author>Book 2 author 1</author>
<author>Book 2 author 2</author>
<title>Book 2 title</title>
<isbn>Book2ISBN</isbn>
</book>
<book type="technical">
<author>Book 3 author 1</author>
<author>Book 3 author 2</author>
<author>Book 3 author 3</author>
<title>Book 3 title</title>
<isbn>Book3ISBN</isbn>
</book>
</booklist>
Run Code Online (Sandbox Code Playgroud)
输出:
Title = 'Book 1 title'
Book 1 author 1
Title = 'Book 2 title'
Book 2 author 1
Book 2 author 2
Title = 'Book 3 title'
Book 3 author 1
Book 3 author 2
Book 3 author 3
Run Code Online (Sandbox Code Playgroud)