我有一个如下所示的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>
我按类型对XML进行排序 - 所以XML :: Simple。 我认为这是一个很好的方法。 按类型整理每本书。
/tmp/walt $ cat bookparse_by_attrib.pl_dump
#!/usr/bin/perl
use strict ;
use warnings ;
use XML::Simple ;
use Data::Dumper ;
my $book = ();
my $booklist = XMLin('book.xml_with_attrib', KeyAttr => {book => 'type'});
#print Dumper($booklist);
print $booklist->{book}->{technical}->{title} . "\n";
/tmp/walt $ ./bookparse_by_attrib.pl_dump
$VAR1 = {
'book' => {
'technical' => {
'author' => [
'Book 3 author 1',
'Book 3 author 2',
'Book 3 author 3'
],
'title' => 'Book 3 title',
'isbn' => 'Book3ISBN'
},
'fiction' => {
'author' => [
'Book 2 author 1',
'Book 2 author 2'
],
'title' => 'Book 2 title',
'isbn' => 'Book2ISBN'
}
}
};
这将打印出来:
print $booklist->{book}->{technical}->{title} . "\n";
/tmp/walt $ ./bookparse_by_attrib.pl_dump
Book 3 title
所以当我知道类型名称时它会起作用 但是这会引发错误:
print $booklist->{book}->{type}->{title} . "\n";
Use of uninitialized value in concatenation (.) or string at ./bookparse_by_attrib.pl_dump line 11.
这不会引发错误 - 但它不会打印出任何内容。
#!/usr/bin/perl
use strict ;
use warnings ;
use XML::Simple ;
use Data::Dumper ;
my $book = ();
my $booklist = ();
foreach my $book (@{$booklist->{book}}) {
print $book->{title} . "\n";
}
我正在尝试打印出类型,只有在我知道类型的情况下才能解决。 最后,我想输入书的类型和标题,但是现在,如果我可以打印出类型,那么tath会很棒。
答案 0 :(得分:2)
我将在my answer中重复我之前提出的问题:dereferencing a XML::Simple hash
请勿使用XML::Simple
。它是一个过时的模块,只会在您尝试破解它以提供所需格式时导致持续出现问题。
相反,使用XML::LibXML
直接提取您想要的信息:
use strict;
use warnings;
use List::MoreUtils qw(uniq);
use XML::LibXML;
my $xml = XML::LibXML->load_xml(IO => \*DATA);
my @types = sort +uniq map {$_->textContent()} $xml->findnodes('//book/@type');
for my $type (@types) {
print "Type = $type\n";
for my $book ($xml->findnodes("//book[\@type='$type']")) {
print " Title = " . $book->findvalue('title') . "\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>
输出:
Type = fiction
Title = Book 2 title
Type = technical
Title = Book 1 title
Title = Book 3 title
答案 1 :(得分:1)
键的结构&#34;书&#34;是一个哈希引用,但是您将其视为数组引用(@{$booklist->{book}}
)。
这种数据结构化方式与您遇到的一般性问题在于它是100%的哈希值。一旦你有两本相同类型的书,你只会得到每种类型的最后一本书。
#!/usr/bin/perl
use warnings;
use strict;
my $booklist = {
'book' => {
'technical' => {
'author' => [
'Book 3 author 1',
'Book 3 author 2',
'Book 3 author 3'
],
'title' => 'Book 3 title',
'isbn' => 'Book3ISBN'
},
'fiction' => {
'author' => [
'Book 2 author 1',
'Book 2 author 2'
],
'title' => 'Book 2 title',
'isbn' => 'Book2ISBN'
}
}
};
for my $book_type ( keys %{ $booklist->{book} } ) {
printf( "Title: %s\n", $booklist->{book}->{$book_type}->{title} );
}