2012-02-06 2 views
2

как получить внутренние значения содержания тегов одного и того же тега, который позиционировал внутри одного тега без символа новой строкиНахождение п числа же внутреннего содержания тега внутри одного тега

<BOOK-REF ID="Kyle-ch001-bib036"><AUTHOR-REF><SURNAME>Neinstein</SURNAME>, <GIVEN-NAME>L. S.</GIVEN-NAME></AUTHOR-REF>, <AUTHOR-REF><SURNAME>Gordon</SURNAME>, <GIVEN-NAME>C. G.</GIVEN-NAME></AUTHOR-REF>, <AUTHOR-REF><SURNAME>Katzman</SURNAME>, <GIVEN-NAME>D.</GIVEN-NAME></AUTHOR-REF>, <AUTHOR-REF><SURNAME>Rosen</SURNAME>, <GIVEN-NAME>D.</GIVEN-NAME></AUTHOR-REF>, &#x0026; <AUTHOR-REF><SURNAME>Woods</SURNAME>, <GIVEN-NAME>E.</GIVEN-NAME></AUTHOR-REF> (<YEAR-REF>2007</YEAR-REF>). <BOOK-TITLE-REF>Adolescent health care: A practical guide</BOOK-TITLE-REF> (<EDITION-REF>5th ed.</EDITION-REF>). <PLACE-OF-PUBLICATION-REF>Philadelphia</PLACE-OF-PUBLICATION-REF>: <PUBLISHER-REF>Lippincott Williams and Wilkins</PUBLISHER-REF>.</BOOK-REF> 

Я просто хочу, чтобы получить содержимое (только название) внутри thenametag и которые представлены внутри книги реф тег, фамилия тег может представлять п раз и я хочу, чтобы содержание в массиве

my (@arr2); 
while ($str =~ /<BOOK-REF ID="([^"]*)">(?:[^\)]*)<SURNAME>(.*?)<\/SURNAME>.*?<YEAR-REF>(\d+\w+)<\/YEAR-REF>.*?<\/BOOK-REF>/sgi){ 
    my $id = $1; 
    my $sname = $2; 
    my $year = $3; 
    push (@arr2,[$id,$sname,$year]); 
} 

заранее спасибо

ответ

1

Использование XML::XSH2:

#!/usr/bin/perl 

use warnings; 
use strict; 

use Data::Dumper; 

use XML::XSH2; 
xsh << ' end xsh;'; 
    open 1.xml ; 
    for //SURNAME { 
     $y = string(../../YEAR-REF) ; 
     $s = string(.) ; 
     $i = string(ancestor::BOOK-REF/@ID) ; 
     perl { push @arr, [$i, $s, $y] } } 
    end xsh; 
print Dumper \@XML::XSH2::Map::arr; 
2

с XML :: Twig. Я добавил обертку books вокруг книги ref, если у вас более одного файла. Код работает без него.

#!/usr/bin/perl 

use strict; 
use warnings; 

use YAML; 
use XML::Twig; 

my @by_name; 
XML::Twig->new(twig_handlers => { 'BOOK-REF' => sub { book_ref(@_, \@by_name); } }) 
     -> parse(\*DATA); 

print Dump \@by_name; 

sub book_ref 
    { my($t, $bookref, $by_name)= @_; 
    foreach my $surname ($bookref->descendants('SURNAME')) 
     { push @$by_name, { name => $surname->text, id => $bookref->att('ID'), year => $bookref->field('YEAR-REF') }; } 
    $t->purge; # if the file can be too big to fit in memory 
    } 



