Search code examples
perlxpathxml-twig

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?


Solution

  • 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