<?xml version='1.0' encoding='utf-8'?>
<spc:wrap xmlns="http://xmlns.livinglogic.de/xist/ns/doc" xmlns:spc="http://xmlns.livinglogic.de/xist/ns/specials">

<p>There are three related methods available for iterating through an &xml;
tree and finding nodes in the tree: The methods <meth>walk</meth>,
<meth>walknodes</meth> and <meth>walkpaths</meth>.</p>

<section><h>The <meth>walk</meth> method</h>

<p>The method <pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>
is a generator. When called without any arguments it visits each node in the
tree once. Furthermore without arguments parent nodes are yielded before their
children, and no attribute nodes are yielded. (This can however be changed
by passing certain arguments to <pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>.)</p>

<p>What <pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>
outputs is a <pyref module="ll.xist.xsc" class="Cursor"><class>Cursor</class></pyref>
object (in fact <pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>
always yields the same cursor object, but the attributes will be updated during
the traversal). A <pyref module="ll.xist.xsc" class="Cursor"><class>Cursor</class></pyref>
object has the following attributes:</p>

<dl>
<dt><lit>root</lit></dt>
<dd>The node where traversal has been started (i.e. the object for which the
<pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>
method has been called).</dd>
<dt><lit>node</lit></dt>
<dd>The current node being traversed.</dd>
<dt><lit>path</lit></dt>
<dd>A list of nodes that contains the path through the tree from the root to
the current node (i.e. <lit>path[0]</lit> is <lit>root</lit> and <lit>path[-1]</lit>
is <lit>node</lit>).</dd>
<dt><lit>index</lit></dt>
<dd>A path of indices (e.g. <lit>[0, 1]</lit> if the current node is the second
child of the first child of the root). Inside attributes the index path will
contain the name of the attribute (or a (attribute name, namespace name) tuple
inside a global attribute).</dd>
<dt><lit>event</lit></dt>
<dd>A string that specifies which event is currently being handled. Possible
values are: <lit>"enterelementnode"</lit>, <lit>"leaveelementnode"</lit>,
<lit>"enterattrnode"</lit>, <lit>"leaveattrnode"</lit>, <lit>"textnode"</lit>,
<lit>"commentnode"</lit>, <lit>"doctypenode"</lit>, <lit>"procinstnode"</lit>,
<lit>"entitynode"</lit> and <lit>"nullnode"</lit>.
</dd>
</dl>

<p>The following example shows the basic usage of the
<pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>
method:</p>

<example><h>Using the <meth>walk</meth> method</h>
<tty>
<prompt>&gt;&gt;&gt; </prompt><input> from ll.xist.ns import html</input>
<prompt>&gt;&gt;&gt; </prompt><input> e = html.ul(html.li(i) for i in range(3))</input>
<prompt>&gt;&gt;&gt; </prompt><input> for cursor in e.walk():</input>
<prompt>... </prompt><input> 	print("{0.event} {0.node!r}".format(cursor))</input>
<prompt>... </prompt><input></input>
<![CDATA[enterelementnode <ll.xist.ns.html.ul element object (3 children/no attrs) at 0x43fbb0>
enterelementnode <ll.xist.ns.html.li element object (1 child/no attrs) at 0x452750>
textnode <ll.xist.xsc.Text content='0' at 0x5b1670>
enterelementnode <ll.xist.ns.html.li element object (1 child/no attrs) at 0x452830>
textnode <ll.xist.xsc.Text content='1' at 0x5b16e8>
enterelementnode <ll.xist.ns.html.li element object (1 child/no attrs) at 0x5b30d0>
textnode <ll.xist.xsc.Text content='2' at 0x5b1760>]]>
</tty>
</example>

<p>The <lit>path</lit> attribute can be used like this:</p>

