perl:如何按顺序解析xml文件
我有一个XML文件,它描述了我可以在UDP通道上交换的数据结构。 例如: 这是我的输入XML文件,描述了我的数据结构perl:如何按顺序解析xml文件,perl,xml-parsing,Perl,Xml Parsing,我有一个XML文件,它描述了我可以在UDP通道上交换的数据结构。 例如: 这是我的输入XML文件,描述了我的数据结构 <ds> <uint32 name='a'/> <uint32 name='b'/> <string name='c'/> <int16 name='d'/> <uint32 name='e'/> </ds> 如您所见,在解析之后,我无法确定字段“e”相对于数据结构开头的相对位置 &l
<ds>
<uint32 name='a'/>
<uint32 name='b'/>
<string name='c'/>
<int16 name='d'/>
<uint32 name='e'/>
</ds>
如您所见,在解析之后,我无法确定字段“e”相对于数据结构开头的相对位置
<ds>
<uint32 name='a'/>
<uint32 name='b'/>
<string name='c'/>
<int16 name='d'/>
<uint32 name='e'/>
</ds>
我想找出这些元素的偏移量
我尝试搜索PerlXML解析器,它允许我按顺序解析XML文件,类似于“getnexttag()”之类的功能,但找不到任何
以编程方式执行此操作的最佳方法是什么?如果不是perl,那么哪种语言最适合做这项工作?您需要使用具有适当回调的流式解析器,这也将提高解析速度(如果正确完成,并减少内存消耗),这是一件非常好的事情 我建议您使用
XML::SAX
,以下链接提供了对该模块的介绍:
start\u元素
提供回调,这样您可以一次读取每个元素的值
你能给我举个简单的例子吗? 是的,我已经有了<强>;-)强> 下面的代码片段将解析OP提供的数据,并打印每个元素的名称以及属性key/value 这应该很容易理解,但如果你有任何问题,请随意添加它们作为评论,我会更新这篇文章更详细的信息
use warnings;
use strict;
use XML::SAX;
my $parser = XML::SAX::ParserFactory->parser(
Handler => ExampleHandler->new
);
$parser->parse_string (<<EOT
<ds>
<uint32 name='a'/>
<uint32 name='b'/>
<string name='c'/>
<int16 name='d'/>
<uint32 name='e'/>
</ds>
EOT
);
# # # # # # # # # # # # # # # # # # # # # # # #
package ExampleHandler;
use base ('XML::SAX::Base');
sub start_element {
my ($self, $el) = @_;
print "found element: ", $el->{Name}, "\n";
for my $attr (values %{$el->{Attributes}}) {
print " '", $attr->{Name}, "' = '", $attr->{Value}, "'\n";
}
print "\n";
}
我对XML::SAX不满意,还有其他可用的模块吗? 是的,有很多选择。阅读以下列表,并选择适合您的特定问题的列表:
不同的解析方法有什么区别? 我还建议阅读以下有关XML解析的常见问题解答。它将介绍使用树解析器(如XML::parser::Simple)或流式解析器的利弊:
- 使用Perl肯定是可行的
下面是一个例子:
使用严格;
使用警告;
使用特征“说”;
使用XML::LibXML;
my$xml=xml::LibXML->load_xml(位置=>'test.xml');
my($dsNode)=$xml->findnodes('/ds');
my@kids=$dsNode->nonBlankChildNodes;#此数组的索引将
#给出偏移量
我的$first_kid=shift@kids;#干掉第一个孩子
说$first_kid->toString;#""
我的$second=$first_kid->nextNonBlankSibling();
my$third=$second->nextNonBlankSibling();
说$third->toString;#""
下面是一个使用
这将产生:
tag uint32 : name = a
tag uint32 : name = b
tag string : name = c
tag int16 : name = d
tag uint32 : name = e
非常感谢你给出如此清晰的答案。这很有帮助。
use strict;
use warnings;
use feature 'say';
use XML::LibXML;
my $xml = XML::LibXML->load_xml( location => 'test.xml' );
my ( $dsNode ) = $xml->findnodes( '/ds' );
my @kids = $dsNode->nonBlankChildNodes; # The indices of this array will
# give the offset
my $first_kid = shift @kids; # Pull off the first kid
say $first_kid->toString; # "<uint32 name='a'/>"
my $second = $first_kid->nextNonBlankSibling();
my $third = $second->nextNonBlankSibling();
say $third->toString; # "<string name="c"/>"
use XML::Twig;
XML::Twig->new( twig_handlers => { 'ds/*' => \&each_child } )
->parse( $your_xml_data );
sub each_child {
my ($twig, $child) = @_;
printf "tag %s : name = %s\n", $child->name, $child->{att}->{name};
}
tag uint32 : name = a
tag uint32 : name = b
tag string : name = c
tag int16 : name = d
tag uint32 : name = e