尝试使用XML :: Simple解析perl中的XML文件。但我没有得到预期的结果

时间:2016-04-05 07:01:15

标签: xml perl xml-parsing

XML文件:

kill

Perl代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE companies>
<companies>
<company>
<ticker>IBN</ticker>
<title>ICICI Bank Ltd</title>
<address>ICICI Bank Ltd.ICICI Bank TowersBandra-kurla Complex,  Mumbai</address>
<phonenum> 91 22 2653 6157</phonenum>
<faxnum> 91 22 2653 1175</faxnum>
<full_time> </full_time>
<website>http://www.icicibank.com</website>
<sector>Financial</sector>
<industry>Foreign Regional Banks</industry>
<news>Headlines Financial Blogs Company Events Message Board</news>
<sno>0</sno>
<fin_ticker>IBN</fin_ticker>
<marketcap>24.52B</marketcap>
<e_value>24.52B</e_value>
<ret_on_assets>0.74%</ret_on_assets>
<gross_profit>8.94B</gross_profit>
<prof_margin>10.79%</prof_margin>
<last_trade>44.05</last_trade>
<trade_time>Apr 8</trade_time>
<prev_close>44.52</prev_close>
<serialno>0</serialno>
<mgt_ticker>IBN</mgt_ticker>
</company>
<company> ... </company>
<company> ... </company>
<company> ... </company>
<company> ... </company>
</companies>

预期产出:ICICI Bank Ltd

2 个答案:

答案 0 :(得分:1)

XML ::简单

本模块的状态

不鼓励在新代码中使用此模块。

特别强调XML::LibXMLXML::Twig是一个很好的选择。

http://search.cpan.org/~grantm/XML-Simple-2.22/lib/XML/Simple.pm

无论如何,XML::Simple尝试的问题是:

$data->{company}{title}

$data->{company}返回数组引用:

use strict;
use warnings; 
use 5.020;
use XML::Simple;
use Data::Dumper;

my $xmlfile = 'xml.xml';
my $href = XMLin($xmlfile);
say Dumper($href);

--output:--
$VAR1 = {
          'company' => [   #<== That means array reference!
                       {
                         'industry' => 'Foreign Regional Banks',
                         'phonenum' => ' 91 22 2653 6157',
                         'trade_time' => 'Apr 8',
                         'ret_on_assets' => '0.74%',
                         'faxnum' => ' 91 22 2653 1175',
                         'website' => 'http://www.icicibank.com',
                         'serialno' => '0',
                         'mgt_ticker' => 'IBN',
                         'title' => 'ICICI Bank Ltd',

                 ...
                 ...

并且您无法像{...}一样访问数组:

     array
       |
+--------------+                 
|              |
$data->{company}{title}

相反,您必须使用[...]访问数组。数组的第一个元素是散列引用,因此散列位于数组中的索引0处:

       hash
        |
+-----------------+                
|                 |
$data->{company}[0]

现在,您可以对该哈希使用哈希访问{...}来获取title

       hash
        |
+-----------------+                
|                 |
$data->{company}[0]{title}


use strict;
use warnings; 
use 5.020;
use XML::Simple;
use Data::Dumper;

my $xmlfile = 'xml.xml';
my $href = XMLin($xmlfile);
say "$href->{company}[0]{title}";

--output:--
ICICI Bank Ltd

这是XML::LibXML

1)Using DOM methods

use strict;
use warnings; 
use 5.020;
use XML::LibXML;
use Data::Dumper;

my $xmlfile = "xml.xml";
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($xmlfile);
#say $doc;  #outputs the xml

my $root = $doc->getDocumentElement; #=> <companies> tag
my @company_tags = $root->getElementsByTagName('company');
my @title_tags = $company_tags[0]->getElementsByTagName('title');
say $title_tags[0]->textContent();

--output:--
ICICI Bank Ltd

2)Using XPaths

use strict;
use warnings; 
use 5.020;
use XML::LibXML;
use Data::Dumper;

my $xmlfile = "xml.xml";
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($xmlfile);
#say $doc;  #outputs the xml

my $root = $doc->getDocumentElement; #=> <companies> tag
my @titles = $root->findnodes("//company/title");
say $titles[0]->findnodes("./text()");

--output:--
ICICI Bank Ltd

方法:

  1. findnodes()
  2. 找到()
  3. findvalue()
  4. 可以在XML::LibXML文档here中找到。

答案 1 :(得分:1)

don't use XML::Simple。它的谎言 - 它根本不简单。

我喜欢XML::Twig作为替代方案:

use XML::Twig; 
print $_ -> text,"\n" for XML::Twig -> parsefile ('sample1.xml') -> get_xpath('//company/title');

会做的伎俩。

为了清楚起见,将其扩展:

#!/usr/bin/env perl
use strict;
use warnings;

use XML::Twig; 

my $twig = XML::Twig -> parsefile ( 'sample1.xml' );

foreach my $company ( $twig -> get_xpath('//company') ) {
    print $company -> first_child('title') -> text,"\n";
}

XML::TwigXML::LibXML的一个主要优势是它们支持xpath - 这有点像XML的正则表达式。

但这意味着您可以通过指定:

来选择公司名称
//company/title
/companies/company/title

//是“在文档中的任何位置”的外卡。你也可以在这个元素下面的任何地方.//进行操作,例如:

print $company -> get_xpath('.//title',0)->text,"\n"

等。