Imported Upstream version 2.3.5
[platform/upstream/python-lxml.git] / doc / html / xpathxslt.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <meta name="generator" content="Docutils 0.8.1: http://docutils.sourceforge.net/" />
6 <title>XPath and XSLT with lxml</title>
7 <link rel="stylesheet" href="style.css" type="text/css" />
8 </head>
9 <body>
10 <div class="document" id="xpath-and-xslt-with-lxml">
11 <div class="sidemenu"><ul id="lxml-section"><li><span class="section title">lxml</span><ul class="menu foreign" id="index-menu"><li class="menu title"><a href="index.html">lxml</a><ul class="submenu"><li class="menu item"><a href="index.html#introduction">Introduction</a></li><li class="menu item"><a href="index.html#support-the-project">Support the project</a></li><li class="menu item"><a href="index.html#documentation">Documentation</a></li><li class="menu item"><a href="index.html#download">Download</a></li><li class="menu item"><a href="index.html#mailing-list">Mailing list</a></li><li class="menu item"><a href="index.html#bug-tracker">Bug tracker</a></li><li class="menu item"><a href="index.html#license">License</a></li><li class="menu item"><a href="index.html#old-versions">Old Versions</a></li><li class="menu item"><a href="index.html#legal-notice-for-donations">Legal Notice for Donations</a></li></ul></li></ul><ul class="menu foreign" id="intro-menu"><li class="menu title"><a href="intro.html">Why lxml?</a><ul class="submenu"><li class="menu item"><a href="intro.html#motto">Motto</a></li><li class="menu item"><a href="intro.html#aims">Aims</a></li></ul></li></ul><ul class="menu foreign" id="installation-menu"><li class="menu title"><a href="installation.html">Installing lxml</a><ul class="submenu"><li class="menu item"><a href="installation.html#requirements">Requirements</a></li><li class="menu item"><a href="installation.html#installation">Installation</a></li><li class="menu item"><a href="installation.html#building-lxml-from-sources">Building lxml from sources</a></li><li class="menu item"><a href="installation.html#using-lxml-with-python-libxml2">Using lxml with python-libxml2</a></li><li class="menu item"><a href="installation.html#ms-windows">MS Windows</a></li><li class="menu item"><a href="installation.html#macos-x">MacOS-X</a></li></ul></li></ul><ul class="menu foreign" id="performance-menu"><li class="menu title"><a href="performance.html">Benchmarks and Speed</a><ul class="submenu"><li class="menu item"><a href="performance.html#general-notes">General notes</a></li><li class="menu item"><a href="performance.html#how-to-read-the-timings">How to read the timings</a></li><li class="menu item"><a href="performance.html#parsing-and-serialising">Parsing and Serialising</a></li><li class="menu item"><a href="performance.html#the-elementtree-api">The ElementTree API</a></li><li class="menu item"><a href="performance.html#xpath">XPath</a></li><li class="menu item"><a href="performance.html#a-longer-example">A longer example</a></li><li class="menu item"><a href="performance.html#lxml-objectify">lxml.objectify</a></li></ul></li></ul><ul class="menu foreign" id="compatibility-menu"><li class="menu title"><a href="compatibility.html">ElementTree compatibility of lxml.etree</a></li></ul><ul class="menu foreign" id="FAQ-menu"><li class="menu title"><a href="FAQ.html">lxml FAQ - Frequently Asked Questions</a><ul class="submenu"><li class="menu item"><a href="FAQ.html#general-questions">General Questions</a></li><li class="menu item"><a href="FAQ.html#installation">Installation</a></li><li class="menu item"><a href="FAQ.html#contributing">Contributing</a></li><li class="menu item"><a href="FAQ.html#bugs">Bugs</a></li><li class="menu item"><a href="FAQ.html#id1">Threading</a></li><li class="menu item"><a href="FAQ.html#parsing-and-serialisation">Parsing and Serialisation</a></li><li class="menu item"><a href="FAQ.html#xpath-and-document-traversal">XPath and Document Traversal</a></li></ul></li></ul></li></ul><ul id="Developing with lxml-section"><li><span class="section title">Developing with lxml</span><ul class="menu foreign" id="tutorial-menu"><li class="menu title"><a href="tutorial.html">The lxml.etree Tutorial</a><ul class="submenu"><li class="menu item"><a href="tutorial.html#the-element-class">The Element class</a></li><li class="menu item"><a href="tutorial.html#the-elementtree-class">The ElementTree class</a></li><li class="menu item"><a href="tutorial.html#parsing-from-strings-and-files">Parsing from strings and files</a></li><li class="menu item"><a href="tutorial.html#namespaces">Namespaces</a></li><li class="menu item"><a href="tutorial.html#the-e-factory">The E-factory</a></li><li class="menu item"><a href="tutorial.html#elementpath">ElementPath</a></li></ul></li></ul><ul class="menu foreign" id="api index-menu"><li class="menu title"><a href="api/index.html">API reference</a></li></ul><ul class="menu foreign" id="api-menu"><li class="menu title"><a href="api.html">APIs specific to lxml.etree</a><ul class="submenu"><li class="menu item"><a href="api.html#lxml-etree">lxml.etree</a></li><li class="menu item"><a href="api.html#other-element-apis">Other Element APIs</a></li><li class="menu item"><a href="api.html#trees-and-documents">Trees and Documents</a></li><li class="menu item"><a href="api.html#iteration">Iteration</a></li><li class="menu item"><a href="api.html#error-handling-on-exceptions">Error handling on exceptions</a></li><li class="menu item"><a href="api.html#error-logging">Error logging</a></li><li class="menu item"><a href="api.html#serialisation">Serialisation</a></li><li class="menu item"><a href="api.html#cdata">CDATA</a></li><li class="menu item"><a href="api.html#xinclude-and-elementinclude">XInclude and ElementInclude</a></li><li class="menu item"><a href="api.html#write-c14n-on-elementtree">write_c14n on ElementTree</a></li></ul></li></ul><ul class="menu foreign" id="parsing-menu"><li class="menu title"><a href="parsing.html">Parsing XML and HTML with lxml</a><ul class="submenu"><li class="menu item"><a href="parsing.html#parsers">Parsers</a></li><li class="menu item"><a href="parsing.html#the-target-parser-interface">The target parser interface</a></li><li class="menu item"><a href="parsing.html#the-feed-parser-interface">The feed parser interface</a></li><li class="menu item"><a href="parsing.html#iterparse-and-iterwalk">iterparse and iterwalk</a></li><li class="menu item"><a href="parsing.html#python-unicode-strings">Python unicode strings</a></li></ul></li></ul><ul class="menu foreign" id="validation-menu"><li class="menu title"><a href="validation.html">Validation with lxml</a><ul class="submenu"><li class="menu item"><a href="validation.html#validation-at-parse-time">Validation at parse time</a></li><li class="menu item"><a href="validation.html#id1">DTD</a></li><li class="menu item"><a href="validation.html#relaxng">RelaxNG</a></li><li class="menu item"><a href="validation.html#xmlschema">XMLSchema</a></li><li class="menu item"><a href="validation.html#id2">Schematron</a></li><li class="menu item"><a href="validation.html#id3">(Pre-ISO-Schematron)</a></li></ul></li></ul><ul class="menu current" id="xpathxslt-menu"><li class="menu title"><a href="xpathxslt.html">XPath and XSLT with lxml</a><ul class="submenu"><li class="menu item"><a href="xpathxslt.html#xpath">XPath</a></li><li class="menu item"><a href="xpathxslt.html#xslt">XSLT</a></li></ul></li></ul><ul class="menu foreign" id="objectify-menu"><li class="menu title"><a href="objectify.html">lxml.objectify</a><ul class="submenu"><li class="menu item"><a href="objectify.html#the-lxml-objectify-api">The lxml.objectify API</a></li><li class="menu item"><a href="objectify.html#asserting-a-schema">Asserting a Schema</a></li><li class="menu item"><a href="objectify.html#objectpath">ObjectPath</a></li><li class="menu item"><a href="objectify.html#python-data-types">Python data types</a></li><li class="menu item"><a href="objectify.html#how-data-types-are-matched">How data types are matched</a></li><li class="menu item"><a href="objectify.html#what-is-different-from-lxml-etree">What is different from lxml.etree?</a></li></ul></li></ul><ul class="menu foreign" id="lxmlhtml-menu"><li class="menu title"><a href="lxmlhtml.html">lxml.html</a><ul class="submenu"><li class="menu item"><a href="lxmlhtml.html#parsing-html">Parsing HTML</a></li><li class="menu item"><a href="lxmlhtml.html#html-element-methods">HTML Element Methods</a></li><li class="menu item"><a href="lxmlhtml.html#running-html-doctests">Running HTML doctests</a></li><li class="menu item"><a href="lxmlhtml.html#creating-html-with-the-e-factory">Creating HTML with the E-factory</a></li><li class="menu item"><a href="lxmlhtml.html#working-with-links">Working with links</a></li><li class="menu item"><a href="lxmlhtml.html#forms">Forms</a></li><li class="menu item"><a href="lxmlhtml.html#cleaning-up-html">Cleaning up HTML</a></li><li class="menu item"><a href="lxmlhtml.html#html-diff">HTML Diff</a></li><li class="menu item"><a href="lxmlhtml.html#examples">Examples</a></li></ul></li></ul><ul class="menu foreign" id="cssselect-menu"><li class="menu title"><a href="cssselect.html">lxml.cssselect</a><ul class="submenu"><li class="menu item"><a href="cssselect.html#the-cssselector-class">The CSSSelector class</a></li><li class="menu item"><a href="cssselect.html#css-selectors">CSS Selectors</a></li><li class="menu item"><a href="cssselect.html#namespaces">Namespaces</a></li><li class="menu item"><a href="cssselect.html#limitations">Limitations</a></li></ul></li></ul><ul class="menu foreign" id="elementsoup-menu"><li class="menu title"><a href="elementsoup.html">BeautifulSoup Parser</a><ul class="submenu"><li class="menu item"><a href="elementsoup.html#parsing-with-the-soupparser">Parsing with the soupparser</a></li><li class="menu item"><a href="elementsoup.html#entity-handling">Entity handling</a></li><li class="menu item"><a href="elementsoup.html#using-soupparser-as-a-fallback">Using soupparser as a fallback</a></li><li class="menu item"><a href="elementsoup.html#using-only-the-encoding-detection">Using only the encoding detection</a></li></ul></li></ul><ul class="menu foreign" id="html5parser-menu"><li class="menu title"><a href="html5parser.html">html5lib Parser</a><ul class="submenu"><li class="menu item"><a href="html5parser.html#differences-to-regular-html-parsing">Differences to regular HTML parsing</a></li><li class="menu item"><a href="html5parser.html#function-reference">Function Reference</a></li></ul></li></ul></li></ul><ul id="Extending lxml-section"><li><span class="section title">Extending lxml</span><ul class="menu foreign" id="resolvers-menu"><li class="menu title"><a href="resolvers.html">Document loading and URL resolving</a><ul class="submenu"><li class="menu item"><a href="resolvers.html#xml-catalogs">XML Catalogs</a></li><li class="menu item"><a href="resolvers.html#uri-resolvers">URI Resolvers</a></li><li class="menu item"><a href="resolvers.html#document-loading-in-context">Document loading in context</a></li><li class="menu item"><a href="resolvers.html#i-o-access-control-in-xslt">I/O access control in XSLT</a></li></ul></li></ul><ul class="menu foreign" id="extensions-menu"><li class="menu title"><a href="extensions.html">Python extensions for XPath and XSLT</a><ul class="submenu"><li class="menu item"><a href="extensions.html#xpath-extension-functions">XPath Extension functions</a></li><li class="menu item"><a href="extensions.html#xslt-extension-elements">XSLT extension elements</a></li></ul></li></ul><ul class="menu foreign" id="element classes-menu"><li class="menu title"><a href="element_classes.html">Using custom Element classes in lxml</a><ul class="submenu"><li class="menu item"><a href="element_classes.html#background-on-element-proxies">Background on Element proxies</a></li><li class="menu item"><a href="element_classes.html#element-initialization">Element initialization</a></li><li class="menu item"><a href="element_classes.html#setting-up-a-class-lookup-scheme">Setting up a class lookup scheme</a></li><li class="menu item"><a href="element_classes.html#generating-xml-with-custom-classes">Generating XML with custom classes</a></li><li class="menu item"><a href="element_classes.html#id1">Implementing namespaces</a></li></ul></li></ul><ul class="menu foreign" id="sax-menu"><li class="menu title"><a href="sax.html">Sax support</a><ul class="submenu"><li class="menu item"><a href="sax.html#building-a-tree-from-sax-events">Building a tree from SAX events</a></li><li class="menu item"><a href="sax.html#producing-sax-events-from-an-elementtree-or-element">Producing SAX events from an ElementTree or Element</a></li><li class="menu item"><a href="sax.html#interfacing-with-pulldom-minidom">Interfacing with pulldom/minidom</a></li></ul></li></ul><ul class="menu foreign" id="capi-menu"><li class="menu title"><a href="capi.html">The public C-API of lxml.etree</a><ul class="submenu"><li class="menu item"><a href="capi.html#writing-external-modules-in-cython">Writing external modules in Cython</a></li><li class="menu item"><a href="capi.html#writing-external-modules-in-c">Writing external modules in C</a></li></ul></li></ul></li></ul><ul id="Developing lxml-section"><li><span class="section title">Developing lxml</span><ul class="menu foreign" id="build-menu"><li class="menu title"><a href="build.html">How to build lxml from source</a><ul class="submenu"><li class="menu item"><a href="build.html#cython">Cython</a></li><li class="menu item"><a href="build.html#github-git-and-hg">Github, git and hg</a></li><li class="menu item"><a href="build.html#id2">Setuptools</a></li><li class="menu item"><a href="build.html#running-the-tests-and-reporting-errors">Running the tests and reporting errors</a></li><li class="menu item"><a href="build.html#building-an-egg">Building an egg</a></li><li class="menu item"><a href="build.html#building-lxml-on-macos-x">Building lxml on MacOS-X</a></li><li class="menu item"><a href="build.html#static-linking-on-windows">Static linking on Windows</a></li><li class="menu item"><a href="build.html#building-debian-packages-from-svn-sources">Building Debian packages from SVN sources</a></li></ul></li></ul><ul class="menu foreign" id="lxml source howto-menu"><li class="menu title"><a href="lxml-source-howto.html">How to read the source of lxml</a><ul class="submenu"><li class="menu item"><a href="lxml-source-howto.html#what-is-cython">What is Cython?</a></li><li class="menu item"><a href="lxml-source-howto.html#where-to-start">Where to start?</a></li><li class="menu item"><a href="lxml-source-howto.html#lxml-etree">lxml.etree</a></li><li class="menu item"><a href="lxml-source-howto.html#python-modules">Python modules</a></li><li class="menu item"><a href="lxml-source-howto.html#lxml-objectify">lxml.objectify</a></li><li class="menu item"><a href="lxml-source-howto.html#lxml-html">lxml.html</a></li></ul></li></ul><ul class="menu foreign" id="changes 2 3 5-menu"><li class="menu title"><a href="changes-2.3.5.html">Release Changelog</a></li></ul><ul class="menu foreign" id="credits-menu"><li class="menu title"><a href="credits.html">Credits</a><ul class="submenu"><li class="menu item"><a href="credits.html#main-contributors">Main contributors</a></li><li class="menu item"><a href="credits.html#special-thanks-goes-to">Special thanks goes to:</a></li></ul></li></ul></li><li><a href="http://lxml.de/sitemap.html">Sitemap</a></li></ul></div><h1 class="title">XPath and XSLT with lxml</h1>
12
13 <p>lxml supports XPath 1.0, XSLT 1.0 and the EXSLT extensions through
14 libxml2 and libxslt in a standards compliant way.</p>
15 <div class="contents topic" id="contents">
16 <p class="topic-title first">Contents</p>
17 <ul class="simple">
18 <li><a class="reference internal" href="#xpath" id="id1">XPath</a><ul>
19 <li><a class="reference internal" href="#the-xpath-method" id="id2">The <tt class="docutils literal">xpath()</tt> method</a></li>
20 <li><a class="reference internal" href="#namespaces-and-prefixes" id="id3">Namespaces and prefixes</a></li>
21 <li><a class="reference internal" href="#xpath-return-values" id="id4">XPath return values</a></li>
22 <li><a class="reference internal" href="#generating-xpath-expressions" id="id5">Generating XPath expressions</a></li>
23 <li><a class="reference internal" href="#the-xpath-class" id="id6">The <tt class="docutils literal">XPath</tt> class</a></li>
24 <li><a class="reference internal" href="#regular-expressions-in-xpath" id="id7">Regular expressions in XPath</a></li>
25 <li><a class="reference internal" href="#the-xpathevaluator-classes" id="id8">The <tt class="docutils literal">XPathEvaluator</tt> classes</a></li>
26 <li><a class="reference internal" href="#etxpath" id="id9"><tt class="docutils literal">ETXPath</tt></a></li>
27 <li><a class="reference internal" href="#error-handling" id="id10">Error handling</a></li>
28 </ul>
29 </li>
30 <li><a class="reference internal" href="#xslt" id="id11">XSLT</a><ul>
31 <li><a class="reference internal" href="#xslt-result-objects" id="id12">XSLT result objects</a></li>
32 <li><a class="reference internal" href="#stylesheet-parameters" id="id13">Stylesheet parameters</a></li>
33 <li><a class="reference internal" href="#errors-and-messages" id="id14">Errors and messages</a></li>
34 <li><a class="reference internal" href="#the-xslt-tree-method" id="id15">The <tt class="docutils literal">xslt()</tt> tree method</a></li>
35 <li><a class="reference internal" href="#dealing-with-stylesheet-complexity" id="id16">Dealing with stylesheet complexity</a></li>
36 <li><a class="reference internal" href="#profiling" id="id17">Profiling</a></li>
37 </ul>
38 </li>
39 </ul>
40 </div>
41 <p>The usual setup procedure:</p>
42 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">lxml</span> <span class="kn">import</span> <span class="n">etree</span>
43 </pre></div>
44 <div class="section" id="xpath">
45 <h1>XPath</h1>
46 <p>lxml.etree supports the simple path syntax of the <a class="reference external" href="http://effbot.org/zone/element.htm#searching-for-subelements">find, findall and
47 findtext</a> methods on ElementTree and Element, as known from the original
48 ElementTree library (<a class="reference external" href="http://effbot.org/zone/element-xpath.htm">ElementPath</a>).  As an lxml specific extension, these
49 classes also provide an <tt class="docutils literal">xpath()</tt> method that supports expressions in the
50 complete XPath syntax, as well as <a class="reference external" href="extensions.html#xpath-extension-functions">custom extension functions</a>.</p>
51 <p>There are also specialized XPath evaluator classes that are more efficient for
52 frequent evaluation: <tt class="docutils literal">XPath</tt> and <tt class="docutils literal">XPathEvaluator</tt>.  See the <a class="reference external" href="performance.html#xpath">performance
53 comparison</a> to learn when to use which.  Their semantics when used on
54 Elements and ElementTrees are the same as for the <tt class="docutils literal">xpath()</tt> method described
55 here.</p>
56 <div class="section" id="the-xpath-method">
57 <h2>The <tt class="docutils literal">xpath()</tt> method</h2>
58 <p>For ElementTree, the xpath method performs a global XPath query against the
59 document (if absolute) or against the root node (if relative):</p>
60 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">f</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">(</span><span class="s">'&lt;foo&gt;&lt;bar&gt;&lt;/bar&gt;&lt;/foo&gt;'</span><span class="p">)</span>
61 <span class="gp">&gt;&gt;&gt; </span><span class="n">tree</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
62
63 <span class="gp">&gt;&gt;&gt; </span><span class="n">r</span> <span class="o">=</span> <span class="n">tree</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="s">'/foo/bar'</span><span class="p">)</span>
64 <span class="gp">&gt;&gt;&gt; </span><span class="nb">len</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
65 <span class="go">1</span>
66 <span class="gp">&gt;&gt;&gt; </span><span class="n">r</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">tag</span>
67 <span class="go">'bar'</span>
68
69 <span class="gp">&gt;&gt;&gt; </span><span class="n">r</span> <span class="o">=</span> <span class="n">tree</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="s">'bar'</span><span class="p">)</span>
70 <span class="gp">&gt;&gt;&gt; </span><span class="n">r</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">tag</span>
71 <span class="go">'bar'</span>
72 </pre></div>
73 <p>When <tt class="docutils literal">xpath()</tt> is used on an Element, the XPath expression is evaluated
74 against the element (if relative) or against the root tree (if absolute):</p>
75 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">root</span> <span class="o">=</span> <span class="n">tree</span><span class="o">.</span><span class="n">getroot</span><span class="p">()</span>
76 <span class="gp">&gt;&gt;&gt; </span><span class="n">r</span> <span class="o">=</span> <span class="n">root</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="s">'bar'</span><span class="p">)</span>
77 <span class="gp">&gt;&gt;&gt; </span><span class="n">r</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">tag</span>
78 <span class="go">'bar'</span>
79
80 <span class="gp">&gt;&gt;&gt; </span><span class="n">bar</span> <span class="o">=</span> <span class="n">root</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
81 <span class="gp">&gt;&gt;&gt; </span><span class="n">r</span> <span class="o">=</span> <span class="n">bar</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="s">'/foo/bar'</span><span class="p">)</span>
82 <span class="gp">&gt;&gt;&gt; </span><span class="n">r</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">tag</span>
83 <span class="go">'bar'</span>
84
85 <span class="gp">&gt;&gt;&gt; </span><span class="n">tree</span> <span class="o">=</span> <span class="n">bar</span><span class="o">.</span><span class="n">getroottree</span><span class="p">()</span>
86 <span class="gp">&gt;&gt;&gt; </span><span class="n">r</span> <span class="o">=</span> <span class="n">tree</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="s">'/foo/bar'</span><span class="p">)</span>
87 <span class="gp">&gt;&gt;&gt; </span><span class="n">r</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">tag</span>
88 <span class="go">'bar'</span>
89 </pre></div>
90 <p>The <tt class="docutils literal">xpath()</tt> method has support for XPath variables:</p>
91 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">expr</span> <span class="o">=</span> <span class="s">"//*[local-name() = $name]"</span>
92
93 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="n">expr</span><span class="p">,</span> <span class="n">name</span> <span class="o">=</span> <span class="s">"foo"</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">tag</span><span class="p">)</span>
94 <span class="go">foo</span>
95
96 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="n">expr</span><span class="p">,</span> <span class="n">name</span> <span class="o">=</span> <span class="s">"bar"</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">tag</span><span class="p">)</span>
97 <span class="go">bar</span>
98
99 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="s">"$text"</span><span class="p">,</span> <span class="n">text</span> <span class="o">=</span> <span class="s">"Hello World!"</span><span class="p">))</span>
100 <span class="go">Hello World!</span>
101 </pre></div>
102 </div>
103 <div class="section" id="namespaces-and-prefixes">
104 <h2>Namespaces and prefixes</h2>
105 <p>If your XPath expression uses namespace prefixes, you must define them
106 in a prefix mapping.  To this end, pass a dictionary to the
107 <tt class="docutils literal">namespaces</tt> keyword argument that maps the namespace prefixes used
108 in the XPath expression to namespace URIs:</p>
109 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">f</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">(</span><span class="s">'''</span><span class="se">\</span>
110 <span class="gp">... </span><span class="s">&lt;a:foo xmlns:a="http://codespeak.net/ns/test1"</span>
111 <span class="gp">... </span><span class="s">       xmlns:b="http://codespeak.net/ns/test2"&gt;</span>
112 <span class="gp">... </span><span class="s">   &lt;b:bar&gt;Text&lt;/b:bar&gt;</span>
113 <span class="gp">... </span><span class="s">&lt;/a:foo&gt;</span>
114 <span class="gp">... </span><span class="s">'''</span><span class="p">)</span>
115 <span class="gp">&gt;&gt;&gt; </span><span class="n">doc</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
116
117 <span class="gp">&gt;&gt;&gt; </span><span class="n">r</span> <span class="o">=</span> <span class="n">doc</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="s">'/t:foo/b:bar'</span><span class="p">,</span>
118 <span class="gp">... </span>              <span class="n">namespaces</span><span class="o">=</span><span class="p">{</span><span class="s">'t'</span><span class="p">:</span> <span class="s">'http://codespeak.net/ns/test1'</span><span class="p">,</span>
119 <span class="gp">... </span>                          <span class="s">'b'</span><span class="p">:</span> <span class="s">'http://codespeak.net/ns/test2'</span><span class="p">})</span>
120 <span class="gp">&gt;&gt;&gt; </span><span class="nb">len</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
121 <span class="go">1</span>
122 <span class="gp">&gt;&gt;&gt; </span><span class="n">r</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">tag</span>
123 <span class="go">'{http://codespeak.net/ns/test2}bar'</span>
124 <span class="gp">&gt;&gt;&gt; </span><span class="n">r</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">text</span>
125 <span class="go">'Text'</span>
126 </pre></div>
127 <p>The prefixes you choose here are not linked to the prefixes used
128 inside the XML document.  The document may define whatever prefixes it
129 likes, including the empty prefix, without breaking the above code.</p>
130 <p>Note that XPath does not have a notion of a default namespace.  The
131 empty prefix is therefore undefined for XPath and cannot be used in
132 namespace prefix mappings.</p>
133 <p>There is also an optional <tt class="docutils literal">extensions</tt> argument which is used to
134 define <a class="reference external" href="extensions.html#xpath-extension-functions">custom extension functions</a> in Python that are local to this
135 evaluation.  The namespace prefixes that they use in the XPath
136 expression must also be defined in the namespace prefix mapping.</p>
137 </div>
138 <div class="section" id="xpath-return-values">
139 <h2>XPath return values</h2>
140 <p>The return value types of XPath evaluations vary, depending on the
141 XPath expression used:</p>
142 <ul class="simple">
143 <li>True or False, when the XPath expression has a boolean result</li>
144 <li>a float, when the XPath expression has a numeric result (integer or float)</li>
145 <li>a 'smart' string (as described below), when the XPath expression has
146 a string result.</li>
147 <li>a list of items, when the XPath expression has a list as result.
148 The items may include Elements (also comments and processing
149 instructions), strings and tuples.  Text nodes and attributes in the
150 result are returned as 'smart' string values.  Namespace
151 declarations are returned as tuples of strings: <tt class="docutils literal">(prefix, URI)</tt>.</li>
152 </ul>
153 <p>XPath string results are 'smart' in that they provide a
154 <tt class="docutils literal">getparent()</tt> method that knows their origin:</p>
155 <ul class="simple">
156 <li>for attribute values, <tt class="docutils literal">result.getparent()</tt> returns the Element
157 that carries them.  An example is <tt class="docutils literal"><span class="pre">//foo/@attribute</span></tt>, where the
158 parent would be a <tt class="docutils literal">foo</tt> Element.</li>
159 <li>for the <tt class="docutils literal">text()</tt> function (as in <tt class="docutils literal">//text()</tt>), it returns the
160 Element that contains the text or tail that was returned.</li>
161 </ul>
162 <p>You can distinguish between different text origins with the boolean
163 properties <tt class="docutils literal">is_text</tt>, <tt class="docutils literal">is_tail</tt> and <tt class="docutils literal">is_attribute</tt>.</p>
164 <p>Note that <tt class="docutils literal">getparent()</tt> may not always return an Element.  For
165 example, the XPath functions <tt class="docutils literal">string()</tt> and <tt class="docutils literal">concat()</tt> will
166 construct strings that do not have an origin.  For them,
167 <tt class="docutils literal">getparent()</tt> will return None.</p>
168 <p>There are certain cases where the smart string behaviour is
169 undesirable.  For example, it means that the tree will be kept alive
170 by the string, which may have a considerable memory impact in the case
171 that the string value is the only thing in the tree that is actually
172 of interest.  For these cases, you can deactivate the parental
173 relationship using the keyword argument <tt class="docutils literal">smart_strings</tt>.</p>
174 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">root</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="s">"&lt;root&gt;&lt;a&gt;TEXT&lt;/a&gt;&lt;/root&gt;"</span><span class="p">)</span>
175
176 <span class="gp">&gt;&gt;&gt; </span><span class="n">find_text</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XPath</span><span class="p">(</span><span class="s">"//text()"</span><span class="p">)</span>
177 <span class="gp">&gt;&gt;&gt; </span><span class="n">text</span> <span class="o">=</span> <span class="n">find_text</span><span class="p">(</span><span class="n">root</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
178 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
179 <span class="go">TEXT</span>
180 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">text</span><span class="o">.</span><span class="n">getparent</span><span class="p">()</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
181 <span class="go">TEXT</span>
182
183 <span class="gp">&gt;&gt;&gt; </span><span class="n">find_text</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XPath</span><span class="p">(</span><span class="s">"//text()"</span><span class="p">,</span> <span class="n">smart_strings</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
184 <span class="gp">&gt;&gt;&gt; </span><span class="n">text</span> <span class="o">=</span> <span class="n">find_text</span><span class="p">(</span><span class="n">root</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
185 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
186 <span class="go">TEXT</span>
187 <span class="gp">&gt;&gt;&gt; </span><span class="nb">hasattr</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="s">'getparent'</span><span class="p">)</span>
188 <span class="go">False</span>
189 </pre></div>
190 </div>
191 <div class="section" id="generating-xpath-expressions">
192 <h2>Generating XPath expressions</h2>
193 <p>ElementTree objects have a method <tt class="docutils literal">getpath(element)</tt>, which returns a
194 structural, absolute XPath expression to find that element:</p>
195 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">a</span>  <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">Element</span><span class="p">(</span><span class="s">"a"</span><span class="p">)</span>
196 <span class="gp">&gt;&gt;&gt; </span><span class="n">b</span>  <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">SubElement</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="s">"b"</span><span class="p">)</span>
197 <span class="gp">&gt;&gt;&gt; </span><span class="n">c</span>  <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">SubElement</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="s">"c"</span><span class="p">)</span>
198 <span class="gp">&gt;&gt;&gt; </span><span class="n">d1</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">SubElement</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="s">"d"</span><span class="p">)</span>
199 <span class="gp">&gt;&gt;&gt; </span><span class="n">d2</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">SubElement</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="s">"d"</span><span class="p">)</span>
200
201 <span class="gp">&gt;&gt;&gt; </span><span class="n">tree</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">ElementTree</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
202 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">tree</span><span class="o">.</span><span class="n">getpath</span><span class="p">(</span><span class="n">d2</span><span class="p">))</span>
203 <span class="go">/c/d[2]</span>
204 <span class="gp">&gt;&gt;&gt; </span><span class="n">tree</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="n">tree</span><span class="o">.</span><span class="n">getpath</span><span class="p">(</span><span class="n">d2</span><span class="p">))</span> <span class="o">==</span> <span class="p">[</span><span class="n">d2</span><span class="p">]</span>
205 <span class="go">True</span>
206 </pre></div>
207 </div>
208 <div class="section" id="the-xpath-class">
209 <h2>The <tt class="docutils literal">XPath</tt> class</h2>
210 <p>The <tt class="docutils literal">XPath</tt> class compiles an XPath expression into a callable function:</p>
211 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">root</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="s">"&lt;root&gt;&lt;a&gt;&lt;b/&gt;&lt;/a&gt;&lt;b/&gt;&lt;/root&gt;"</span><span class="p">)</span>
212
213 <span class="gp">&gt;&gt;&gt; </span><span class="n">find</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XPath</span><span class="p">(</span><span class="s">"//b"</span><span class="p">)</span>
214 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">find</span><span class="p">(</span><span class="n">root</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">tag</span><span class="p">)</span>
215 <span class="go">b</span>
216 </pre></div>
217 <p>The compilation takes as much time as in the <tt class="docutils literal">xpath()</tt> method, but it is
218 done only once per class instantiation.  This makes it especially efficient
219 for repeated evaluation of the same XPath expression.</p>
220 <p>Just like the <tt class="docutils literal">xpath()</tt> method, the <tt class="docutils literal">XPath</tt> class supports XPath
221 variables:</p>
222 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">count_elements</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XPath</span><span class="p">(</span><span class="s">"count(//*[local-name() = $name])"</span><span class="p">)</span>
223
224 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">count_elements</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">name</span> <span class="o">=</span> <span class="s">"a"</span><span class="p">))</span>
225 <span class="go">1.0</span>
226 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">count_elements</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">name</span> <span class="o">=</span> <span class="s">"b"</span><span class="p">))</span>
227 <span class="go">2.0</span>
228 </pre></div>
229 <p>This supports very efficient evaluation of modified versions of an XPath
230 expression, as compilation is still only required once.</p>
231 <p>Prefix-to-namespace mappings can be passed as second parameter:</p>
232 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">root</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="s">"&lt;root xmlns='NS'&gt;&lt;a&gt;&lt;b/&gt;&lt;/a&gt;&lt;b/&gt;&lt;/root&gt;"</span><span class="p">)</span>
233
234 <span class="gp">&gt;&gt;&gt; </span><span class="n">find</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XPath</span><span class="p">(</span><span class="s">"//n:b"</span><span class="p">,</span> <span class="n">namespaces</span><span class="o">=</span><span class="p">{</span><span class="s">'n'</span><span class="p">:</span><span class="s">'NS'</span><span class="p">})</span>
235 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">find</span><span class="p">(</span><span class="n">root</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">tag</span><span class="p">)</span>
236 <span class="go">{NS}b</span>
237 </pre></div>
238 </div>
239 <div class="section" id="regular-expressions-in-xpath">
240 <h2>Regular expressions in XPath</h2>
241 <p>By default, <tt class="docutils literal">XPath</tt> supports regular expressions in the <a class="reference external" href="http://www.exslt.org/">EXSLT</a> namespace:</p>
242 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">regexpNS</span> <span class="o">=</span> <span class="s">"http://exslt.org/regular-expressions"</span>
243 <span class="gp">&gt;&gt;&gt; </span><span class="n">find</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XPath</span><span class="p">(</span><span class="s">"//*[re:test(., '^abc$', 'i')]"</span><span class="p">,</span>
244 <span class="gp">... </span>                   <span class="n">namespaces</span><span class="o">=</span><span class="p">{</span><span class="s">'re'</span><span class="p">:</span><span class="n">regexpNS</span><span class="p">})</span>
245
246 <span class="gp">&gt;&gt;&gt; </span><span class="n">root</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="s">"&lt;root&gt;&lt;a&gt;aB&lt;/a&gt;&lt;b&gt;aBc&lt;/b&gt;&lt;/root&gt;"</span><span class="p">)</span>
247 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">find</span><span class="p">(</span><span class="n">root</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
248 <span class="go">aBc</span>
249 </pre></div>
250 <p>You can disable this with the boolean keyword argument <tt class="docutils literal">regexp</tt> which
251 defaults to True.</p>
252 </div>
253 <div class="section" id="the-xpathevaluator-classes">
254 <h2>The <tt class="docutils literal">XPathEvaluator</tt> classes</h2>
255 <p>lxml.etree provides two other efficient XPath evaluators that work on
256 ElementTrees or Elements respectively: <tt class="docutils literal">XPathDocumentEvaluator</tt> and
257 <tt class="docutils literal">XPathElementEvaluator</tt>.  They are automatically selected if you use the
258 XPathEvaluator helper for instantiation:</p>
259 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">root</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="s">"&lt;root&gt;&lt;a&gt;&lt;b/&gt;&lt;/a&gt;&lt;b/&gt;&lt;/root&gt;"</span><span class="p">)</span>
260 <span class="gp">&gt;&gt;&gt; </span><span class="n">xpatheval</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XPathEvaluator</span><span class="p">(</span><span class="n">root</span><span class="p">)</span>
261
262 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">xpatheval</span><span class="p">,</span> <span class="n">etree</span><span class="o">.</span><span class="n">XPathElementEvaluator</span><span class="p">))</span>
263 <span class="go">True</span>
264
265 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">xpatheval</span><span class="p">(</span><span class="s">"//b"</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">tag</span><span class="p">)</span>
266 <span class="go">b</span>
267 </pre></div>
268 <p>This class provides efficient support for evaluating different XPath
269 expressions on the same Element or ElementTree.</p>
270 </div>
271 <div class="section" id="etxpath">
272 <h2><tt class="docutils literal">ETXPath</tt></h2>
273 <p>ElementTree supports a language named <a class="reference external" href="http://effbot.org/zone/element-xpath.htm">ElementPath</a> in its <tt class="docutils literal"><span class="pre">find*()</span></tt> methods.
274 One of the main differences between XPath and ElementPath is that the XPath
275 language requires an indirection through prefixes for namespace support,
276 whereas ElementTree uses the Clark notation (<tt class="docutils literal">{ns}name</tt>) to avoid prefixes
277 completely.  The other major difference regards the capabilities of both path
278 languages.  Where XPath supports various sophisticated ways of restricting the
279 result set through functions and boolean expressions, ElementPath only
280 supports pure path traversal without nesting or further conditions.  So, while
281 the ElementPath syntax is self-contained and therefore easier to write and
282 handle, XPath is much more powerful and expressive.</p>
283 <p>lxml.etree bridges this gap through the class <tt class="docutils literal">ETXPath</tt>, which accepts XPath
284 expressions with namespaces in Clark notation.  It is identical to the
285 <tt class="docutils literal">XPath</tt> class, except for the namespace notation.  Normally, you would
286 write:</p>
287 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">root</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="s">"&lt;root xmlns='ns'&gt;&lt;a&gt;&lt;b/&gt;&lt;/a&gt;&lt;b/&gt;&lt;/root&gt;"</span><span class="p">)</span>
288
289 <span class="gp">&gt;&gt;&gt; </span><span class="n">find</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XPath</span><span class="p">(</span><span class="s">"//p:b"</span><span class="p">,</span> <span class="n">namespaces</span><span class="o">=</span><span class="p">{</span><span class="s">'p'</span> <span class="p">:</span> <span class="s">'ns'</span><span class="p">})</span>
290 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">find</span><span class="p">(</span><span class="n">root</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">tag</span><span class="p">)</span>
291 <span class="go">{ns}b</span>
292 </pre></div>
293 <p><tt class="docutils literal">ETXPath</tt> allows you to change this to:</p>
294 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">find</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">ETXPath</span><span class="p">(</span><span class="s">"//{ns}b"</span><span class="p">)</span>
295 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">find</span><span class="p">(</span><span class="n">root</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">tag</span><span class="p">)</span>
296 <span class="go">{ns}b</span>
297 </pre></div>
298 </div>
299 <div class="section" id="error-handling">
300 <h2>Error handling</h2>
301 <p>lxml.etree raises exceptions when errors occur while parsing or evaluating an
302 XPath expression:</p>
303 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">find</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XPath</span><span class="p">(</span><span class="s">"</span><span class="se">\\</span><span class="s">"</span><span class="p">)</span>
304 <span class="gt">Traceback (most recent call last):</span>
305   <span class="c">...</span>
306 <span class="gr">lxml.etree.XPathSyntaxError</span>: <span class="n">Invalid expression</span>
307 </pre></div>
308 <p>lxml will also try to give you a hint what went wrong, so if you pass a more
309 complex expression, you may get a somewhat more specific error:</p>
310 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">find</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XPath</span><span class="p">(</span><span class="s">"//*[1.1.1]"</span><span class="p">)</span>
311 <span class="gt">Traceback (most recent call last):</span>
312   <span class="c">...</span>
313 <span class="gr">lxml.etree.XPathSyntaxError</span>: <span class="n">Invalid predicate</span>
314 </pre></div>
315 <p>During evaluation, lxml will emit an XPathEvalError on errors:</p>
316 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">find</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XPath</span><span class="p">(</span><span class="s">"//ns:a"</span><span class="p">)</span>
317 <span class="gp">&gt;&gt;&gt; </span><span class="n">find</span><span class="p">(</span><span class="n">root</span><span class="p">)</span>
318 <span class="gt">Traceback (most recent call last):</span>
319   <span class="c">...</span>
320 <span class="gr">lxml.etree.XPathEvalError</span>: <span class="n">Undefined namespace prefix</span>
321 </pre></div>
322 <p>This works for the <tt class="docutils literal">XPath</tt> class, however, the other evaluators (including
323 the <tt class="docutils literal">xpath()</tt> method) are one-shot operations that do parsing and evaluation
324 in one step.  They therefore raise evaluation exceptions in all cases:</p>
325 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">root</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">Element</span><span class="p">(</span><span class="s">"test"</span><span class="p">)</span>
326 <span class="gp">&gt;&gt;&gt; </span><span class="n">find</span> <span class="o">=</span> <span class="n">root</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="s">"//*[1.1.1]"</span><span class="p">)</span>
327 <span class="gt">Traceback (most recent call last):</span>
328   <span class="c">...</span>
329 <span class="gr">lxml.etree.XPathEvalError</span>: <span class="n">Invalid predicate</span>
330
331 <span class="gp">&gt;&gt;&gt; </span><span class="n">find</span> <span class="o">=</span> <span class="n">root</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="s">"//ns:a"</span><span class="p">)</span>
332 <span class="gt">Traceback (most recent call last):</span>
333   <span class="c">...</span>
334 <span class="gr">lxml.etree.XPathEvalError</span>: <span class="n">Undefined namespace prefix</span>
335
336 <span class="gp">&gt;&gt;&gt; </span><span class="n">find</span> <span class="o">=</span> <span class="n">root</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="s">"</span><span class="se">\\</span><span class="s">"</span><span class="p">)</span>
337 <span class="gt">Traceback (most recent call last):</span>
338   <span class="c">...</span>
339 <span class="gr">lxml.etree.XPathEvalError</span>: <span class="n">Invalid expression</span>
340 </pre></div>
341 <p>Note that lxml versions before 1.3 always raised an <tt class="docutils literal">XPathSyntaxError</tt> for
342 all errors, including evaluation errors.  The best way to support older
343 versions is to except on the superclass <tt class="docutils literal">XPathError</tt>.</p>
344 </div>
345 </div>
346 <div class="section" id="xslt">
347 <h1>XSLT</h1>
348 <p>lxml.etree introduces a new class, lxml.etree.XSLT. The class can be
349 given an ElementTree or Element object to construct an XSLT
350 transformer:</p>
351 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">xslt_root</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="s">'''</span><span class="se">\</span>
352 <span class="gp">... </span><span class="s">&lt;xsl:stylesheet version="1.0"</span>
353 <span class="gp">... </span><span class="s">    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;</span>
354 <span class="gp">... </span><span class="s">    &lt;xsl:template match="/"&gt;</span>
355 <span class="gp">... </span><span class="s">        &lt;foo&gt;&lt;xsl:value-of select="/a/b/text()" /&gt;&lt;/foo&gt;</span>
356 <span class="gp">... </span><span class="s">    &lt;/xsl:template&gt;</span>
357 <span class="gp">... </span><span class="s">&lt;/xsl:stylesheet&gt;'''</span><span class="p">)</span>
358 <span class="gp">&gt;&gt;&gt; </span><span class="n">transform</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XSLT</span><span class="p">(</span><span class="n">xslt_root</span><span class="p">)</span>
359 </pre></div>
360 <p>You can then run the transformation on an ElementTree document by simply
361 calling it, and this results in another ElementTree object:</p>
362 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">f</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">(</span><span class="s">'&lt;a&gt;&lt;b&gt;Text&lt;/b&gt;&lt;/a&gt;'</span><span class="p">)</span>
363 <span class="gp">&gt;&gt;&gt; </span><span class="n">doc</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
364 <span class="gp">&gt;&gt;&gt; </span><span class="n">result_tree</span> <span class="o">=</span> <span class="n">transform</span><span class="p">(</span><span class="n">doc</span><span class="p">)</span>
365 </pre></div>
366 <p>By default, XSLT supports all extension functions from libxslt and
367 libexslt as well as Python regular expressions through the <a class="reference external" href="http://www.exslt.org/regexp/">EXSLT
368 regexp functions</a>.  Also see the documentation on <a class="reference external" href="extensions.html#xpath-extension-functions">custom extension
369 functions</a>, <a class="reference external" href="extensions.html#xslt-extension-elements">XSLT extension elements</a> and <a class="reference external" href="resolvers.html">document resolvers</a>.
370 There is a separate section on <a class="reference external" href="resolvers.html#i-o-access-control-in-xslt">controlling access</a> to external
371 documents and resources.</p>
372 <div class="section" id="xslt-result-objects">
373 <h2>XSLT result objects</h2>
374 <p>The result of an XSL transformation can be accessed like a normal ElementTree
375 document:</p>
376 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">root</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="s">'&lt;a&gt;&lt;b&gt;Text&lt;/b&gt;&lt;/a&gt;'</span><span class="p">)</span>
377 <span class="gp">&gt;&gt;&gt; </span><span class="n">result</span> <span class="o">=</span> <span class="n">transform</span><span class="p">(</span><span class="n">root</span><span class="p">)</span>
378
379 <span class="gp">&gt;&gt;&gt; </span><span class="n">result</span><span class="o">.</span><span class="n">getroot</span><span class="p">()</span><span class="o">.</span><span class="n">text</span>
380 <span class="go">'Text'</span>
381 </pre></div>
382 <p>but, as opposed to normal ElementTree objects, can also be turned into an (XML
383 or text) string by applying the str() function:</p>
384 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
385 <span class="go">'&lt;?xml version="1.0"?&gt;\n&lt;foo&gt;Text&lt;/foo&gt;\n'</span>
386 </pre></div>
387 <p>The result is always a plain string, encoded as requested by the
388 <tt class="docutils literal">xsl:output</tt> element in the stylesheet.  If you want a Python unicode string
389 instead, you should set this encoding to <tt class="docutils literal"><span class="pre">UTF-8</span></tt> (unless the <cite>ASCII</cite> default
390 is sufficient).  This allows you to call the builtin <tt class="docutils literal">unicode()</tt> function on
391 the result:</p>
392 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="nb">unicode</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
393 <span class="go">u'&lt;?xml version="1.0"?&gt;\n&lt;foo&gt;Text&lt;/foo&gt;\n'</span>
394 </pre></div>
395 <p>You can use other encodings at the cost of multiple recoding.  Encodings that
396 are not supported by Python will result in an error:</p>
397 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">xslt_tree</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="s">'''</span><span class="se">\</span>
398 <span class="gp">... </span><span class="s">&lt;xsl:stylesheet version="1.0"</span>
399 <span class="gp">... </span><span class="s">    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;</span>
400 <span class="gp">... </span><span class="s">    &lt;xsl:output encoding="UCS4"/&gt;</span>
401 <span class="gp">... </span><span class="s">    &lt;xsl:template match="/"&gt;</span>
402 <span class="gp">... </span><span class="s">        &lt;foo&gt;&lt;xsl:value-of select="/a/b/text()" /&gt;&lt;/foo&gt;</span>
403 <span class="gp">... </span><span class="s">    &lt;/xsl:template&gt;</span>
404 <span class="gp">... </span><span class="s">&lt;/xsl:stylesheet&gt;'''</span><span class="p">)</span>
405 <span class="gp">&gt;&gt;&gt; </span><span class="n">transform</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XSLT</span><span class="p">(</span><span class="n">xslt_tree</span><span class="p">)</span>
406
407 <span class="gp">&gt;&gt;&gt; </span><span class="n">result</span> <span class="o">=</span> <span class="n">transform</span><span class="p">(</span><span class="n">doc</span><span class="p">)</span>
408 <span class="gp">&gt;&gt;&gt; </span><span class="nb">unicode</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
409 <span class="gt">Traceback (most recent call last):</span>
410   <span class="c">...</span>
411 <span class="gr">LookupError: unknown encoding</span>: <span class="n">UCS4</span>
412 </pre></div>
413 </div>
414 <div class="section" id="stylesheet-parameters">
415 <h2>Stylesheet parameters</h2>
416 <p>It is possible to pass parameters, in the form of XPath expressions, to the
417 XSLT template:</p>
418 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">xslt_tree</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="s">'''</span><span class="se">\</span>
419 <span class="gp">... </span><span class="s">&lt;xsl:stylesheet version="1.0"</span>
420 <span class="gp">... </span><span class="s">    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;</span>
421 <span class="gp">... </span><span class="s">    &lt;xsl:param name="a" /&gt;</span>
422 <span class="gp">... </span><span class="s">    &lt;xsl:template match="/"&gt;</span>
423 <span class="gp">... </span><span class="s">        &lt;foo&gt;&lt;xsl:value-of select="$a" /&gt;&lt;/foo&gt;</span>
424 <span class="gp">... </span><span class="s">    &lt;/xsl:template&gt;</span>
425 <span class="gp">... </span><span class="s">&lt;/xsl:stylesheet&gt;'''</span><span class="p">)</span>
426 <span class="gp">&gt;&gt;&gt; </span><span class="n">transform</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XSLT</span><span class="p">(</span><span class="n">xslt_tree</span><span class="p">)</span>
427 <span class="gp">&gt;&gt;&gt; </span><span class="n">doc_root</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="s">'&lt;a&gt;&lt;b&gt;Text&lt;/b&gt;&lt;/a&gt;'</span><span class="p">)</span>
428 </pre></div>
429 <p>The parameters are passed as keyword parameters to the transform call.
430 First, let's try passing in a simple integer expression:</p>
431 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">result</span> <span class="o">=</span> <span class="n">transform</span><span class="p">(</span><span class="n">doc_root</span><span class="p">,</span> <span class="n">a</span><span class="o">=</span><span class="s">"5"</span><span class="p">)</span>
432 <span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
433 <span class="go">'&lt;?xml version="1.0"?&gt;\n&lt;foo&gt;5&lt;/foo&gt;\n'</span>
434 </pre></div>
435 <p>You can use any valid XPath expression as parameter value:</p>
436 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">result</span> <span class="o">=</span> <span class="n">transform</span><span class="p">(</span><span class="n">doc_root</span><span class="p">,</span> <span class="n">a</span><span class="o">=</span><span class="s">"/a/b/text()"</span><span class="p">)</span>
437 <span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
438 <span class="go">'&lt;?xml version="1.0"?&gt;\n&lt;foo&gt;Text&lt;/foo&gt;\n'</span>
439 </pre></div>
440 <p>It's also possible to pass an XPath object as a parameter:</p>
441 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">result</span> <span class="o">=</span> <span class="n">transform</span><span class="p">(</span><span class="n">doc_root</span><span class="p">,</span> <span class="n">a</span><span class="o">=</span><span class="n">etree</span><span class="o">.</span><span class="n">XPath</span><span class="p">(</span><span class="s">"/a/b/text()"</span><span class="p">))</span>
442 <span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
443 <span class="go">'&lt;?xml version="1.0"?&gt;\n&lt;foo&gt;Text&lt;/foo&gt;\n'</span>
444 </pre></div>
445 <p>Passing a string expression looks like this:</p>
446 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">result</span> <span class="o">=</span> <span class="n">transform</span><span class="p">(</span><span class="n">doc_root</span><span class="p">,</span> <span class="n">a</span><span class="o">=</span><span class="s">"'A'"</span><span class="p">)</span>
447 <span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
448 <span class="go">'&lt;?xml version="1.0"?&gt;\n&lt;foo&gt;A&lt;/foo&gt;\n'</span>
449 </pre></div>
450 <p>To pass a string that (potentially) contains quotes, you can use the
451 <tt class="docutils literal">.strparam()</tt> class method.  Note that it does not escape the
452 string.  Instead, it returns an opaque object that keeps the string
453 value.</p>
454 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">plain_string_value</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XSLT</span><span class="o">.</span><span class="n">strparam</span><span class="p">(</span>
455 <span class="gp">... </span>                         <span class="sd">""" It's "Monty Python" """</span><span class="p">)</span>
456 <span class="gp">&gt;&gt;&gt; </span><span class="n">result</span> <span class="o">=</span> <span class="n">transform</span><span class="p">(</span><span class="n">doc_root</span><span class="p">,</span> <span class="n">a</span><span class="o">=</span><span class="n">plain_string_value</span><span class="p">)</span>
457 <span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
458 <span class="go">'&lt;?xml version="1.0"?&gt;\n&lt;foo&gt; It\'s "Monty Python" &lt;/foo&gt;\n'</span>
459 </pre></div>
460 <p>If you need to pass parameters that are not legal Python identifiers,
461 pass them inside of a dictionary:</p>
462 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">transform</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XSLT</span><span class="p">(</span><span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="s">'''</span><span class="se">\</span>
463 <span class="gp">... </span><span class="s">&lt;xsl:stylesheet version="1.0"</span>
464 <span class="gp">... </span><span class="s">    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;</span>
465 <span class="gp">... </span><span class="s">    &lt;xsl:param name="non-python-identifier" /&gt;</span>
466 <span class="gp">... </span><span class="s">    &lt;xsl:template match="/"&gt;</span>
467 <span class="gp">... </span><span class="s">        &lt;foo&gt;&lt;xsl:value-of select="$non-python-identifier" /&gt;&lt;/foo&gt;</span>
468 <span class="gp">... </span><span class="s">    &lt;/xsl:template&gt;</span>
469 <span class="gp">... </span><span class="s">&lt;/xsl:stylesheet&gt;'''</span><span class="p">))</span>
470
471 <span class="gp">&gt;&gt;&gt; </span><span class="n">result</span> <span class="o">=</span> <span class="n">transform</span><span class="p">(</span><span class="n">doc_root</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span><span class="s">'non-python-identifier'</span><span class="p">:</span> <span class="s">'5'</span><span class="p">})</span>
472 <span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
473 <span class="go">'&lt;?xml version="1.0"?&gt;\n&lt;foo&gt;5&lt;/foo&gt;\n'</span>
474 </pre></div>
475 </div>
476 <div class="section" id="errors-and-messages">
477 <h2>Errors and messages</h2>
478 <p>Like most of the processing oriented objects in lxml.etree, <tt class="docutils literal">XSLT</tt>
479 provides an error log that lists messages and error output from the
480 last run.  See the <a class="reference external" href="parsing.html#error-log">parser documentation</a> for a description of the
481 error log.</p>
482 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">xslt_root</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="s">'''</span><span class="se">\</span>
483 <span class="gp">... </span><span class="s">&lt;xsl:stylesheet version="1.0"</span>
484 <span class="gp">... </span><span class="s">    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;</span>
485 <span class="gp">... </span><span class="s">    &lt;xsl:template match="/"&gt;</span>
486 <span class="gp">... </span><span class="s">        &lt;xsl:message terminate="no"&gt;STARTING&lt;/xsl:message&gt;</span>
487 <span class="gp">... </span><span class="s">        &lt;foo&gt;&lt;xsl:value-of select="/a/b/text()" /&gt;&lt;/foo&gt;</span>
488 <span class="gp">... </span><span class="s">        &lt;xsl:message terminate="no"&gt;DONE&lt;/xsl:message&gt;</span>
489 <span class="gp">... </span><span class="s">    &lt;/xsl:template&gt;</span>
490 <span class="gp">... </span><span class="s">&lt;/xsl:stylesheet&gt;'''</span><span class="p">)</span>
491 <span class="gp">&gt;&gt;&gt; </span><span class="n">transform</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XSLT</span><span class="p">(</span><span class="n">xslt_root</span><span class="p">)</span>
492
493 <span class="gp">&gt;&gt;&gt; </span><span class="n">doc_root</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="s">'&lt;a&gt;&lt;b&gt;Text&lt;/b&gt;&lt;/a&gt;'</span><span class="p">)</span>
494 <span class="gp">&gt;&gt;&gt; </span><span class="n">result</span> <span class="o">=</span> <span class="n">transform</span><span class="p">(</span><span class="n">doc_root</span><span class="p">)</span>
495 <span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
496 <span class="go">'&lt;?xml version="1.0"?&gt;\n&lt;foo&gt;Text&lt;/foo&gt;\n'</span>
497
498 <span class="gp">&gt;&gt;&gt; </span><span class="k">print</span><span class="p">(</span><span class="n">transform</span><span class="o">.</span><span class="n">error_log</span><span class="p">)</span>
499 <span class="go">&lt;string&gt;:0:0:ERROR:XSLT:ERR_OK: STARTING</span>
500 <span class="go">&lt;string&gt;:0:0:ERROR:XSLT:ERR_OK: DONE</span>
501
502 <span class="gp">&gt;&gt;&gt; </span><span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">transform</span><span class="o">.</span><span class="n">error_log</span><span class="p">:</span>
503 <span class="gp">... </span>    <span class="k">print</span><span class="p">(</span><span class="s">'message from line </span><span class="si">%s</span><span class="s">, col </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span>
504 <span class="gp">... </span>               <span class="n">entry</span><span class="o">.</span><span class="n">line</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">column</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">message</span><span class="p">))</span>
505 <span class="gp">... </span>    <span class="k">print</span><span class="p">(</span><span class="s">'domain: </span><span class="si">%s</span><span class="s"> (</span><span class="si">%d</span><span class="s">)'</span> <span class="o">%</span> <span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">domain_name</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">domain</span><span class="p">))</span>
506 <span class="gp">... </span>    <span class="k">print</span><span class="p">(</span><span class="s">'type: </span><span class="si">%s</span><span class="s"> (</span><span class="si">%d</span><span class="s">)'</span> <span class="o">%</span> <span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">type_name</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">type</span><span class="p">))</span>
507 <span class="gp">... </span>    <span class="k">print</span><span class="p">(</span><span class="s">'level: </span><span class="si">%s</span><span class="s"> (</span><span class="si">%d</span><span class="s">)'</span> <span class="o">%</span> <span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">level_name</span><span class="p">,</span> <span class="n">entry</span><span class="o">.</span><span class="n">level</span><span class="p">))</span>
508 <span class="gp">... </span>    <span class="k">print</span><span class="p">(</span><span class="s">'filename: </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="n">entry</span><span class="o">.</span><span class="n">filename</span><span class="p">)</span>
509 <span class="go">message from line 0, col 0: STARTING</span>
510 <span class="go">domain: XSLT (22)</span>
511 <span class="go">type: ERR_OK (0)</span>
512 <span class="go">level: ERROR (2)</span>
513 <span class="go">filename: &lt;string&gt;</span>
514 <span class="go">message from line 0, col 0: DONE</span>
515 <span class="go">domain: XSLT (22)</span>
516 <span class="go">type: ERR_OK (0)</span>
517 <span class="go">level: ERROR (2)</span>
518 <span class="go">filename: &lt;string&gt;</span>
519 </pre></div>
520 <p>Note that there is no way in XSLT to distinguish between user
521 messages, warnings and error messages that occurred during the
522 run. <tt class="docutils literal">libxslt</tt> simply does not provide this information.  You can
523 partly work around this limitation by making your own messages
524 uniquely identifiable, e.g. with a common text prefix.</p>
525 </div>
526 <div class="section" id="the-xslt-tree-method">
527 <h2>The <tt class="docutils literal">xslt()</tt> tree method</h2>
528 <p>There's also a convenience method on ElementTree objects for doing XSL
529 transformations.  This is less efficient if you want to apply the same XSL
530 transformation to multiple documents, but is shorter to write for one-shot
531 operations, as you do not have to instantiate a stylesheet yourself:</p>
532 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">result</span> <span class="o">=</span> <span class="n">doc</span><span class="o">.</span><span class="n">xslt</span><span class="p">(</span><span class="n">xslt_tree</span><span class="p">,</span> <span class="n">a</span><span class="o">=</span><span class="s">"'A'"</span><span class="p">)</span>
533 <span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
534 <span class="go">'&lt;?xml version="1.0"?&gt;\n&lt;foo&gt;A&lt;/foo&gt;\n'</span>
535 </pre></div>
536 <p>This is a shortcut for the following code:</p>
537 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">transform</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">XSLT</span><span class="p">(</span><span class="n">xslt_tree</span><span class="p">)</span>
538 <span class="gp">&gt;&gt;&gt; </span><span class="n">result</span> <span class="o">=</span> <span class="n">transform</span><span class="p">(</span><span class="n">doc</span><span class="p">,</span> <span class="n">a</span><span class="o">=</span><span class="s">"'A'"</span><span class="p">)</span>
539 <span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
540 <span class="go">'&lt;?xml version="1.0"?&gt;\n&lt;foo&gt;A&lt;/foo&gt;\n'</span>
541 </pre></div>
542 </div>
543 <div class="section" id="dealing-with-stylesheet-complexity">
544 <h2>Dealing with stylesheet complexity</h2>
545 <p>Some applications require a larger set of rather diverse stylesheets.
546 lxml.etree allows you to deal with this in a number of ways.  Here are
547 some ideas to try.</p>
548 <p>The most simple way to reduce the diversity is by using XSLT
549 parameters that you pass at call time to configure the stylesheets.
550 The <tt class="docutils literal">partial()</tt> function in the <tt class="docutils literal">functools</tt> module of Python 2.5
551 may come in handy here.  It allows you to bind a set of keyword
552 arguments (i.e. stylesheet parameters) to a reference of a callable
553 stylesheet.  The same works for instances of the <tt class="docutils literal">XPath()</tt>
554 evaluator, obviously.</p>
555 <p>You may also consider creating stylesheets programmatically.  Just
556 create an XSL tree, e.g. from a parsed template, and then add or
557 replace parts as you see fit.  Passing an XSL tree into the <tt class="docutils literal">XSLT()</tt>
558 constructor multiple times will create independent stylesheets, so
559 later modifications of the tree will not be reflected in the already
560 created stylesheets.  This makes stylesheet generation very straight
561 forward.</p>
562 <p>A third thing to remember is the support for <a class="reference external" href="extensions.html#xpath-extension-functions">custom extension
563 functions</a> and <a class="reference external" href="extensions.html#xslt-extension-elements">XSLT extension elements</a>.  Some things are much
564 easier to express in XSLT than in Python, while for others it is the
565 complete opposite.  Finding the right mixture of Python code and XSL
566 code can help a great deal in keeping applications well designed and
567 maintainable.</p>
568 </div>
569 <div class="section" id="profiling">
570 <h2>Profiling</h2>
571 <p>If you want to know how your stylesheet performed, pass the <tt class="docutils literal">profile_run</tt>
572 keyword to the transform:</p>
573 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">result</span> <span class="o">=</span> <span class="n">transform</span><span class="p">(</span><span class="n">doc</span><span class="p">,</span> <span class="n">a</span><span class="o">=</span><span class="s">"/a/b/text()"</span><span class="p">,</span> <span class="n">profile_run</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
574 <span class="gp">&gt;&gt;&gt; </span><span class="n">profile</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">xslt_profile</span>
575 </pre></div>
576 <p>The value of the <tt class="docutils literal">xslt_profile</tt> property is an ElementTree with profiling
577 data about each template, similar to the following:</p>
578 <div class="syntax"><pre><span class="nt">&lt;profile&gt;</span>
579   <span class="nt">&lt;template</span> <span class="na">rank=</span><span class="s">"1"</span> <span class="na">match=</span><span class="s">"/"</span> <span class="na">name=</span><span class="s">""</span> <span class="na">mode=</span><span class="s">""</span> <span class="na">calls=</span><span class="s">"1"</span> <span class="na">time=</span><span class="s">"1"</span> <span class="na">average=</span><span class="s">"1"</span><span class="nt">/&gt;</span>
580 <span class="nt">&lt;/profile&gt;</span>
581 </pre></div>
582 <p>Note that this is a read-only document.  You must not move any of its elements
583 to other documents.  Please deep-copy the document if you need to modify it.
584 If you want to free it from memory, just do:</p>
585 <div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">del</span> <span class="n">result</span><span class="o">.</span><span class="n">xslt_profile</span>
586 </pre></div>
587 </div>
588 </div>
589 </div>
590 <div class="footer">
591 <hr class="footer" />
592 Generated on: 2012-07-31.
593
594 </div>
595 </body>
596 </html>