__DATA__ 
<books> 
<BOOK-REF ID="Kyle-ch001-bib036"><AUTHOR-REF><SURNAME>Neinstein</SURNAME>, <GIVEN-NAME>L. S.</GIVEN-NAME></AUTHOR-REF>, <AUTHOR-REF><SURNAME>Gordon</SURNAME>, <GIVEN-NAME>C. G.</GIVEN-NAME></AUTHOR-REF>, <AUTHOR-REF><SURNAME>Katzman</SURNAME>, <GIVEN-NAME>D.</GIVEN-NAME></AUTHOR-REF>, <AUTHOR-REF><SURNAME>Rosen</SURNAME>, <GIVEN-NAME>D.</GIVEN-NAME></AUTHOR-REF>, &#x0026; <AUTHOR-REF><SURNAME>Woods</SURNAME>, <GIVEN-NAME>E.</GIVEN-NAME></AUTHOR-REF> (<YEAR-REF>2007</YEAR-REF>). <BOOK-TITLE-REF>Adolescent health care: A practical guide</BOOK-TITLE-REF> (<EDITION-REF>5th ed.</EDITION-REF>). <PLACE-OF-PUBLICATION-REF>Philadelphia</PLACE-OF-PUBLICATION-REF>: <PUBLISHER-REF>Lippincott Williams and Wilkins</PUBLISHER-REF>.</BOOK-REF> 
</books> 
0

Использование XPath запросов для извлечения значений вы заинтересованы в этих трех XPath запросы должны возвращать значения, которые вы ищете:.

//BOOK-REF/@ID 
//BOOK-REF/AUTHOR-REF/SURNAME 
//BOOK-REF/YEAR-REF 

Чтобы сделать XPath запросы, использовать что-то вроде XML::LibXML. Полный пример:

#!/usr/bin/perl 
use strict; 
use warnings; 
use XML::LibXML; 

my $xml = XML::LibXML->load_xml(string => q{<?xml version="1.0" encoding="utf-8"?> 
<BOOK-REF ID="Kyle-ch001-bib036"><AUTHOR-REF><SURNAME>Neinstein</SURNAME>, <GIVEN-NAME>L. S.</GIVEN-NAME></AUTHOR-REF>, <AUTHOR-REF><SURNAME>Gordon</SURNAME>, <GIVEN-NAME>C. G.</GIVEN-NAME></AUTHOR-REF>, <AUTHOR-REF><SURNAME>Katzman</SURNAME>, <GIVEN-NAME>D.</GIVEN-NAME></AUTHOR-REF>, <AUTHOR-REF><SURNAME>Rosen</SURNAME>, <GIVEN-NAME>D.</GIVEN-NAME></AUTHOR-REF>, &#x0026; <AUTHOR-REF><SURNAME>Woods</SURNAME>, <GIVEN-NAME>E.</GIVEN-NAME></AUTHOR-REF> (<YEAR-REF>2007</YEAR-REF>). <BOOK-TITLE-REF>Adolescent health care: A practical guide</BOOK-TITLE-REF> (<EDITION-REF>5th ed.</EDITION-REF>). <PLACE-OF-PUBLICATION-REF>Philadelphia</PLACE-OF-PUBLICATION-REF>: <PUBLISHER-REF>Lippincott Williams and Wilkins</PUBLISHER-REF>.</BOOK-REF> 
}); 

my $xc = XML::LibXML::XPathContext->new($xml); 

my $id = $xc->find('//BOOK-REF/@ID'); 
my @snames = map $_->textContent => $xc->findnodes('//BOOK-REF/AUTHOR-REF/SURNAME'); 
my $year = $xc->find('//BOOK-REF/YEAR-REF'); 

print "$id\n"; 
print join(', ' => @snames), "\n"; 
print "$year\n"; 

# prints: 
# Kyle-ch001-bib036 
# Neinstein, Gordon, Katzman, Rosen, Woods 
# 2007 

Вы можете сохранить результаты славно в массиве, как это:

push @some_array, +{ 
    id  => $id, 
    snames => \@snames, 
    year => $year 
}; 

Если вы хотите, чтобы следовать вашей исходной схемы и дублировать идентификатор и год для каждого SNAME, то это:

push @arr2, map [ $id, $_, $year ] => @snames; 

Другой потенциально полезный способ хранить их бы в хэш шпонкой над полем идентификатора, так

$some_hash{$id} = +{ 
    id  => $id, 
    snames => \@snames, 
    year => $year 
}; 
Смежные вопросы