我有一个非常庞大的
XML文件,我想列出文档元素的所有子节点.
我正在使用下面的代码工作正常,但它需要很长时间来处理文件,它也从文档元素获取数据,这是不需要的:
我正在使用下面的代码工作正常,但它需要很长时间来处理文件,它也从文档元素获取数据,这是不需要的:
use XML::Simple; my $xml = XML::Simple->new(); my $d = $xml->XMLin("sample.xml"); my @arr = keys %$d; print "@arr\n";
示例XML:
<?xml version="1.0" encoding="ISO-8859-15"?> <document version="1.0" createdAt="2017-03-31T11:41:34"> <TITLE>Computer Parts</TITLE> <PART001> <ITEM>motherboard</ITEM> <MANUFACTURER>ASUS</MANUFACTURER> <MODEL>P3B-F</MODEL> <COST> 123.00</COST> </PART001> <PART002> <ITEM>Video Card</ITEM> <MANUFACTURER>ATI</MANUFACTURER> <MODEL>All-in-Wonder Pro</MODEL> <COST> 160.00</COST> </PART002> <PART003> <ITEM>Sound Card</ITEM> <MANUFACTURER>Creative Labs</MANUFACTURER> <MODEL>Sound Blaster Live</MODEL> <COST> 80.00</COST> </PART003> <PART004> <ITEM>14 inch Monitor</ITEM> <MANUFACTURER>LG Electronics</MANUFACTURER> <MODEL> 995E</MODEL> <COST> 290.00</COST> </PART004> </document>
预期产出:
标题,
PART001,
PART002,
PART003,
PART004
通过使用
XML::LibXML和XPath.
use 5.014; use warnings; use XML::LibXML; my $file = 'xml'; my $dom = XML::LibXML->load_xml(location => $file); for my $child ($dom->findnodes( q{//document/*} )) { say $child->nodeName(); }
产量
TITLE PART001 PART002 PART003 PART004
或者只是为了这个案例,如果你只需要PARTs
for my $part ($dom->findnodes( q{//*[contains(name(),'PART')]} )) { say $part->nodeName(); }
产量
PART001 PART002 PART003 PART004
编辑:使用拉解析器(不会将整个xml加载到内存中):
use 5.014; use warnings; use XML::LibXML::Reader qw(XML_READER_TYPE_ELEMENT); my $file="xml"; my $reader = XML::LibXML::Reader->new(location => $file) or die "problem $!"; while($reader->read()) { if( $reader->depth == 1 && $reader->nodeType == XML_READER_TYPE_ELEMENT ) { say $reader->name; } } TITLE PART001 PART002 PART003 PART004
EDIT2
use 5.014; use warnings; use XML::LibXML::Reader qw(XML_READER_TYPE_ELEMENT); my $file="xml"; my $reader = XML::LibXML::Reader->new(location => $file) or die "problem $!"; my $indoc; while($reader->read()) { # sets the flag in youre inside the <document> if( $reader->name eq 'document' ) { $indoc = $reader->nodeType == XML_READER_TYPE_ELEMENT ? 1 : 0; } # all nodes with level 1 if they're inside of the <document> if( $indoc && $reader->depth == 1 && $reader->nodeType == XML_READER_TYPE_ELEMENT ) { say $reader->name; } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。