Nate Glenn
Nate Glenn

Reputation: 6744

XML::Twig xpath bar

I'm using XML::Twig to process this 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>

I'm using the following code to process it:

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');

The code fails with:

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

I've been trying different things, and any time I use the '|' character in the xpath it breaks the program. It works just fine at http://www.xpathtester.com (thought I replace '.' with '//'). Any ideas on how to fix this?

Upvotes: 2

Views: 504

Answers (2)

Zaid
Zaid

Reputation: 37136

There is more than one way to do it™:

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

Output

Like a forest
noun

Upvotes: 7

FailedDev
FailedDev

Reputation: 26920

From the documentation :

"XPath expressions are limited to using the child and descendant axis (indeed you can't specify an axis), and predicates cannot be nested. You can use the string, or string() function (except in twig_roots triggers)"

Your XPath is correct. You might wanna try : XML::Twig::Xpath then you get the full Xpath power :)

Upvotes: 2

Related Questions