【问题标题】:Perl, how to parse XML file, xpathPerl,如何解析 XML 文件,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";

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

【问题讨论】:

    标签: perl xpath xml-parsing


    【解决方案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.
    猜你喜欢
    • 2012-01-27
    • 1970-01-01
    • 2017-10-28
    • 2013-07-17
    • 1970-01-01
    • 2011-04-13
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多