Извлечение из повторяющихся многоуровневых тегов, содержащих повторяющиеся теги, с использованием Perl - PullRequest
0 голосов
/ 19 января 2012

У меня есть 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>

Я хочу извлечь все под тегом History и получить список разных годов, месяцев, дней, часов и минут? Мне удалось проанализировать простой XML-файл с использованием XML :: Simple и получить выходные данные, но я не могу извлечь информацию из повторяющихся многоуровневых тегов, содержащих повторяющиеся теги. Пожалуйста, помогите мне разобраться.

Спасибо, Gouri

Ответы [ 3 ]

1 голос
/ 20 января 2012

Вы можете использовать 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

note : вам нужно1 корневой тег в документе, поэтому просто оберните его <xml></xml>, например

0 голосов
/ 20 января 2012

Это можно сделать хорошо

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
0 голосов
/ 20 января 2012

Следующий код работает, если у вас есть один тег :

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>

Чтобы добавить больше тегов, вам придется поместить все в другой контейнер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...