epubjs
Version:
Render ePub documents in the browser, across many devices
180 lines (178 loc) • 30.3 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>XPath</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="XPath"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-24-SECT-5"/>XPath</h1></div></div></div><p>XPath is an expression language for addressing parts of an XML
document. You can think of XPath expressions as sort of like regular
expressions for XML. They let you pull out parts of an XML document based
on patterns. In the case of XPath, the patterns are more concerned with
structural information than with character content and the values returned
may be either simple text or “live” DOM nodes. With XPath, we can query an
XML document for all of the elements with a certain name or in a certain
parent-child relationship. We can also apply fairly sophisticated tests or
<span class="emphasis"><em>predicates</em></span> to the nodes, which allows us to construct
complex queries such as this one: give me all of the <code class="literal">Animal</code>s with a <code class="literal">Weight</code> greater than the number 400 and a
<code class="literal">Temperament</code> of <code class="literal">irritable</code> whose <code class="literal">animalClass</code> attribute is <code class="literal">mammal</code>.</p><p>The full XPath specification has many features and includes both a
compact and more verbose syntax. We won’t try to cover it all here, but
the basics are easy and it’s important to know them because XPath
expressions are at the core of XSL transformations and other APIs that
refer to parts of XML documents. The full specification does not make
great bedtime reading, but can be found at <a class="ulink" href="http://www.w3.org/TR/xpath">http://www.w3.org/TR/xpath</a>.</p><div class="sect2" title="Nodes"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-24-SECT-5.1"/>Nodes</h2></div></div></div><p><a id="idx11199" class="indexterm"/> <a id="idx11229" class="indexterm"/> <a id="idx11235" class="indexterm"/>An XPath expression addresses a <code class="literal">Node</code> in an XML document tree. The node may be
an element (possibly with children) like <code class="literal"><animal>...</animal></code> or it may be
a lower-level document node representing an attribute (e.g., <code class="literal">animalClass="mammal"</code>), a CDATA block, or even
a comment. All of the structure of an XML document is accessible through
the XPath syntax. Once we’ve addressed the node, we can either reduce
the content to a text string (as we might with a simple text content
element like <code class="literal">name</code>) or we can access
it as a proper DOM tree to further read or manipulate it.</p><p><a class="xref" href="ch24s06.html#learnjava3-CHP-24-TABLE-2" title="Table 24-2. Basic node-related syntax">Table 24-2</a> shows the most basic
node-related syntax.</p><div class="table"><a id="learnjava3-CHP-24-TABLE-2"/><p class="title">Table 24-2. Basic node-related syntax</p><div class="table-contents"><table summary="Basic node-related syntax" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; "><colgroup><col/><col/><col/></colgroup><thead><tr><th style="text-align: left"><p>Syntax</p></th><th style="text-align: left"><p>Example</p></th><th style="text-align: left"><p>Description</p></th></tr></thead><tbody><tr><td style="text-align: left"><p> <a id="I_indexterm24_id831274" class="indexterm"/> <a id="I_indexterm24_id831280" class="indexterm"/> <code class="literal">/Name</code>
</p></td><td style="text-align: left"><p> <code class="literal">/inventory/animal</code> </p></td><td style="text-align: left"><p>All animal nodes under <code class="literal">/inventory</code>. </p></td></tr><tr><td style="text-align: left"><p> <code class="literal">//Name</code> </p></td><td style="text-align: left"><p> <code class="literal">//animal</code> </p></td><td style="text-align: left"><p>All animal nodes anywhere in document.
A <code class="literal">foodRecipe/animal</code> would
also match.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm24_id831353" class="indexterm"/> <a id="I_indexterm24_id831362" class="indexterm"/> <code class="literal">Name/*</code>
</p></td><td style="text-align: left"><p> <code class="literal">/inventory/*</code> </p></td><td style="text-align: left"><p>All child nodes of inventory (<code class="literal">animal</code>s and any other elements
directly under <code class="literal">inventory</code>).</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm24_id831411" class="indexterm"/> <code class="literal">@Name</code>
</p></td><td style="text-align: left"><p> <code class="literal">//animal/@animalClass</code> </p></td><td style="text-align: left"><p>All <code class="literal">animalClass</code> attributes of <code class="literal">animal</code>s.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm24_id831455" class="indexterm"/> <a id="I_indexterm24_id831464" class="indexterm"/> <code class="literal">.</code>
</p></td><td style="text-align: left"><p> <code class="literal">/inventory/animal/.</code> </p></td><td style="text-align: left"><p>The current node (all <code class="literal">animal</code>s).</p></td></tr><tr><td style="text-align: left"><p> <code class="literal">..</code>
</p></td><td style="text-align: left"><p> <code class="literal">/inventory/animal/..</code> </p></td><td style="text-align: left"><p>The parent node (<code class="literal">inventory</code>).</p></td></tr></tbody></table></div></div><p>Nodes are addressed with a slash-separated path based on name. For
example, <code class="literal">/Inventory/Animal</code> refers to
the set of all <code class="literal">Animal</code> nodes under the
<code class="literal">Inventory</code> node. If we want to list
the names of all <code class="literal">Animal</code>s, we would
use <code class="literal">/Inventory/Animal/Name</code>. The
<code class="literal">//</code> syntax matches a node anywhere in
a document, at any level of nesting, so <code class="literal">//Name</code> would match the name elements of
<code class="literal">Animal</code>s, <code class="literal">FoodRecipe</code>s, and possibly many other elements.
We could be more specific, using <code class="literal">//Animal/Name</code> to match only <code class="literal">Name</code> elements whose parent is an <code class="literal">Animal</code> element. The at sign (@) matches
attributes. This becomes much more useful with predicates, which we
describe next. Finally, the familiar <code class="literal">.</code> and <code class="literal">..</code>
notation can be used to “move” relative to a node; read on to see how
this is used.<a id="I_indexterm24_id831618" class="indexterm"/><a id="I_indexterm24_id831625" class="indexterm"/><a id="I_indexterm24_id831632" class="indexterm"/></p></div><div class="sect2" title="Predicates"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-24-SECT-5.2"/>Predicates</h2></div></div></div><p><a id="idx11200" class="indexterm"/> <a id="I_indexterm24_id831656" class="indexterm"/> <a id="I_indexterm24_id831667" class="indexterm"/>Predicates let us apply a test to a node. Nodes that pass
the test are included in the result set or used to select other nodes
(child or parent) relative to them. There are many types of tests
available in XPath. <a class="xref" href="ch24s06.html#learnjava3-CHP-24-TABLE-3" title="Table 24-3. Predicates">Table 24-3</a> lists a
few examples.</p><div class="table"><a id="learnjava3-CHP-24-TABLE-3"/><p class="title">Table 24-3. Predicates</p><div class="table-contents"><table summary="Predicates" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; "><colgroup><col/><col/><col/></colgroup><thead><tr><th style="text-align: left"><p>Syntax</p></th><th style="text-align: left"><p>Example</p></th><th style="text-align: left"><p>Description</p></th></tr></thead><tbody><tr><td style="text-align: left"><p> <a id="I_indexterm24_id831737" class="indexterm"/> <a id="I_indexterm24_id831748" class="indexterm"/> <code class="literal">[n]</code>
</p></td><td style="text-align: left"><p> <code class="literal">/inventory/animal[1]</code> </p></td><td style="text-align: left"><p>Select the <span class="emphasis"><em>n</em></span>th
element of a set. (Starts with 1 rather than 0.) For example,
select the first <code class="literal">animal</code> in
the <code class="literal">inventory</code>.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm24_id831802" class="indexterm"/> <code class="literal">[@name=value]</code>
</p></td><td style="text-align: left"><p> <code class="literal">//animal[@animalClass="mammal"]</code>
</p></td><td style="text-align: left"><p>Match nodes with the specified
attribute value. For example, <code class="literal">animal</code>s with the <code class="literal">animalClass</code> attribute <code class="literal">"mammal"</code>.</p></td></tr><tr><td style="text-align: left"><p> <code class="literal">[element=value]</code> </p></td><td style="text-align: left"><p> <code class="literal">//animal[name="Cocoa"]</code> </p></td><td style="text-align: left"><p>Match nodes with a child node whose
text value is specified. For example, match the <code class="literal">animal</code> with a <code class="literal">name</code> element containing the simple
text <code class="literal">"Cocoa"</code>.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm24_id831896" class="indexterm"/> <a id="I_indexterm24_id831903" class="indexterm"/> <a id="I_indexterm24_id831909" class="indexterm"/> <a id="I_indexterm24_id831916" class="indexterm"/> <a id="I_indexterm24_id831922" class="indexterm"/> <a id="I_indexterm24_id831929" class="indexterm"/> <a id="I_indexterm24_id831936" class="indexterm"/> <code class="literal">=!=><</code>
</p></td><td style="text-align: left"><p> <code class="literal">//animal[weight > 400]</code>
</p></td><td style="text-align: left"><p>Predicates may also test for
inequality and numeric greater-/lesser-than
value.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm24_id831971" class="indexterm"/> <a id="I_indexterm24_id831977" class="indexterm"/> <code class="literal">and, or</code>
</p></td><td style="text-align: left"><p> <code class="literal">//animal[@animalClass= "mammal"</code> or
<code class="literal">@class="reptile"]]</code></p></td><td style="text-align: left"><p>Predicates may use logical AND and OR
to test. For example, <code class="literal">animal</code>s whose <code class="literal">animalClass</code> is <code class="literal">mammal</code> or <code class="literal">reptile</code>.</p></td></tr></tbody></table></div></div><p>Predicates can be compounded (AND’ed) using this syntax or simply
by adding more predicates, like so:</p><a id="I_24_tt1316"/><pre class="programlisting"> <code class="c1">//animal[@animalClass="mammal"][weight > 400]</code></pre><p>Here, we’ve asked for <code class="literal">animal</code>s
with a class attribute of <code class="literal">"mammal"</code>
and a <code class="literal">weight</code> element containing a
number greater than 400.</p><p>We can now also see the usefulness of the <code class="literal">..</code> operator. Suppose we want to find all of
the <code class="literal">animal</code>s with a <code class="literal">foodRecipe</code> that uses <code class="literal">Fruit</code> as an ingredient:</p><a id="I_24_tt1317"/><pre class="programlisting"> <code class="c1">//animal/foodRecipe[ingredient="Fruit"]/..</code></pre><p>The <code class="literal">..</code> means that instead of
returning the matching <code class="literal">foodRecipe</code>
node itself, we return its parent—the <code class="literal">animal</code> element. The <code class="literal">.</code> (current node) operator is useful in other
cases where we use XPath functions to manipulate values in more refined
ways. We’ll say a few words about functions next.<a id="I_indexterm24_id832128" class="indexterm"/></p></div><div class="sect2" title="Functions"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-24-SECT-5.3"/>Functions</h2></div></div></div><p><a id="idx11193" class="indexterm"/> <a id="idx11228" class="indexterm"/> <a id="idx11234" class="indexterm"/>The XPath specification includes not only the basic node
traversal and predicate syntax we’ve shown, but also the ability to
invoke more open-ended functions that operate on nodes and the node
context. These XPath functions cover a wide range of duties and we’ll
just give a couple of examples here. The functions fall into a few
general categories.</p><p>Some functions select node types other than an element. For
example, there is no special syntax for selecting an XML comment.
Instead you invoke a special method called <a id="I_indexterm24_id832190" class="indexterm"/><code class="literal">comment()</code>, like
this:</p><a id="I_24_tt1318"/><pre class="programlisting"><code class="o">/</code><code class="n">inventory</code><code class="o">/</code><code class="n">comment</code><code class="o">()</code></pre><p>This expression returns any XML comment nodes that are children of
the <code class="literal">inventory</code> element. XPath also
offers functions that duplicate all of the (compact) syntax we’ve
discussed, including methods like <a id="I_indexterm24_id832220" class="indexterm"/><code class="literal">child()</code> and <a id="I_indexterm24_id832230" class="indexterm"/><code class="literal">parent()</code> (corresponding
to <code class="literal">.</code> and <code class="literal">..</code>).</p><p>Other functions look at the context of nodes—for example,
<a id="I_indexterm24_id832255" class="indexterm"/><code class="literal">last()</code> and <a id="I_indexterm24_id832265" class="indexterm"/><code class="literal">count()</code>.</p><a id="I_24_tt1319"/><pre class="programlisting"><code class="o">/</code><code class="n">inventory</code><code class="o">/</code><code class="n">animal</code><code class="o">[</code><code class="n">last</code><code class="o">()]</code></pre><p>This expression selects the last <code class="literal">animal</code> child element of <code class="literal">inventory</code> in the same way that <code class="literal">[n]</code> selects the
<span class="emphasis"><em>n</em></span>th.</p><a id="I_24_tt1320"/><pre class="programlisting"><code class="c1">//foodRecipe[count(ingredient)>2]</code></pre><p>This expression matches all of the <code class="literal">foodRecipe</code> elements with more than two
ingredients. (Cool, eh?)</p><p>Finally, there are many string-related functions. Some are useful
for simple tests, but others are really useful only in the context of
XSL, where they help out the language (in an awkward way) with basic
formatting and string manipulation. For example, the <a id="I_indexterm24_id832328" class="indexterm"/><code class="literal">contains()</code> and
<a id="I_indexterm24_id832339" class="indexterm"/><code class="literal">starts-with()</code> methods
can be used to look at the text values inside XML documents:</p><a id="I_24_tt1321"/><pre class="programlisting"><code class="c1">//animal[starts-with(name,"S")]</code></pre><p>This expression matches <code class="literal">animal</code>s
whose <code class="literal">name</code> starts with the character
<code class="literal">S</code> (e.g., Song Fang). The <code class="literal">contains()</code> method, similarly, can be used to
look for a substring in text.<a id="I_indexterm24_id832383" class="indexterm"/><a id="I_indexterm24_id832390" class="indexterm"/><a id="I_indexterm24_id832398" class="indexterm"/></p></div><div class="sect2" title="The XPath API"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-24-SECT-5.4"/>The XPath API</h2></div></div></div><p><a id="idx11231" class="indexterm"/> <a id="idx11237" class="indexterm"/>Now that we’ve got a taste for the syntax, let’s look at
how to use the API. The procedure is similar to that of the Java regular
expression API for strings. We use a factory to create an XPath object.
We can then either evaluate expressions with it or “compile” an
expression down to an <a id="I_indexterm24_id832444" class="indexterm"/><code class="literal">XPathExpression</code> for
better performance if we’re going to use it more than once.</p><a id="I_24_tt1322"/><pre class="programlisting"><code class="n">XPath</code> <code class="n">xpath</code> <code class="o">=</code> <code class="n">XPathFactory</code><code class="o">.</code><code class="na">newInstance</code><code class="o">().</code><code class="na">newXPath</code><code class="o">();</code>
<code class="n">InputSource</code> <code class="n">source</code> <code class="o">=</code> <code class="k">new</code> <code class="n">InputSource</code><code class="o">(</code> <code class="n">filename</code> <code class="o">);</code>
<code class="err"> </code>
<code class="n">String</code> <code class="n">result</code> <code class="o">=</code> <code class="n">xpath</code><code class="o">.</code><code class="na">evaluate</code><code class="o">(</code> <code class="s">"//animal/name"</code><code class="o">,</code> <code class="n">source</code> <code class="o">);</code>
<code class="c1">// Song Fang</code></pre><p>Here we’ve used the simplest form of the <a id="I_indexterm24_id832470" class="indexterm"/><code class="literal">evaluate()</code> method,
which returns only the first match and takes the value as a string. This
method is useful for pulling simple text values from elements. However,
if we want the full set of values (e.g., the names of all the <code class="literal">animal</code>s matched by this expression), we need
to return the results as a set of <code class="literal">Node</code> objects instead.</p><p>The return type of (the overloaded forms of) <code class="literal">evaluate()</code> is controlled by identifiers of the
<a id="I_indexterm24_id832503" class="indexterm"/><code class="literal">XPathConstants</code> class.
We can get the result as one of the following: <code class="literal">STRING</code>, <code class="literal">BOOLEAN</code>, <code class="literal">NUMBER</code>, <code class="literal">NODE</code>, or <code class="literal">NODESET</code>. The default is <code class="literal">STRING</code>, which strips out child element tags
and returns just the text of the matching nodes. <code class="literal">BOOLEAN</code> and <code class="literal">NUMBER</code> are conveniences for getting primitive
types. <code class="literal">NODE</code> and <code class="literal">NODESET</code> return <code class="literal">org.w3c.dom.Node</code> and <a id="I_indexterm24_id832573" class="indexterm"/><code class="literal">Node</code><code class="literal">List</code> objects, respectively. We need the
<code class="literal">NodeList</code> to get all the
values.</p><a id="I_24_tt1323"/><pre class="programlisting"><code class="n">NodeList</code> <code class="n">elements</code> <code class="o">=</code> <code class="o">(</code><code class="n">NodeList</code><code class="o">)</code><code class="n">xpath</code><code class="o">.</code><code class="na">evaluate</code><code class="o">(</code>
<code class="n">expression</code><code class="o">,</code> <code class="n">inputSource</code><code class="o">,</code> <code class="n">XPathConstants</code><code class="o">.</code><code class="na">NODESET</code> <code class="o">);</code></pre><p>Next, let’s put this together in a useful example.<a id="I_indexterm24_id832608" class="indexterm"/><a id="I_indexterm24_id832615" class="indexterm"/></p></div><div class="sect2" title="XMLGrep"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-24-SECT-5.5"/>XMLGrep</h2></div></div></div><p><a id="idx11230" class="indexterm"/> <a id="idx11233" class="indexterm"/> <a id="idx11236" class="indexterm"/>This simple example can be used as a command-line utility,
such as <a id="I_indexterm24_id832668" class="indexterm"/><span class="emphasis"><em>grep</em></span>, for testing XPath expressions
against a file. It applies an XPath expression and then prints the
resulting elements as XML text using the same technique we used in our
<code class="literal">PrintDOM</code> example. Nodes that are not
elements (e.g., attributes, comments, and so on) are simply printed with
their <code class="literal">toString()</code> method, which
normally serves well enough to identify them, but you can expand the
example to your taste. Here it is:</p><a id="I_24_tt1324"/><pre class="programlisting"> <code class="kn">import</code> <code class="nn">org.w3c.dom.*</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">org.xml.sax.InputSource</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">javax.xml.xpath.*</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">javax.xml.transform.*</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">javax.xml.transform.dom.DOMSource</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">javax.xml.transform.stream.StreamResult</code><code class="o">;</code>
<code class="err"> </code>
<code class="kd">public</code> <code class="kd">class</code> <code class="nc">XMLGrep</code> <code class="o">{</code>
<code class="err"> </code>
<code class="kd">public</code> <code class="kd">static</code> <code class="kt">void</code> <code class="nf">printXML</code><code class="o">(</code> <code class="n">Element</code> <code class="n">element</code> <code class="o">)</code>
<code class="kd">throws</code> <code class="n">TransformerException</code> <code class="o">{</code>
<code class="n">Transformer</code> <code class="n">transformer</code> <code class="o">=</code>
<code class="n">TransformerFactory</code><code class="o">.</code><code class="na">newInstance</code><code class="o">().</code><code class="na">newTransformer</code><code class="o">();</code>
<code class="n">transformer</code><code class="o">.</code><code class="na">setOutputProperty</code><code class="o">(</code> <code class="n">OutputKeys</code><code class="o">.</code><code class="na">OMIT_XML_DECLARATION</code><code class="o">,</code>
<code class="s">"yes"</code> <code class="o">);</code>
<code class="n">Source</code> <code class="n">source</code> <code class="o">=</code> <code class="k">new</code> <code class="n">DOMSource</code><code class="o">(</code> <code class="n">element</code> <code class="o">);</code>
<code class="n">Result</code> <code class="n">output</code> <code class="o">=</code> <code class="k">new</code> <code class="n">StreamResult</code><code class="o">(</code> <code class="n">System</code><code class="o">.</code><code class="na">out</code> <code class="o">);</code>
<code class="n">transformer</code><code class="o">.</code><code class="na">transform</code><code class="o">(</code> <code class="n">source</code><code class="o">,</code> <code class="n">output</code> <code class="o">);</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">();</code>
<code class="o">}</code>
<code class="err"> </code>
<code class="kd">public</code> <code class="kd">static</code> <code class="kt">void</code> <code class="nf">main</code><code class="o">(</code> <code class="n">String</code> <code class="o">[]</code> <code class="n">args</code> <code class="o">)</code> <code class="kd">throws</code> <code class="n">Exception</code> <code class="o">{</code>
<code class="k">if</code> <code class="o">(</code> <code class="n">args</code><code class="o">.</code><code class="na">length</code> <code class="o">!=</code> <code class="mi">2</code> <code class="o">)</code> <code class="o">{</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code> <code class="s">"usage: PrintXPath expression file.xml"</code> <code class="o">);</code>
<code class="n">System</code><code class="o">.</code><code class="na">exit</code><code class="o">(</code><code class="mi">1</code><code class="o">);</code>
<code class="o">}</code>
<code class="n">String</code> <code class="n">expression</code> <code class="o">=</code> <code class="n">args</code><code class="o">[</code><code class="mi">0</code><code class="o">],</code> <code class="n">filename</code> <code class="o">=</code> <code class="n">args</code><code class="o">[</code><code class="mi">1</code><code class="o">];</code>
<code class="err"> </code>
<code class="n">XPath</code> <code class="n">xpath</code> <code class="o">=</code> <code class="n">XPathFactory</code><code class="o">.</code><code class="na">newInstance</code><code class="o">().</code><code class="na">newXPath</code><code class="o">();</code>
<code class="n">InputSource</code> <code class="n">inputSource</code> <code class="o">=</code> <code class="k">new</code> <code class="n">InputSource</code><code class="o">(</code> <code class="n">filename</code> <code class="o">);</code>
<code class="err"> </code>
<code class="n">NodeList</code> <code class="n">elements</code> <code class="o">=</code> <code class="o">(</code><code class="n">NodeList</code><code class="o">)</code><code class="n">xpath</code><code class="o">.</code><code class="na">evaluate</code><code class="o">(</code>
<code class="n">expression</code><code class="o">,</code> <code class="n">inputSource</code><code class="o">,</code> <code class="n">XPathConstants</code><code class="o">.</code><code class="na">NODESET</code> <code class="o">);</code>
<code class="err"> </code>
<code class="k">for</code><code class="o">(</code> <code class="kt">int</code> <code class="n">i</code><code class="o">=</code><code class="mi">0</code><code class="o">;</code> <code class="n">i</code><code class="o"><</code><code class="n">elements</code><code class="o">.</code><code class="na">getLength</code><code class="o">();</code> <code class="n">i</code><code class="o">++</code> <code class="o">)</code>
<code class="k">if</code> <code class="o">(</code> <code class="n">elements</code><code class="o">.</code><code class="na">item</code><code class="o">(</code><code class="n">i</code><code class="o">)</code> <code class="k">instanceof</code> <code class="n">Element</code> <code class="o">)</code> <code class="o">{</code>
<code class="n">printXML</code><code class="o">(</code> <code class="o">(</code><code class="n">Element</code><code class="o">)</code><code class="n">elements</code><code class="o">.</code><code class="na">item</code><code class="o">(</code><code class="n">i</code><code class="o">)</code> <code class="o">);</code>
<code class="o">}</code> <code class="k">else</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code> <code class="n">elements</code><code class="o">.</code><code class="na">item</code><code class="o">(</code><code class="n">i</code><code class="o">)</code> <code class="o">);</code>
<code class="o">}</code>
<code class="err"> </code>
<code class="o">}</code></pre><p>There are again a lot of <code class="literal">import</code>s in this example. The transform code in
our <code class="literal">printXML()</code> method is drawn from
the <code class="literal">PrintDOM</code> example with one
addition. We’ve set a property on the transformer to omit the standard
XML declaration that would normally be output for us at the head of our
document. Since we may print more than one (root) element, the output is
not well formed XML anyway.</p><p>Run the example by passing an XPath expression and the name of an
XML file as arguments:</p><a id="I_24_tt1325"/><pre class="programlisting"><code class="o">%</code> <strong class="userinput"><code><code class="n">java</code> <code class="n">XMLGrep</code> <code class="s">"//animal[starts-with(name,'C')]"</code> <code class="n">zooinventory</code><code class="o">.</code><code class="na">xml</code></code></strong></pre><p>This example really is useful for trying out XPath. Please give it
a whirl. Mastering these expressions (and learning more) will give you
great power over XML documents and, again, form the basis for learning
about XSL transformations.<a id="I_indexterm24_id832771" class="indexterm"/><a id="I_indexterm24_id832778" class="indexterm"/><a id="I_indexterm24_id832785" class="indexterm"/></p></div></div></body></html>