<example><h>Using the <lit>path</lit> attribute</h>
<tty>
<prompt>&gt;&gt;&gt; </prompt><input> from ll.xist.ns import html</input>
<prompt>&gt;&gt;&gt; </prompt><input> e = html.ul(html.li(i) for i in range(3))</input>
<prompt>&gt;&gt;&gt; </prompt><input> for cursor in e.walk():</input>
<prompt>... </prompt><input> 	print(["{0.__module__}.{0.__qualname__}".format(n.__class__) for n in cursor.path])</input>
<prompt>... </prompt><input></input>
['ll.xist.ns.html.ul']
['ll.xist.ns.html.ul', 'll.xist.ns.html.li']
['ll.xist.ns.html.ul', 'll.xist.ns.html.li', 'll.xist.xsc.Text']
['ll.xist.ns.html.ul', 'll.xist.ns.html.li']
['ll.xist.ns.html.ul', 'll.xist.ns.html.li', 'll.xist.xsc.Text']
['ll.xist.ns.html.ul', 'll.xist.ns.html.li']
['ll.xist.ns.html.ul', 'll.xist.ns.html.li', 'll.xist.xsc.Text']
</tty>
</example>

<p>The following example shows how the <lit>index</lit> attribute works:</p>

<example><h>Using the <lit>index</lit> attribute</h>
<tty>
<prompt>&gt;&gt;&gt; </prompt><input> from ll.xist.ns import html</input>
<prompt>&gt;&gt;&gt; </prompt><input> e = html.ul(html.li(i) for i in range(3))</input>
<prompt>&gt;&gt;&gt; </prompt><input> for cursor in e.walk():</input>
<prompt>... </prompt><input> 	print("{0.index} {0.node!r}".format(cursor))</input>
<prompt>... </prompt><input></input>
<![CDATA[[] <ll.xist.ns.html.ul element object (5 children/no attrs) at 0x4b7bb0>
[0] <ll.xist.ns.html.li element object (1 child/no attrs) at 0x4ca750>
[0, 0] <ll.xist.xsc.Text content='0' at 0x629670>
[1] <ll.xist.ns.html.li element object (1 child/no attrs) at 0x4ca830>
[1, 0] <ll.xist.xsc.Text content='1' at 0x6296e8>
[2] <ll.xist.ns.html.li element object (1 child/no attrs) at 0x62b0d0>
[2, 0] <ll.xist.xsc.Text content='2' at 0x629760>]]>
</tty>
</example>

</section>

<section><h>Changing which parts of the tree are traversed</h>
<p>The <pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>
method has a few additional parameters that specify which part of the tree should
be traversed and in which order:</p>

<dl>
<dt><lit>entercontent</lit> (default <lit>True</lit>)</dt>
<dd>Should the content of an element be entered? Note that when you call
<pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>
with <lit>entercontent</lit> being false, <pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>
will only yield the root node itself.</dd>

<dt><lit>enterattrs</lit> (default <lit>False</lit>)</dt>
<dd><p>Should the attributes of an element be entered? The following example
shows the usage of <lit>enterattrs</lit>:</p>

<example><h>Using the <lit>enterattrs</lit> parameter</h>
<tty>
<prompt>&gt;&gt;&gt; </prompt> <input>from ll.xist.ns import html</input>
<prompt>&gt;&gt;&gt; </prompt> <input>e = html.ul(html.li(i, class_="li-{}".format(i)) for i in range(3))</input>
<prompt>&gt;&gt;&gt; </prompt> <input>for cursor in e.walk(enterattrs=True):</input>
<prompt>... </prompt> <input>	print("{}{!r}".format("\t"*(len(cursor.path)-1), cursor.node))</input>
<prompt>... </prompt> <input></input>
<![CDATA[<ll.xist.ns.html.ul element object (3 children/no attrs) at 0x51e790>
	<ll.xist.ns.html.li element object (1 child/1 attr) at 0x51e8b0>
		<ll.xist.ns.html.coreattrs.class_ attr object (1 child) at 0x532f30>
		<ll.xist.xsc.Text content='0' at 0x67e6c0>
	<ll.xist.ns.html.li element object (1 child/1 attr) at 0x67f8b0>
		<ll.xist.ns.html.coreattrs.class_ attr object (1 child) at 0x671720>
		<ll.xist.xsc.Text content='1' at 0x67e7b0>
	<ll.xist.ns.html.li element object (1 child/1 attr) at 0x67f930>
		<ll.xist.ns.html.coreattrs.class_ attr object (1 child) at 0x671630>
		<ll.xist.xsc.Text content='2' at 0x67e990>]]></tty>
