UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

180 lines (178 loc) 30.3 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <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">&lt;animal&gt;...&lt;/animal&gt;</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">=!=&gt;&lt;</code> </p></td><td style="text-align: left"><p> <code class="literal">//animal[weight &gt; 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 &gt; 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)&gt;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">&lt;</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>