我有一个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
答案 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