Perl,如何解析 XML 文件,xpath

Posted

技术标签:

【中文标题】Perl,如何解析 XML 文件,xpath【英文标题】:Perl, how to parse XML file, xpath 【发布时间】:2012-03-27 22:06:57 【问题描述】:

我想使用 Perl 解析 XML 文件。我可以使用 XML::Simple 模块,但现在我想开始使用 XML::XPath 模块,因为它使用 XPath 表达式。根据我有限的知识,我认为 XPaths 将使未来的解析更容易,对吧? 这是我到目前为止的 Perl 代码:

use strict;
use warnings;
use XML::XPath;

my $file = "data.xml";
my $path = XML::XPath->new(filename => $file);

my $name = $path->find('/category/event/@name');
print $name."\n";

我的问题是如何分隔每个名称属性(类别/事件/@名称),以便我可以对我解析的每个值执行测试。目前我只是得到一个充满解析数据的大字符串,而我想要几个可以测试的小字符串。我怎样才能做到这一点?谢谢:-)

【问题讨论】:

【参考方案1】:

find 方法返回一个XML::XPath::NodeSet 对象,它是找到的所有节点的集合。我无法想象你能做些什么来看到一个包含所有属性值的长字符串。

检索到节点集后,您可以使用 sizeget_nodeget_nodelist 等方法处理其内容(请参阅上面链接的文档)。 get_nodelist 将返回一个 Perl 列表,在这种情况下,XML::XPath::Node::Attribute 对象也有自己的方法。这个程序应该让你开始

use strict;
use warnings;

use XML::XPath;

my $xp = XML::XPath->new(ioref => \*DATA);

my $names = $xp->find('/category/event/@name');

for my $node ($names->get_nodelist) 
  say $node->getNodeValue;



__DATA__
  <category name="a">
    <event name="cat1" />  
    <event name="cat2" />  
    <event name="cat3" />  
    <event name="cat4" />  
    <event name="cat5" />  
  </category>

输出

cat1
cat2
cat3
cat4
cat5

【讨论】:

感谢您的回复。在阅读了 daxim 发布的链接后,我决定改用 XML::LibXML。它似乎是最好的,所以作为一个初学者,我认为学习一个文档更好的模块对我来说会更好。我很欣赏你写的介绍信息,它帮助我更好地理解了一些事情:-) 使用XML::XPath,我们可以在路径中使用^*吗? EX : my $names = $xp-&gt;find('/category/eve*');.Inside category,搜索以eve开头的标签【参考方案2】:

This review指出XML::XPath自2003年以来一直没有更新,并推荐XML::LibXML代替

use 5.010;
use strict;
use warnings;
use XML::LibXML;

my $dom = XML::LibXML->new->parse_file('data.xml');
for my $node ($dom->findnodes('/category/event/@name')) 
    say $node->toString;

请参阅 XML::LibXML::ParserXML::LibXML::Node

【讨论】:

您推荐XML::LibXML 是因为您更了解它,还是因为您认为它比XML::XPath 具有真正的优势?据我所知,后者工作正常。它也是纯 Perl,这使得它比 LibXML 慢,但无需外部库的帮助即可使用。 这是一个超链接。请遵循它。 @daxim 感谢您的回复。我试过它有效,但不是 100% 我想要的方式。我的输出是 name="attribute_value",但我只想要 attribute_value。有没有办法只输出不带 name="" 的属性值? 经过更多研究后,我发现将行 ´$node->toString´ 更改为 ´$node->to_literal´ 只会输出没有 name="" 的属性值。这就是我想要的。如果这是一种不好的做事方式,请告诉我,否则我的问题得到了回答。再次感谢您的帮助:-) 不,调用记录在案的方法to_literal 并不是一件坏事。 - 请mark the answer as accepted.

以上是关于Perl,如何解析 XML 文件,xpath的主要内容,如果未能解决你的问题,请参考以下文章

如何使用DOM4j+xpath 解析

Java DocumentBuilderFactory(javax.xml)通过XPath解析xml文件

如何使用 XML::XPath 获取属性?

如何使用Xpath检索XML文件中的命名空间

Dom4J配合XPath解析schema约束的xml配置文件问题

在python中解析xml以查找所有元素(节点)的xpath