Sau khi gặp các tệp dữ liệu xml chứa các nút văn bản lớn, Tôi đã tìm một số cách để đọc và đánh giá chúng trong dữ liệu của tôi xử lý tập lệnh.Cách thực hành đọc xml với các nút văn bản lớn trong Perl
Các tập tin xml là các tập tin phối hợp 3D cho mô hình phân tử ứng dụng một có cấu trúc này (ví dụ):
<?xml version="1.0" encoding="UTF-8"?>
<hoomd_xml version="1.4">
<configuration>
<position>
-0.101000 0.011000 -40.000000
-0.077000 0.008000 -40.469000
-0.008000 0.001000 -40.934000
-0.301000 0.033000 -41.157000
0.213000 -0.023000 -41.348000
...
... 300,000 to 500,000 lines may follow >>
...
-0.140000 0.015000 -42.556000
</position>
<next_huge_section_of_the_same_pattern>
...
...
...
</next_huge_section_of_the_same_pattern>
</configuration>
</hoomd_xml>
Mỗi file xml chứa một số nút văn bản rất lớn và có kích thước giữa 60MB và 100MB tùy thuộc vào Nội dung.
tôi đã cố gắng approch ngây thơ sử dụng XML::Simple đầu tiên nhưng bộ nạp sẽ mất mãi mãi để bước đầu phân tích các file:
...
my $data = $xml->XMLin('structure_80mb.xml');
...
và chỉ dừng lại ở "lỗi nội bộ: tra cứu đầu vào lớn", do đó phương pháp này isn' t rất thực tế.
Lần thử tiếp theo là sử dụng XML::LibXML để đọc - nhưng tại đây, trình nạp ban đầu sẽ được gửi ngay lập tức với thông báo lỗi "lỗi phân tích cú pháp: xmlSAX2Characters: nút văn bản lớn".
Befor viết về chủ đề này trên stackoverflow, tôi đã viết aq & d phân tích cú pháp cho bản thân mình và gửi các tập tin thông qua nó (sau khi slurping xx MB file xml vào vô hướng $xml
):
...
# read the <position> data from in-memory xml file
my @Coord = xml_parser_hack('position', $xml);
...
mà trả về dữ liệu của mỗi dòng dưới dạng một mảng, hoàn thành trong vài giây và trông giống như sau:
sub xml_parser_hack {
my ($tagname, $xml) = @_;
return() unless $xml =~ /^</;
my @Data =();
my ($p0, $p1) = (undef,undef);
$p0 = $+[0] if $xml =~ /^<$tagname[^>]*>[^\r\n]*[r\n]+/msg; # start tag
$p1 = $-[0] if $xml =~ /^<\/$tagname[^>]*>/msg; # end tag
return() unless defined $p0 && defined $p1;
my @Lines = split /[\r\n]+/, substr $xml, $p0, $p1-$p0;
for my $line (@Lines) {
push @Data, [ split /\s+/, $line ];
}
return @Data;
}
Điều này làm việc tốt cho đến nay nhưng không được coi là 'sẵn sàng sản xuất', tất nhiên.
Hỏi: Làm cách nào để đọc tệp bằng mô-đun Perl? Tôi sẽ chọn mô-đun nào?
Cảm ơn trước
RBO
Phụ Lục: sau khi đọc bình luận của choroba, tôi nhìn sâu hơn vào XML :: LibXML. Việc mở tập tin my $reader = XML::LibXML::Reader->new(location =>'structure_80mb.xml');
hoạt động, trái với những gì tôi nghĩ trước đây. Lỗi xảy ra nếu tôi cố truy cập vào nút văn bản bên dưới thẻ:
...
while ($reader->read) {
# bails out in the loop iteration after accessing the <position> tag,
# if the position's text node is accessed
# -- xmlSAX2Characters: huge text node ---
...
http://search.cpan.org/~mirod/XML-Twig -3.44/Twig.pm - mô-đun perl để xử lý các tài liệu XML lớn trong chế độ cây. –
Bạn đã mở tệp bằng XML :: LibXML như thế nào? Nó làm việc cho tôi cho các tập tin 100MB. – choroba
@choroba - cảm ơn, tôi đã kiểm tra lại - và cập nhật chủ đề. –