</example>

<p>When both <lit>entercontent</lit> and <lit>enterattrs</lit> are true, the
attributes will always be entered before the content. Setting <lit>enterattrs</lit>
to true will only visit the attribute nodes themselves, but not their content.</p>

</dd>

<dt><lit>enterattr</lit> (default <lit>False</lit>)</dt>
<dd>
<p>Should the content of the attributes of an element be entered? (This is
only relevant if <lit>enterattrs</lit> is true.) The following example shows the
usage of the <lit>enterattr</lit> parameter:</p>

<example><h>Using the <lit>enterattr</lit> parameter</h>
<tty>
<prompt>&gt;&gt;&gt; </prompt> <input>from ll.xist.ns import html</input>
<prompt>&gt;&gt;&gt; </prompt> <input>e = html.ul(html.li(i, class_="li-{}".format(i)) for i in range(3))</input>
<prompt>&gt;&gt;&gt; </prompt> <input>for cursor in e.walk(enterattrs=True, enterattr=True):</input>
<prompt>... </prompt> <input>	print("{}{!r}".format("\t"*(len(cursor.path)-1), cursor.node))</input>
<prompt>... </prompt> <input></input>
<![CDATA[<ll.xist.ns.html.ul element object (3 children/no attrs) at 0x4c1790>
	<ll.xist.ns.html.li element object (1 child/1 attr) at 0x4c18b0>
		<ll.xist.ns.html.coreattrs.class_ attr object (1 child) at 0x4d5f30>
			<ll.xist.xsc.Text content='li-0' at 0x621788>
		<ll.xist.xsc.Text content='0' at 0x621710>
	<ll.xist.ns.html.li element object (1 child/1 attr) at 0x6228b0>
		<ll.xist.ns.html.coreattrs.class_ attr object (1 child) at 0x614720>
			<ll.xist.xsc.Text content='li-1' at 0x621968>
		<ll.xist.xsc.Text content='1' at 0x621800>
	<ll.xist.ns.html.li element object (1 child/1 attr) at 0x622930>
		<ll.xist.ns.html.coreattrs.class_ attr object (1 child) at 0x614630>
			<ll.xist.xsc.Text content='li-2' at 0x621ad0>
		<ll.xist.xsc.Text content='2' at 0x6219e0>]]></tty>
</example>

</dd>

</dl>

</section>

<section><h>Changing traversal order</h>

<p>The default traversal order is "top down". The following
<pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>
parameters can be used to change that into "bottom up" order or into visiting
each element or attribute both on the way down <em>and</em> up:</p>

<dl>
<dt><lit>enterelementnode</lit> (default <lit>True</lit>)</dt>
<dd>Should the generator yield the cursor before it enters an element (i.e.
before it visits the attributes and content of the element)? The cursor attribute
<lit>event</lit> will have the value <lit>"enterelementnode"</lit> in this case.</dd>

<dt><lit>leaveelementnode</lit> (default <lit>False</lit>)</dt>
<dd>Should the generator yield the cursor after it has visited an element? The
cursor attribute <lit>event</lit> will have the value <lit>"leaveelementnode"</lit>
in this case. Passing <lit>enterelementnode=False, leaveelementnode=True</lit> to
<pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>
will change "top down" traversal into "bottom up".</dd>

