Codex

HTML::Element::traverse

Section: User Contributed Perl Documentation (3pm)

Updated: 2013-10-07

Index?action=index Return to Main Contents


NAME

HTML::Element::traverse - discussion of HTML::Element's traverse method

VERSION

This document describes version 5.03 of HTML::Element::traverse, released September 22, 2012 as part of HTML-Tree.

SYNOPSIS

DESCRIPTION

provides a method that traverses the tree and calls user-specified callbacks for each node, in pre- or post-order. However, use of the method is quite superfluous: if you want to recursively visit every node in the tree, it's almost always simpler to write a subroutine does just that, than it is to bundle up the pre- and/or post-order code in callbacks for the method.

EXAMPLES

Suppose you want to traverse at/under a node and give elements an 'id' attribute unless they already have one.
You can use the method:
or you can just be simple and clear (and not have to understand the calling format for ) by writing a sub that traverses the tree by just calling itself:

See, isn't that nice and clear?

But, if you really need to know:

THE TRAVERSE METHOD

The method is a general object-method for traversing a tree or subtree and calling user-specified callbacks. It accepts the following syntaxes:

:$h->traverse(\&callback)

:or $h->traverse(\&callback, $ignore_text)

:or $h->traverse( [\&pre_callback,\&post_callback] , $ignore_text)

These all mean to traverse the element and all of its children. That is, this method starts at node , ``pre-order visits , traverses its children, and then will ``post-order visit . ``Visiting'' means that the callback routine is called, with these arguments:
If the parameter is given and true, then the pre-order call will not be happen for text content.

The startflag is 1 when we enter a node (i.e., in pre-order calls) and 0 when we leave the node (in post-order calls).

Note, however, that post-order calls don't happen for nodes that are text segments or are elements that are prototypically empty (like ``br, ``hr, etc.).

If we visit text nodes (i.e., unless is given and true), then when text nodes are visited, we will also pass two extra arguments to the callback:

Note that you can specify that the pre-order routine can be a different routine from the post-order one:

You can also specify that no post-order calls are to be made, by providing a false value as the post-order routine:

And similarly for suppressing pre-order callbacks:

Note that these two syntaxes specify the same operation:

The return values from calls to your pre- or post-order routines are significant, and are used to control recursion into the tree.

These are the values you can return, listed in descending order of my estimation of their usefulness:

HTML
:Element::OK, 1, or any other true value:...to keep on traversing.
Note that et al are constants. So if you're running under (as I hope you are), and you say: the compiler will flag this as an error (an unallowable bareword, specifically), whereas if you spell PRUNE correctly, the compiler will not complain.

:

undef, 0, '0', '', or HTML
:Element::PRUNE:...to block traversing under the current element's content. (This is ignored if received from a post-order callback, since by then the recursion has already happened.) If this is returned by a pre-order callback, no post-order callback for the current node will happen. (Recall that if your callback exits with just , it is returning undef --- at least in scalar context, and always calls your callbacks in scalar context.):
HTML
:Element::ABORT:...to abort the whole traversal immediately. This is often useful when you're looking for just the first node in the tree that meets some criterion of yours.:
HTML
:Element::PRUNE_UP:...to abort continued traversal into this node and its parent node. No post-order callback for the current or parent node will happen.:
HTML
:Element::PRUNE_SOFTLY:Like PRUNE, except that the post-order call for the current node is not blocked.:

Almost every task to do with extracting information from a tree can be expressed in terms of traverse operations (usually in only one pass, and usually paying attention to only pre-order, or to only post-order), or operations based on traversing. (In fact, many of the other methods in this class are basically calls to traverse() with particular arguments.)

The source code for HTML::Element and HTML::TreeBuilder contain several examples of the use of the ``traverse'' method to gather information about the content of trees and subtrees.

(Note: you should not change the structure of a tree while you are traversing it.)

[End of documentation for the method]

Traversing with Recursive Anonymous Routines

Now, if you've been reading Structure and Interpretation of Computer Programs too much, maybe you even want a recursive lambda. Go ahead:

It's a bit nutty, and it's still more concise than a call to the method!
It is left as an exercise to the reader to figure out how to do the same thing without using a symbol at all.
It is also left as an exercise to the reader to figure out why I undefine , above; and why I could achieved the same effect with any of:

But not:

Doing Recursive Things Iteratively

Note that you may at times see an iterative implementation of pre-order traversal, like so:

This can under certain circumstances be more efficient than just a normal recursive routine, but at the cost of being rather obscure. It gains efficiency by avoiding the overhead of function-calling, but since there are several method dispatches however you do it (to and ), the overhead for a simple function call is insignificant.

Pruning and Whatnot

The method does have the fairly neat features of the , and signals. None of these can be implemented totally straightforwardly with recursive routines, but it is quite possible. -like behavior can be implemented either with using non-local returning with / :

or you can just do it with flags:

SEE ALSO

HTML::Element

AUTHOR

Current maintainers:

Christopher J. Madsen :
Jeff Fearn :

Original HTML-Tree author:

Gisle Aas:

Former maintainers:

Sean M. Burke:
Andy Lester:
Pete Krawczyk :

You can follow or contribute to HTML-Tree's development at <http://github.com/madsen/HTML-Tree>.

COPYRIGHT

Copyright 2000,2001 Sean M. Burke


Index

NAME

VERSION

SYNOPSIS

DESCRIPTION

EXAMPLES

THE TRAVERSE METHOD

Traversing with Recursive Anonymous Routines

Doing Recursive Things Iteratively

Pruning and Whatnot

SEE ALSO

AUTHOR

COPYRIGHT