The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


Tree::DAG_Node::XPath - Add XPath support to Tree::DAG_Node


  use Tree::DAG_Node::XPath;

  # create a tree
  my $root = Tree::DAG_Node::XPath->new()->name( "root_node");
  $root->new_daughter->name("daugther$_") foreach (1..5);

  # now use XPath to find nodes
  my $roots= $root->find( '/root_node');
  foreach (@$roots) { print "found root: ", $_->name, "\n"; }

  my $daughters= $root->find( '/root_node/daugther2 | /root_node/daugther4');
  foreach (@$daughters) { print "found daughter: ", $_->name, "\n"; }


This package extends Tree::DAG_Node to add XPath queries to it

It adds the findnodes, matches and find methods to the base Tree::DAG_Node class.

With a little customization it can also add the findnodes_as_string and findvalue methods.


Methods you are likely to use

findnodes($path, [$context])

Returns a list of nodes found by $path, optionally in context $context. In scalar context returns an Tree::XPathEngine::NodeSet object.

findvalue($path, [$context])

Returns either a Tree::XPathEngine::Literal, a Tree::XPathEngine::Boolean or a Tree::XPathEngine::Number object. If the path returns a NodeSet, $nodeset->xpath_to_literal is called automatically for you (and thus a Tree::XPathEngine::Literal is returned). Note that for each of the objects stringification is overloaded, so you can just print the value found, or manipulate it in the ways you would a normal perl value (e.g. using regular expressions).

find($path, [$context])

The find function takes an XPath expression (a string) and returns either an Tree::XPathEngine::NodeSet object containing the nodes it found (or empty if no nodes matched the path), or one of Tree::XPathEngine::Literal (a string), Tree::XPathEngine::Number, or Tree::XPathEngine::Boolean. It should always return something - and you can use isa() to find out what it returned. If you need to check how many nodes it found you should check $nodeset->size. See Tree::XPathEngine::NodeSet.

matches($node, $path, [$context])

Returns true if the node matches the path (optionally in context $context).

Methods provided by the module for Tree::XPathEngine

You probably don't need to use those.


returns an array of attributes of the node (an arrayref in scalar context)



returns an array of children of the node (an arrayref in scalar context)


returns the parent node


returns the root node of the tree


returns 1


returns 0


returns 0


compares 2 nodes and returns their order in the tree


alias for name


alias for right_sister


alias for left_sister


XPath is an XML standard, which is designed to work on a DOM ( tree. So the closer the tree you are working on mimics a DOM tree, the more of XPath you will be able to use.

In order for a generic tree to work better with XPath here are the main features that can be addressed:

Changing the XPath engine

In XPath, tokens in the query (node names and attribute names) must follow the rules for XML tokens (see the definition at

The definition of the tokens can be changed, within reasons: in order not to confuse the interpreter XPath delimiters cannot be used in tokens. '/', '[', '|', '!'.

Test carefully your expressions, so they don't confuse the XPath engine. For example qr/\w+/ is _not_ recommended, as numbers are then matched by the expression, making the XPath engine consider them as names.


None known at this time


better docs, especially on customizing derived classes to use more of XPath power

more tests (current coverage according to Devel::Cover: 96.2%)

if needed performance improvements (using address to sort the node sets is convenient but probably real slow, grabing the code to sort nodesfrom XML::Twig::XPath would likely be faster in most cases)


Tree::DAG_Node the base package that Tree::DAG_Node::XPath extends

Tree::XPathEngine the XPath engine for Tree::DAG_Node::XPath the XPath recommendations

examples are in the examples directory


Michel Rodriguez, <>


Copyright (C) 2004 by Michel Rodriguez

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.4 or, at your option, any later version of Perl 5 you may have available.