<dt><lit>enterattrnode</lit> (default <lit>True</lit>)</dt>
<dd>Should the generator yield the cursor before it enters an attribute?
The cursor attribute <lit>event</lit> will have the value <lit>"enterattrnode"</lit>
in this case. Note that the attribute will only be entered when
<lit>enterattr</lit> is true and it will only be visited if <lit>enterattrs</lit>
is true.</dd>

<dt><lit>leaveattrnode</lit> (default <lit>False</lit>)</dt>
<dd>Should the generator yield the cursor after it has visited an attribute?
The cursor attribute <lit>event</lit> will have the value <lit>"leaveattrnode"</lit>
in this case. Note that the attribute will only be entered when
<lit>enterattr</lit> is true and it will only be visited if <lit>enterattrs</lit>
is true.</dd>
</dl>

<p>Passing <lit>True</lit> for all these parameters gives us the following output:</p>

<example><h>Full tree traversal</h>
<tty>
<prompt>&gt;&gt;&gt; </prompt> <input>from ll.xist.ns import html</input>
<prompt>&gt;&gt;&gt; </prompt> <input>e = html.ul(html.li(i, class_="li-{}".format(i)) for i in range(3))</input>
<prompt>&gt;&gt;&gt; </prompt> <input>for cursor in e.walk(entercontent=True, enterattrs=True, enterattr=True,</input>
<prompt>... </prompt> 	<input> enterelementnode=True, leaveelementnode=True,</input>
<prompt>... </prompt> 	<input> enterattrnode=True, leaveattrnode=True):</input>
<prompt>... </prompt> <input>	print("{0}{1.event} {1.index} {1.node!r}".format("\t"*(len(cursor.path)-1), cursor))</input>
<prompt>... </prompt> <input></input>
<![CDATA[enterelementnode [] <ll.xist.ns.html.ul element object (3 children/no attrs) at 0x4cbe50>
	enterelementnode [0] <ll.xist.ns.html.li element object (1 child/1 attr) at 0x4de850>
		enterattrnode [0, 'class'] <ll.xist.ns.html.coreattrs.class_ attr object (1 child) at 0x4f2f90>
			textnode [0, 'class', 0] <ll.xist.xsc.Text content='li-0' at 0x63f800>
		leaveattrnode [0, 'class'] <ll.xist.ns.html.coreattrs.class_ attr object (1 child) at 0x4f2f90>
		textnode [0, 0] <ll.xist.xsc.Text content='0' at 0x63f788>
	leaveelementnode [0] <ll.xist.ns.html.li element object (1 child/1 attr) at 0x4de850>
	enterelementnode [1] <ll.xist.ns.html.li element object (1 child/1 attr) at 0x63e870>
		enterattrnode [1, 'class'] <ll.xist.ns.html.coreattrs.class_ attr object (1 child) at 0x631780>
			textnode [1, 'class', 0] <ll.xist.xsc.Text content='li-1' at 0x63f9e0>
		leaveattrnode [1, 'class'] <ll.xist.ns.html.coreattrs.class_ attr object (1 child) at 0x631780>
		textnode [1, 0] <ll.xist.xsc.Text content='1' at 0x63f878>
	leaveelementnode [1] <ll.xist.ns.html.li element object (1 child/1 attr) at 0x63e870>
	enterelementnode [2] <ll.xist.ns.html.li element object (1 child/1 attr) at 0x63e8f0>
		enterattrnode [2, 'class'] <ll.xist.ns.html.coreattrs.class_ attr object (1 child) at 0x631690>
			textnode [2, 'class', 0] <ll.xist.xsc.Text content='li-2' at 0x63fb48>
		leaveattrnode [2, 'class'] <ll.xist.ns.html.coreattrs.class_ attr object (1 child) at 0x631690>
		textnode [2, 0] <ll.xist.xsc.Text content='2' at 0x63fa58>
	leaveelementnode [2] <ll.xist.ns.html.li element object (1 child/1 attr) at 0x63e8f0>
leaveelementnode [] <ll.xist.ns.html.ul element object (3 children/no attrs) at 0x4cbe50>]]></tty>
</example>

