使用Perl从包含重复标记的重复多级标记中提取

时间:2012-01-19 19:24:04

标签: xml perl

我有一个XML文件(已编辑)。

    <xml>
        <PubmedData>
            <History>
                <PubMedPubDate PubStatus="entrez">
                    <Year>2010</Year>
                    <Month>6</Month>
                    <Day>18</Day>
                    <Hour>6</Hour>
                    <Minute>0</Minute>
                </PubMedPubDate>
                <PubMedPubDate PubStatus="pubmed">
                    <Year>2010</Year>
                    <Month>7</Month>
                    <Day>19</Day>
                    <Hour>6</Hour>
                    <Minute>10</Minute>
                </PubMedPubDate>
                <PubMedPubDate PubStatus="medline">
                    <Year>2010</Year>
                    <Month>8</Month>
                    <Day>20</Day>
                    <Hour>7</Hour>
                    <Minute>0</Minute>
                </PubMedPubDate>
            <PublicationStatus>aheadofprint</PublicationStatus>
            <Initials>JJ</Initials>
            <NlmUniqueID>8434563</NlmUniqueID>
            </History>  
            <History>
                <PubMedPubDate PubStatus="entrez">
                    <Year>2011</Year>
                    <Month>4</Month>
                    <Day>18</Day>
                    <Hour>10</Hour>
                    <Minute>20</Minute>
                </PubMedPubDate>
                <PubMedPubDate PubStatus="pubmed">
                    <Year>2011</Year>
                    <Month>7</Month>
                    <Day>24</Day>
                    <Hour>8</Hour>
                    <Minute>10</Minute>
                </PubMedPubDate>
                <PubMedPubDate PubStatus="medline">
                    <Year>2011</Year>
                    <Month>3</Month>
                    <Day>4</Day>
                    <Hour>5</Hour>
                    <Minute>37</Minute>
                </PubMedPubDate>
            <PublicationStatus>aheadofprint</PublicationStatus>
            <Initials>BP</Initials>
            <NlmUniqueID>9814863</NlmUniqueID>
            </History>
        </PubmedData>
    </xml>

我想提取历史记录标记下的所有内容,并获取不同年份,月份,日期,小时和分钟的列表?我能够使用XML :: Simple解析一个简单的XML文件并获取输出,但我无法从包含重复标记的重复多级标记中提取信息。请帮我搞清楚。

谢谢, Gouri

3 个答案:

答案 0 :(得分:1)

您可以使用XML :: TreeBuilder,如下所示:

use XML::TreeBuilder;                                                                                                                                                                                              

my $root= XML::TreeBuilder->new();                                                                                                                                         
$root->parse($xml);                                                                                                                                                                                                

my @history=$root->look_down(_tag=>'PubMedPubDate');                                                                                                                                                               
foreach my $h (@history) {                                                                                                                                                                                         
    printf "%s: %d-%d-%d %d:%d\n", $h->attr('PubStatus'),                                                                                                                                                          
        $h->look_down(_tag => Year)->as_text,                                                                                                                                                                      
        $h->look_down(_tag => Month)->as_text,                                                                                                                                                                     
        $h->look_down(_tag => Day)->as_text,                                                                                                                                                                       
        $h->look_down(_tag => Hour)->as_text,                                                                                                                                                                      
        $h->look_down(_tag => Minute)->as_text;                                                                                                                                                                    
}

您将获得以下输出:

entrez: 2010-6-18 6:0
pubmed: 2010-7-19 6:10
medline: 2010-8-20 7:0
entrez: 2011-4-18 10:20
pubmed: 2011-7-24 8:10
medline: 2011-3-4 5:37

注意:您需要在文档中添加1个根标记,因此只需将其与<xml></xml>一起包装,例如

答案 1 :(得分:0)

当您有一个&lt; PubmedData&gt;时,以下代码可以正常工作标记:

use strict;

use XML::Simple();
use Data::Dumper;

my $xml = '';
while (<DATA>) {
    $xml .= $_;
}

my $x = XML::Simple->new;
my $doc = $x->XMLin($xml);

for my $date (@{$doc->{History}->{PubMedPubDate}}) {
    print sprintf("%d-%02d-%02d", $date->{Year}, $date->{Month}, $date->{Day}), "\n";
}

__DATA__
<PubmedData>
...
</PubmedData>

对于更多标签,您必须将所有内容都包含在另一个容器中。

答案 2 :(得分:0)

可以做得很好

use XML::Simple;
use Data::Dumper;
use IO::File;

my $File = IO::File->new('File.xml');
my $XML = XML::Simple->new;
my $ref = $XML->XMLin($File);

$i = $j = 0;

for (;;){

    if($ref->{PubmedData}->[$j]->{History}->{PubMedPubDate}->[$i] =~ /^HASH/){
        print "-" x 70 . "\n";
        print "Year   : " . $ref->{PubmedData}->[$j]->{History}->{PubMedPubDate}->[$i]->{Year}   . "\n";
        print "Month  : " . $ref->{PubmedData}->[$j]->{History}->{PubMedPubDate}->[$i]->{Month}  . "\n";
        print "Day    : " . $ref->{PubmedData}->[$j]->{History}->{PubMedPubDate}->[$i]->{Day}    . "\n";
        $i++;
    }else{
        $j++;
        $i = 0;
        unless($ref->{PubmedData}->[$j]->{History}->{PubMedPubDate}->[$i] =~ /^HASH/){
            last;
        }

    }

}

out:

----------------------------------------------------------------------
Year   : 2010
Month  : 6
Day    : 18
----------------------------------------------------------------------
Year   : 2010
Month  : 7
Day    : 19
----------------------------------------------------------------------
Year   : 2010
Month  : 8
Day    : 20
----------------------------------------------------------------------
Year   : 2011
Month  : 4
Day    : 18
----------------------------------------------------------------------
Year   : 2011
Month  : 7
Day    : 24
----------------------------------------------------------------------
Year   : 2011
Month  : 3
Day    : 4