取消引用XML :: Simple哈希

时间:2014-07-25 21:19:39

标签: xml perl

我有一个看起来像这样的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>

当我将文件放入翻斗车时 - 它看起来像这样:

#!/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";
#}

这是转储:

/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'
                     }
                   ]
        };

然而,当我尝试打印作者时 - 这就是我得到的。

foreach $book (@{$booklist->{book}} ) {
     print $book->{author}  ;
     print "\n";
}

ARRAY(0x249a140)
ARRAY(0x249a098)
ARRAY(0x2499fc0)

我如何打印出作者?

2 个答案:

答案 0 :(得分:5)

在该数据结构中,作者指向数组引用。因此,您需要迭代数组或在打印前取消引用它:

foreach $book (@{$booklist->{book}} ) {
     print "@{$book->{author}}\n";
}

但是,我建议您使用比XML::Simple更好的XML解析模块。这是模块本身的建议:

  

本模块的状态

     

不鼓励在新代码中使用此模块。其他模块可用,提供更直接和一致的接口。特别强烈建议使用XML::LibXML

     

此模块的主要问题是大量选项以及这些选项交互的任意方式 - 通常会产生意外结果。

     

欢迎使用包含错误修复和文档修补程序的修补程序,但不太可能添加新功能。

目前,如果您只有一位作者的记录,它将引用标量而不是数组。这可以通过XML::Simple中的选项进行调整,但说实话,它不值得付出努力。

相反,我建议使用更好的模块,例如XML::LibXMLXML::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>

输出:

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

答案 1 :(得分:1)

由于作者键是数组引用,您还需要取消引用它们:

foreach my $book ( @{ $booklist->{ book } } ) {
    foreach my $author ( @{ $book->{ author } } ) {
        print "$author\n";
    }
}