</section>

<section><h>Skipping parts of the tree</h>

<p>It is possible to change the cursor attributes that specify the traversal
order during the traversal to skip certain parts of the tree. In the following
example the content of <class>html.li</class> elements is skipped if they have a
<lit>class</lit> attribute:</p>

<example><h>Skipping parts of the tree</h>
<tty>
<prompt>&gt;&gt;&gt; </prompt> <input>from ll.xist.ns import html</input>
<prompt>&gt;&gt;&gt; </prompt> <input>e = html.ul(html.li(i, class_=None if i%2 else "li-{}".format(i)) for i in range(3))</input>
<prompt>&gt;&gt;&gt; </prompt> <input>for cursor in e.walk():</input>
<prompt>... </prompt> <input>	if isinstance(cursor.node, html.li) and "class_" in cursor.node.attrs:</input>
<prompt>... </prompt> <input>		cursor.entercontent = False</input>
<prompt>... </prompt> <input>	print("{0}{1.event} {1.node!r}".format("\t"*(len(cursor.path)-1), cursor))</input>
<prompt>... </prompt> <input></input>
<![CDATA[enterelementnode <ll.xist.ns.html.ul element object (3 children/no attrs) at 0x495790>
	enterelementnode <ll.xist.ns.html.li element object (1 child/1 attr) at 0x4958d0>
	enterelementnode <ll.xist.ns.html.li element object (1 child/no attrs) at 0x5f6130>
		textnode <ll.xist.xsc.Text content='1' at 0x5f4760>
	enterelementnode <ll.xist.ns.html.li element object (1 child/1 attr) at 0x5f6570>]]></tty>
</example>

<p>This works for the following attributes:</p>

<ul>
<li><lit>entercontent</lit></li>
<li><lit>enterattrs</lit></li>
<li><lit>enterattr</lit></li>
<li><lit>enterelementnode</lit></li>
<li><lit>leaveelementnode</lit></li>
<li><lit>enterattrnode</lit></li>
<li><lit>leaveattrnode</lit></li>
</ul>

<p>After the <pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>
generator has been reentered and the modified attribute has been taken into
account all those attributes wil be reset to their initial value (i.e. the
value that has been passed to <pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>).</p>

</section>


<section><h>The methods <meth>walknodes</meth> and <meth>walkpaths</meth></h>

<p>In addition to <pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>
two other methods are available: <pyref module="ll.xist.xsc" class="Node" method="walknodes"><meth>walknodes</meth></pyref>
and <pyref module="ll.xist.xsc" class="Node" method="walkpaths"><meth>walkpaths</meth></pyref>.</p>

<p>These generators don't produce a cursor object like <pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref> does.
<pyref module="ll.xist.xsc" class="Node" method="walknodes"><meth>walknodes</meth></pyref>
produces the node itself as the following example demonstrates:</p>

<example><h>Using <meth>walknodes</meth></h>
<tty>
<prompt>&gt;&gt;&gt; </prompt><input> from ll.xist.ns import html</input>
<prompt>&gt;&gt;&gt; </prompt><input> e = html.ul(html.li(i) for i in range(3))</input>
<prompt>&gt;&gt;&gt; </prompt><input> for node in e.walknodes():</input>
<prompt>... </prompt><input> 	print(repr(node))</input>
<prompt>... </prompt><input></input>
<![CDATA[<ll.xist.ns.html.ul element object (3 children/no attrs) at 0x43fbb0>
<ll.xist.ns.html.li element object (1 child/no attrs) at 0x452750>
<ll.xist.xsc.Text content='0' at 0x5b1670>
<ll.xist.ns.html.li element object (1 child/no attrs) at 0x452830>
<ll.xist.xsc.Text content='1' at 0x5b16e8>
<ll.xist.ns.html.li element object (1 child/no attrs) at 0x5b30d0>
<ll.xist.xsc.Text content='2' at 0x5b1760>]]>
</tty>
</example>

