2012-05-01 36 views
8

Tôi nghĩ rằng đây là một vấn đề rất đơn giản, nhưng tôi không thể tìm ra nó mặc dù nhiều tìm kiếm.Kịch bản Perl để phân tích cú pháp XML bằng cách sử dụng XML :: LibXML;

Tôi đang cố gắng phân tích cú pháp XML sau để in một cái gì đó tương tự như TAG = VALUE, để tôi có thể viết nó vào một tệp CSV. Vấn đề là các thẻ không phải lúc nào cũng giống nhau cho mỗi mẫu. Tôi không thể tìm ra cách để có được tên thẻ thực tế. Bất kỳ trợ giúp đánh giá cao !!!

XML File -

<Statistics> 
    <Stats> 
    <Sample> 
     <Name>System1</Name> 
     <Type>IBM</Type> 
     <Memory>2GB</Memory> 
     <StartTime>2012-04-26T14:30:01Z</StartTime> 
     <EndTime>2012-04-26T14:45:01Z</EndTime> 
    </Sample> 

    <Sample> 
     <Name>System2</Name> 
     <Type>Intel</Type> 
     <Disks>2</Disks> 
     <StartTime>2012-04-26T15:30:01Z</StartTime> 
     <EndTime>2012-04-26T15:45:01Z</EndTime> 
     <Video>1</Video> 
    </Sample> 
    </Stats> 
</Statistics> 

Script -

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

$filename = "data.xml"; 

my $parser = XML::LibXML->new(); 
my $xmldoc = $parser->parse_file($filename); 

for my $sample ($xmldoc->findnodes('/Statistics/Stats/Sample')) { 

print $sample->nodeName(), ": ", $sample->textContent(), "\n"; 

} 

Trả lời

16

Bạn đã phương pháp phù hợp cho việc tên thẻ, bạn chỉ cần một vòng lặp thêm để chạy qua các thẻ bên trong mỗi <sample>:

#!/usr/bin/perl 

use strict; 
use warnings; 

use XML::LibXML; 

my $filename = "data.xml"; 

my $parser = XML::LibXML->new(); 
my $xmldoc = $parser->parse_file($filename); 

for my $sample ($xmldoc->findnodes('/Statistics/Stats/Sample')) { 
    for my $property ($sample->findnodes('./*')) { 
     print $property->nodeName(), ": ", $property->textContent(), "\n"; 
    } 
    print "\n"; 
} 

Chỉnh sửa: Tôi hiện có đã tạo trang web hướng dẫn có tên là Perl XML::LibXML by Example, câu trả lời chính xác cho loại câu hỏi này.

5

Bạn cần phải lặp qua các con của nút mẫu,

for my $sample ($xmldoc->findnodes('/Statistics/Stats/Sample')) { 
    print $sample->nodeName(), "\n"; 
    foreach my $child ($sample->getChildnodes) { 
     if ($child->nodeType() == XML_ELEMENT_NODE) { 
      print "\t", $child->nodeName(), ":", $child->textContent(), "\n"; 
     } 
    } 
} 

sẽ hiển thị,

Sample 
     Name:System1 
     Type:IBM 
     Memory:2GB 
     StartTime:2012-04-26T14:30:01Z 
     EndTime:2012-04-26T14:45:01Z 
Sample 
     Name:System2 
     Type:Intel 
     Disks:2 
     StartTime:2012-04-26T15:30:01Z 
     EndTime:2012-04-26T15:45:01Z 
     Video:1 
+2

Dòng 3 + 4 + 6 có thể được thay thế bằng: 'foreach $ con tôi ($ mẫu -> findnodes ('*')) {' – ikegami

+0

Cảm ơn, tuyệt vời !! – lozwell

Các vấn đề liên quan