【问题标题】:XML::Twig xpath barXML::Twig xpath 栏
【发布时间】:2011-11-19 22:30:49
【问题描述】:

我正在使用 XML::Twig 来处理这个 XML:

<?xml version="1.0" encoding="UTF-8"?>
<termEntry>
    <langSet lang="en">
        <ntig>
            <termGrp>
                <term>trail</term>
                <termNote type="partOfSpeech">noun</termNote>
            </termGrp>
            <descrip type="context">Like in a forest</descrip>
        </ntig>
    </langSet>
</termEntry>

我正在使用以下代码来处理它:

use strict;
use XML::Twig;

my $twig_handlers = {
    termEntry => sub { for my $node($_[1]->findnodes('.//descrip|.//termNote')){print $node->text;}},
};

my $twig= new XML::Twig(
                                TwigRoots           => { termEntry => 1},
                                TwigHandlers        => $twig_handlers,
);

$twig->parsefile('C:\Users\me\file.xml');

代码失败:

error in xpath expression .//descrip|.//termNote around descrip|.//termNote at 
C:\Users\nate\Desktop\test.pl line 6

我一直在尝试不同的东西,每次我使用“|” xpath 中的字符会破坏程序。它在http://www.xpathtester.com 工作得很好(我想我用'//'替换'.')。有关如何解决此问题的任何想法?

【问题讨论】:

    标签: perl xpath xml-twig


    【解决方案1】:

    有不止一种方法可以做到这一点™:

    use strict;
    use warnings;
    use XML::Twig;
    
    sub process {
      my ( $twig, $elt ) = @_;
      print $_->text, "\n" for ( $elt->findnodes( './/descrip' ),
                                 $elt->findnodes( './/termNote' ) );
    }
    
    my $xml = XML::Twig->new( twig_roots => { termEntry => \&process } );
    
    $xml->parse( <<XML );
    <?xml version="1.0" encoding="UTF-8"?>
    <termEntry>
        <langSet lang="en">
            <ntig>
                <termGrp>
                    <term>trail</term>
                    <termNote type="partOfSpeech">noun</termNote>
                </termGrp>
                <descrip type="context">Like in a forest</descrip>
            </ntig>
        </langSet>
    </termEntry>
    XML
    

    输出

    Like a forest
    noun
    

    【讨论】:

    • 呵呵,不知道为什么我没想到。如果没有人知道 XPath,我会使用它。
    • @NateGlenn 您应该使用它,因为您使用的 XPath 是正确的。该模块根本不支持它。还 +1 表示“有不止一种方法可以做到这一点:) - 我今天不能再投票了。必须等待 48 分钟:)
    【解决方案2】:

    来自documentation

    “XPath 表达式仅限于使用子轴和后代轴(确实不能指定轴),谓词不能嵌套。可以使用字符串,或者 string() 函数(twig_roots 触发器除外)”

    您的 XPath 是正确的。您可能想尝试:XML::Twig::Xpath 然后您将获得完整的 Xpath 功能 :)

    【讨论】:

    • 这是非常有用的信息,谢谢。抱歉,但是当我阅读您的答案时,我意识到我输入了错误的问题。我使用'./'而不是'//'来选择节点。在验证器站点的测试要求我使用“//”。
    • @NateGlenn 你意识到 '/' 和 '//' 很不一样,对吧?
    • @NateGlenn : './' 行不通,我认为 './/' 是你的意思
    猜你喜欢
    • 2018-04-28
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    相关资源
    最近更新 更多