<p><pyref module="ll.xist.xsc" class="Node" method="walkpaths"><meth>walkpaths</meth></pyref>
produces the path. This is a copy of the path, so it won't be changed once
<pyref module="ll.xist.xsc" class="Node" method="walkpaths"><meth>walkpaths</meth></pyref>
is reentered:</p>

<example><h>Using <meth>walkpaths</meth></h>
<tty>
<prompt>&gt;&gt;&gt; </prompt><input> from ll.xist.ns import html</input>
<prompt>&gt;&gt;&gt; </prompt><input> e = html.ul(html.li(i) for i in range(3))</input>
<prompt>&gt;&gt;&gt; </prompt><input> for node in e.walkpaths():</input>
<prompt>... </prompt><input> 	print(["{0.__module__}.{0.__qualname__}".format(n.__class__) for n in path])</input>
<prompt>... </prompt><input></input>
<![CDATA[['ll.xist.ns.html.ul']
['ll.xist.ns.html.ul', 'll.xist.ns.html.li']
['ll.xist.ns.html.ul', 'll.xist.ns.html.li', 'll.xist.xsc.Text']
['ll.xist.ns.html.ul', 'll.xist.ns.html.li']
['ll.xist.ns.html.ul', 'll.xist.ns.html.li', 'll.xist.xsc.Text']
['ll.xist.ns.html.ul', 'll.xist.ns.html.li']
['ll.xist.ns.html.ul', 'll.xist.ns.html.li', 'll.xist.xsc.Text']
]]>
</tty>
</example>

</section>


<section><h>Filtering the output of the tree traversal</h>

<p>All three tree traversal methods provide an additional argument
(<lit>*selectors</lit>) that can be used to filter which nodes/paths are produced.
This argument can be specified multiple times (which also means that all other
arguments must be passed as keyword arguments).</p>

<section><h>Passing a node class</h>
<p>In the simplest case you can pass a <pyref module="ll.xist.xsc" class="Node"><class>Node</class></pyref>
subclass to get only instances of that class. The following example prints all
the links on the <a href="http://www.python.org/">Python home page</a>:</p>

<example><h>Finding all links on the Python home page</h>
<prog>
from ll.xist import xsc, parse
from ll.xist.ns import xml, html

doc = parse.tree(
	parse.URL("http://www.python.org"),
	parse.Expat(ns=True),
	parse.Node(pool=xsc.Pool(xml, html, chars))
)

for node in doc.walknodes(html.a):
	print(node.attrs.href)
</prog>
</example>

<p>This gives the output:</p>

<tty>
http://www.python.org/
http://www.python.org/#left%2Dhand%2Dnavigation
http://www.python.org/#content%2Dbody
http://www.python.org/search
http://www.python.org/about/
http://www.python.org/news/
http://www.python.org/doc/
http://www.python.org/download/
http://www.python.org/getit/
http://www.python.org/community/
<rep>...</rep>
</tty>

</section>

<section><h>Passing multiple selector arguments</h>
<p>You can also pass multiple classes to search for nodes that are an instance
of any of the classes:</p>

<p>The following example will print all header element on the Python home page:</p>

<example><h>Finding all headers on the Python home page</h>
<prog>
from ll.xist import xsc, parse
from ll.xist.ns import xml, html, chars

doc = parse.tree(
	parse.URL("http://www.python.org"),
	parse.Expat(ns=True),
	parse.Node(pool=xsc.Pool(xml, html, chars))
)

for node in doc.walknodes(html.h1, html.h2, html.h3, html.h4, html.h5, html.h6):
	print(node.string())
</prog>
</example>

<p>This will output:</p>

