2013-07-01 110 views
1

我想使用Perl的XML :: LibXML庫解析下面的XML。LibXML - 遍歷節點直到

<?xml version="1.0" encoding="UTF-8" ?> 
<TaggedPDF-doc> 
<Part> 
    <Sect> 
    <H4>2.1 Study purpose </H4> 
    <P>This is study purpose content</P> 
    <P>content 1</P> 
    <P>content 2</P> 
    <P>content 3 </P> 
    <P>content 4</P> 
    <P>3. Some Header</P> 
    <P>obj content 4</P> 
    <P>obj content 2</P> 
    </Sect> 
</Part> 
</TaggedPDF-doc> 

對於標題研究目的,我試圖顯示所有相關的兄弟姐妹。所以我的預期成果是:

<H4>2.1 Study purpose </H4> 
<P>This is study purpose content</P> 
<P>content 1</P> 
<P>content 2</P> 
<P>content 3 </P> 
<P>content 4</P> 

我的Perl代碼如下。我可以顯示第一個節點。

給定第一個節點的值,研究目的,有沒有一種方法可以循環和打印所有節點,直到我點擊包含「數字後跟一個」的節點。

我的Perl實現:

my $purpose_str = 'Purpose and rationale|Study purpose|Study rationale'; 
$parser = XML::LibXML->new; 
#print "Parser for file $file is: $parser \n";  
$dom = $parser->parse_file($file); 

$root = $dom->getDocumentElement; 
$dom->setDocumentElement($root); 

for my $purpose_search('/TaggedPDF-doc/Part/Sect/H4') 
{ 
    $purpose_nodeset = $dom->find($purpose_search); 
    foreach my $purp_node ($purpose_nodeset -> get_nodelist) 
    { 
     if ($purp_node =~ m/$purpose_str/i) 
     { 
      #Get the corresponding child nodes 
      @childnodes = $purp_node->nonBlankChildNodes(); 

      $first_kid = shift @childnodes; 
      $second_kid = $first_kid->nextNonBlankSibling(); 
      #$third_kid = $second_kid->nextNonBlankSibling(); 

      $first_kid -> string_value; 
      $second_kid -> string_value; 
      #$third_kid -> string_value; 
     } 

     print "Study Purpose is: $first_kid\n.$second_kid\n"; 
    } 
}  
+0

嘗試'使用Data :: Dumper;打印翻車機(@childnodes);'你設置它後,看看你真的得到 – KeepCalmAndCarryOn

回答

1

別看子節點,如果你想兄弟姐妹。如果要匹配節點的文本內容,請使用textContent

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

my $file  = 'input.xml'; 
my $purpose_str = 'Purpose and rationale|Study purpose|Study rationale'; 
my $dom   = XML::LibXML->load_xml(location => $file); 

for my $purpose_search('/TaggedPDF-doc/Part/Sect/H4') 
{ 
    my $purpose_nodeset = $dom->find($purpose_search); 
    for my $purp_node ($purpose_nodeset -> get_nodelist) 
    { 
     if ($purp_node->textContent =~ m/$purpose_str/i) 
     { 
      my @siblings = $purp_node->find('following-sibling::*') 
          ->get_nodelist; 

      for my $i (0 .. $#siblings) 
      { 
       if ($siblings[$i]->textContent =~ /^[0-9]+\./) 
       { 
        splice @siblings, $i; 
        last; 
       } 
      } 

      print $_->textContent, "\n" for @siblings; 
     } 

    } 
}  
+0

非常感謝。這工作。 – BRZ