<tty>
<![CDATA[<h1 id="logoheader">
    <a accesskey="1" href="http://www.python.org/" id="logolink">
      <img alt="homepage" border="0" id="logo" src="http://www.python.org/images/python-logo.gif" />
   </a>
  </h1>
<h4><a href="http://www.python.org/about/help/">Help</a></h4>
<h4><a href="http://pypi.python.org/pypi" title="Repository of Python Software">Package Index</a></h4>
<h4><a href="http://www.python.org/download/releases/2.7.3/">Quick Links (2.7.3)</a></h4>
<h4><a href="http://www.python.org/download/releases/3.3.0/">Quick Links (3.3.0)</a></h4>
<h4><a href="http://www.python.org/community/jobs/" title="Employers and Job Openings">Python Jobs</a></h4>
<h4><a href="http://www.python.org/community/merchandise/" title="T-shirts &amp; more; a portion goes to the PSF">Python Merchandise</a></h4>
<h4><a href="http://wiki.python.org/moin/" style="margin-top: 1.5em">Python Wiki</a></h4>
<h4><a href="http://blog.python.org/" style="margin-top: 1.5em">Python Insider Blog</a></h4>
<h4><a href="http://wiki.python.org/moin/Python2orPython3" style="margin-top: 1.5em">Python 2 or 3?</a></h4>
<h4><a href="http://www.python.org/psf/donations/" style="color: #D58228; margin-top: 1.5em">Help Fund Python</a></h4>
<h4><a href="http://wiki.python.org/moin/Languages">Non-English Resources</a></h4>
<h1 class="pageheading">Python Programming Language – Official Website</h1>
<h4>Support the Python Community</h4>
<h4><a href="http://wiki.python.org/moin/Python2orPython3">Python 3</a> Poll</h4>
<h4>NASA uses Python...</h4>
<h4>What they are saying...</h4>
<h4>Using Python For...</h4>
<h2 class="news">Python 3.3.0 released</h2>
<h2 class="news">Third rc for Python 3.3.0 released</h2>
<h2 class="news">Python Software Foundation announces Distinguished Service Award</h2>
<h2 class="news">ConFoo conference in Canada, February 25th - March 13th</h2>
<h2 class="news">Second rc for Python 3.3.0 released</h2>
<h2 class="news">First rc for Python 3.3.0 released</h2>
<h2 class="news">Fifth annual pyArkansas conference to be held</h2>]]>
</tty>

</section>

<section><h>Passing a callable</h>

<p>It is also possible to pass a function to <pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>.
This function will be called for each visited node and gets passed the path to
the visited node. If the function returns true, the node will be output.</p>

<p>The following example will find all external links on the Python home
page:</p>

<example><h>Finding external links on the Python home page</h>
<prog>
from ll.xist import xsc, parse
from ll.xist.ns import xml, html, chars

doc = parse.tree(
	parse.URL("http://www.python.org"),
	parse.Expat(ns=True),
	parse.Node(pool=xsc.Pool(xml, html, chars))
)

def isextlink(path):
	return isinstance(path[-1], html.a) and not str(path[-1].attrs.href).startswith("http://www.python.org")

for node in doc.walknodes(isextlink):
	print(node.attrs.href)
</prog>
</example>

<p>This gives the output:</p>

<tty>
http://docs.python.org/devguide/
http://pypi.python.org/pypi
http://docs.python.org/2/
http://docs.python.org/3/
http://wiki.python.org/moin/
http://blog.python.org/
http://wiki.python.org/moin/Python2orPython3
http://wiki.python.org/moin/Languages
http://wiki.python.org/moin/Languages
<rep>...</rep>
</tty>

</section>

<section><h><mod>xfind</mod> selectors</h>

<p>The selector arguments for the walk methods get converted into a so called
xfind selector. xfind selectors look somewhat like XPath expressions, but are
implemented as pure Python expressions (overloading various Python operators).</p>

<p>Every subclass of
<pyref module="ll.xist.xsc" class="Node"><class>ll.xist.xsc.Node</class></pyref>
can be used as an xfind selector and combined with other xfind selector to create
more complex ones. For example searching for links that contain images works as
follows:</p>

<example><h>Searching for <class>img</class> inside <class>a</class> with an xfind expression</h>
<prog>
for path in doc.walkpaths(html.a/html.img):
	print(path[-2].attrs.href, path[-1].attrs.src)
</prog>
</example>

<p>The output looks like this:</p>

<tty>
http://www.python.org/ http://www.python.org/images/python-logo.gif
http://www.python.org/#left%2Dhand%2Dnavigation http://www.python.org/images/trans.gif
http://www.python.org/#content%2Dbody http://www.python.org/images/trans.gif
http://www.python.org/psf/donations/ http://www.python.org/images/donate.png
http://wiki.python.org/moin/Languages http://www.python.org/images/worldmap.jpg
http://www.python.org/about/success/usa/ http://www.python.org/images/success/nasa.jpg
</tty>

<p>If the <class>img</class> elements are not immediate children of the
<class>a</class> elements, the xfind selector above won't output then. In this
case you can use a <z>decendant selector</z> instead of a <z>child selector</z>.
To do this simply replace <lit>html.a/html.img</lit> with <lit>html.a//html.img</lit>.</p>

<p>Apart from the <lit>/</lit> and <lit>//</lit> operators you can also use
the <lit>|</lit> and <lit>&amp;</lit> operators to combine xfind selector:</p>

<prog>
from ll.xist import xsc, parse, xfind
from ll.xist.ns import xml, html

doc = parse.tree(
	parse.URL("http://www.python.org"),
	parse.Expat(ns=True),
	parse.Node(pool=xsc.Pool(xml, html, chars))
)

for node in doc.walknodes((html.a | html.area) &amp; xfind.hasattr("href")):
	print(node.attrs.href)
</prog>

<p>Here's another example that finds all elements that have an <lit>id</lit>
attribute:</p>

<prog>
from ll.xist import xsc, parse, xfind
from ll.xist.ns import xml, html, chars

doc = parse.tree(
	parse.URL("http://www.python.org"),
	parse.Expat(ns=True),
	parse.Node(pool=xsc.Pool(xml, html, chars))
)

for node in doc.walknodes(xfind.hasattr("id")):
	print(node.attrs.id)
</prog>

<p>The output looks like this:</p>

<tty>
screen-switcher-stylesheet
logoheader
logolink
logo
skiptonav
skiptocontent
utility-menu
searchbox
searchform
<rep>...</rep>
</tty>

<p>For more examples refer to the documentation of the <pyref module="ll.xist.xfind"><mod>xfind</mod></pyref>
module.</p>

</section>


<section><h>&css; selectors</h>

<p>It's also possible to use &css; selectors as selectors for the
<pyref module="ll.xist.xsc" class="Node" method="walk"><meth>walk</meth></pyref>
method. The module <pyref module="ll.xist.css"><mod>ll.xist.css</mod></pyref>
provides a function <func>selector</func> that turns a &css; selector expression
into an xfind selector:</p>

<example><h>Using &css; selectors as xfind selector</h>
<prog>
from ll.xist import xsc, parse, css
from ll.xist.ns import xml, html, chars

doc = parse.tree(
	parse.URL("http://www.python.org"),
	parse.Expat(ns=True),
	parse.Node(pool=xsc.Pool(xml, html, chars))
)

for cursor in doc.walk(css.selector("div#menu ul.level-one li > a")):
	print(cursor.node.attrs.href)
</prog>
</example>

<p>This outputs all the first level links in the navigation:</p>
<tty>
http://www.python.org/about/
http://www.python.org/news/
http://www.python.org/doc/
http://www.python.org/download/
http://www.python.org/getit/
http://www.python.org/community/
http://www.python.org/psf/
http://docs.python.org/devguide/
</tty>

<p>Most of the <a href="http://www.w3.org/TR/css3-selectors/">CSS 3 selectors</a>
are supported.</p>

<p>For more examples see the documentation of the
<pyref module="ll.xist.css"><mod>css</mod></pyref> module.</p>

</section>

</section>

</spc:wrap>
