Sophie

Sophie

distrib > CentOS > 5 > i386 > by-pkgid > 90dba77ca23efa667b541b5c0dd77497 > files > 389

python-lxml-2.0.11-2.el5.i386.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.4.1: http://docutils.sourceforge.net/" />
<title>Document loading and URL resolving</title>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<div class="document" id="document-loading-and-url-resolving">
<div class="sidemenu"><ul id="lxml"><li><span class="section title">lxml</span><ul class="menu foreign" id="index"><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#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></ul></li></ul><ul class="menu foreign" id="intro"><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"><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#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="lxml2"><li class="menu title"><a href="lxml2.html">What's new in lxml 2.0?</a><ul class="submenu"><li class="menu item"><a href="lxml2.html#changes-in-etree-and-objectify">Changes in etree and objectify</a></li><li class="menu item"><a href="lxml2.html#new-modules">New modules</a></li></ul></li></ul><ul class="menu foreign" id="performance"><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"><li class="menu title"><a href="compatibility.html">ElementTree compatibility of lxml.etree</a></li></ul><ul class="menu foreign" id="FAQ"><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#threading">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"><li><span class="section title">Developing with lxml</span><ul class="menu foreign" id="tutorial"><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"><li class="menu title"><a href="api/index.html">API reference</a></li></ul><ul class="menu foreign" id="api"><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#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"><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"><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#dtd">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#schematron">Schematron</a></li></ul></li></ul><ul class="menu foreign" id="xpathxslt"><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"><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"><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"><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#limitations">Limitations</a></li></ul></li></ul><ul class="menu foreign" id="elementsoup"><li class="menu title"><a href="elementsoup.html">BeautifulSoup Parser</a><ul class="submenu"><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></ul></li></ul></li></ul><ul id="Extending lxml"><li><span class="section title">Extending lxml</span><ul class="menu current" id="resolvers"><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#resolvers">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"><li class="menu title"><a href="extensions.html">Extension functions for XPath and XSLT</a><ul class="submenu"><li class="menu item"><a href="extensions.html#the-functionnamespace">The FunctionNamespace</a></li><li class="menu item"><a href="extensions.html#global-prefix-assignment">Global prefix assignment</a></li><li class="menu item"><a href="extensions.html#the-xpath-context">The XPath context</a></li><li class="menu item"><a href="extensions.html#evaluators-and-xslt">Evaluators and XSLT</a></li><li class="menu item"><a href="extensions.html#evaluator-local-extensions">Evaluator-local extensions</a></li><li class="menu item"><a href="extensions.html#what-to-return-from-a-function">What to return from a function</a></li></ul></li></ul><ul class="menu foreign" id="element classes"><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#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#implementing-namespaces">Implementing namespaces</a></li></ul></li></ul><ul class="menu foreign" id="sax"><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"><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"><li><span class="section title">Developing lxml</span><ul class="menu foreign" id="build"><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#subversion">Subversion</a></li><li class="menu item"><a href="build.html#setuptools">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#contributing-an-egg">Contributing an egg</a></li><li class="menu item"><a href="build.html#providing-newer-library-versions-on-mac-os-x">Providing newer library versions on Mac-OS 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"><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-pyclasslookup">lxml.pyclasslookup</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 0 11"><li class="menu title"><a href="changes-2.0.11.html">Release Changelog</a></li></ul><ul class="menu foreign" id="credits"><li class="menu title"><a href="credits.html">Credits</a><ul class="submenu"><li class="menu item"><a href="credits.html#special-thanks-goes-to:">Special thanks goes to:</a></li></ul></li></ul></li></ul></div><h1 class="title">Document loading and URL resolving</h1>
<div class="contents topic">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#resolvers" id="id1" name="id1">Resolvers</a></li>
<li><a class="reference" href="#document-loading-in-context" id="id2" name="id2">Document loading in context</a></li>
<li><a class="reference" href="#i-o-access-control-in-xslt" id="id3" name="id3">I/O access control in XSLT</a></li>
</ul>
</div>
<p>Lxml has support for custom document loaders in both the parsers and XSL
transformations.  These so-called resolvers are subclasses of the
etree.Resolver class.</p>
<div class="section">
<h1><a id="resolvers" name="resolvers">Resolvers</a></h1>
<p>Here is an example of a custom resolver:</p>
<pre class="literal-block">
&gt;&gt;&gt; from lxml import etree

&gt;&gt;&gt; class DTDResolver(etree.Resolver):
...     def resolve(self, url, id, context):
...         print "Resolving URL '%s'" % url
...         return self.resolve_string(
...             '&lt;!ENTITY myentity "[resolved text: %s]"&gt;' % url, context)
</pre>
<p>This defines a resolver that always returns a dynamically generated DTD
fragment defining an entity.  The <tt class="docutils literal"><span class="pre">url</span></tt> argument passes the system URL of
the requested document, the <tt class="docutils literal"><span class="pre">id</span></tt> argument is the public ID.  Note that any
of these may be None.  The context object is not normally used by client code.</p>
<p>Resolving is based on three methods of the Resolver object that build internal
representations of the result document.  The following methods exist:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">resolve_string</span></tt> takes a parsable string as result document</li>
<li><tt class="docutils literal"><span class="pre">resolve_filename</span></tt> takes a filename</li>
<li><tt class="docutils literal"><span class="pre">resolve_file</span></tt> takes an open file-like object that has at least a read() method</li>
<li><tt class="docutils literal"><span class="pre">resolve_empty</span></tt> resolves into an empty document</li>
</ul>
<p>The <tt class="docutils literal"><span class="pre">resolve()</span></tt> method may choose to return None, in which case the next
registered resolver (or the default resolver) is consulted.  Resolving always
terminates if <tt class="docutils literal"><span class="pre">resolve()</span></tt> returns the result of any of the above
<tt class="docutils literal"><span class="pre">resolve_*()</span></tt> methods.</p>
<p>Resolvers are registered local to a parser:</p>
<pre class="literal-block">
&gt;&gt;&gt; parser = etree.XMLParser(load_dtd=True)
&gt;&gt;&gt; parser.resolvers.add( DTDResolver() )
</pre>
<p>Note that we instantiate a parser that loads the DTD.  This is not done by the
default parser, which does no validation.  When we use this parser to parse a
document that requires resolving a URL, it will call our custom resolver:</p>
<pre class="literal-block">
&gt;&gt;&gt; xml = u'&lt;!DOCTYPE doc SYSTEM "MissingDTD.dtd"&gt;&lt;doc&gt;&amp;myentity;&lt;/doc&gt;'
&gt;&gt;&gt; from StringIO import StringIO
&gt;&gt;&gt; tree = etree.parse(StringIO(xml), parser)
Resolving URL 'MissingDTD.dtd'
&gt;&gt;&gt; root = tree.getroot()
&gt;&gt;&gt; print root.text
[resolved text: MissingDTD.dtd]
</pre>
<p>The entity in the document was correctly resolved by the generated DTD
fragment.</p>
</div>
<div class="section">
<h1><a id="document-loading-in-context" name="document-loading-in-context">Document loading in context</a></h1>
<p>XML documents memorise their initial parser (and its resolvers) during their
life-time.  This means that a lookup process related to a document will use
the resolvers of the document's parser.  We can demonstrate this with a
resolver that only responds to a specific prefix:</p>
<pre class="literal-block">
&gt;&gt;&gt; class PrefixResolver(etree.Resolver):
...     def __init__(self, prefix):
...         self.prefix = prefix
...         self.result_xml = '''\
...              &lt;xsl:stylesheet
...                     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
...                &lt;test xmlns="testNS"&gt;%s-TEST&lt;/test&gt;
...              &lt;/xsl:stylesheet&gt;
...              ''' % prefix
...     def resolve(self, url, pubid, context):
...         if url.startswith(self.prefix):
...             print "Resolved url %s as prefix %s" % (url, self.prefix)
...             return self.resolve_string(self.result_xml, context)
</pre>
<p>We demonstrate this in XSLT and use the following stylesheet as an example:</p>
<pre class="literal-block">
&gt;&gt;&gt; xml_text = """\
... &lt;xsl:stylesheet version="1.0"
...    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
...   &lt;xsl:include href="honk:test"/&gt;
...   &lt;xsl:template match="/"&gt;
...     &lt;test&gt;
...       &lt;xsl:value-of select="document('hoi:test')/*/*/text()"/&gt;
...     &lt;/test&gt;
...   &lt;/xsl:template&gt;
... &lt;/xsl:stylesheet&gt;
... """
</pre>
<p>Note that it needs to resolve two URIs: <tt class="docutils literal"><span class="pre">honk:test</span></tt> when compiling the XSLT
document (i.e. when resolving <tt class="docutils literal"><span class="pre">xsl:import</span></tt> and <tt class="docutils literal"><span class="pre">xsl:include</span></tt> elements) and
<tt class="docutils literal"><span class="pre">hoi:test</span></tt> at transformation time, when calls to the <tt class="docutils literal"><span class="pre">document</span></tt> function
are resolved.  If we now register different resolvers with two different
parsers, we can parse our document twice in different resolver contexts:</p>
<pre class="literal-block">
&gt;&gt;&gt; hoi_parser = etree.XMLParser()
&gt;&gt;&gt; normal_doc = etree.parse(StringIO(xml_text), hoi_parser)

&gt;&gt;&gt; hoi_parser.resolvers.add( PrefixResolver("hoi") )
&gt;&gt;&gt; hoi_doc = etree.parse(StringIO(xml_text), hoi_parser)

&gt;&gt;&gt; honk_parser = etree.XMLParser()
&gt;&gt;&gt; honk_parser.resolvers.add( PrefixResolver("honk") )
&gt;&gt;&gt; honk_doc = etree.parse(StringIO(xml_text), honk_parser)
</pre>
<p>These contexts are important for the further behaviour of the documents.  They
memorise their original parser so that the correct set of resolvers is used in
subsequent lookups.  To compile the stylesheet, XSLT must resolve the
<tt class="docutils literal"><span class="pre">honk:test</span></tt> URI in the <tt class="docutils literal"><span class="pre">xsl:include</span></tt> element.  The <tt class="docutils literal"><span class="pre">hoi</span></tt> resolver cannot
do that:</p>
<pre class="literal-block">
&gt;&gt;&gt; transform = etree.XSLT(normal_doc)
Traceback (most recent call last):
  [...]
XSLTParseError: Cannot resolve URI honk:test

&gt;&gt;&gt; transform = etree.XSLT(hoi_doc)
Traceback (most recent call last):
  [...]
XSLTParseError: Cannot resolve URI honk:test
</pre>
<p>However, if we use the <tt class="docutils literal"><span class="pre">honk</span></tt> resolver associated with the respective
document, everything works fine:</p>
<pre class="literal-block">
&gt;&gt;&gt; transform = etree.XSLT(honk_doc)
Resolved url honk:test as prefix honk
</pre>
<p>Running the transform accesses the same parser context again, but since it now
needs to resolve the <tt class="docutils literal"><span class="pre">hoi</span></tt> URI in the call to the document function, its
<tt class="docutils literal"><span class="pre">honk</span></tt> resolver will fail to do so:</p>
<pre class="literal-block">
&gt;&gt;&gt; result = transform(normal_doc)
Traceback (most recent call last):
  [...]
XSLTApplyError: Cannot resolve URI hoi:test

&gt;&gt;&gt; result = transform(hoi_doc)
Traceback (most recent call last):
  [...]
XSLTApplyError: Cannot resolve URI hoi:test

&gt;&gt;&gt; result = transform(honk_doc)
Traceback (most recent call last):
  [...]
XSLTApplyError: Cannot resolve URI hoi:test
</pre>
<p>This can only be solved by adding a <tt class="docutils literal"><span class="pre">hoi</span></tt> resolver to the original parser:</p>
<pre class="literal-block">
&gt;&gt;&gt; honk_parser.resolvers.add( PrefixResolver("hoi") )
&gt;&gt;&gt; result = transform(honk_doc)
Resolved url hoi:test as prefix hoi
&gt;&gt;&gt; print str(result),
&lt;?xml version="1.0"?&gt;
&lt;test&gt;hoi-TEST&lt;/test&gt;
</pre>
<p>We can see that the <tt class="docutils literal"><span class="pre">hoi</span></tt> resolver was called to generate a document that
was then inserted into the result document by the XSLT transformation.  Note
that this is completely independent of the XML file you transform, as the URI
is resolved from within the stylesheet context:</p>
<pre class="literal-block">
&gt;&gt;&gt; result = transform(normal_doc)
Resolved url hoi:test as prefix hoi
&gt;&gt;&gt; print str(result),
&lt;?xml version="1.0"?&gt;
&lt;test&gt;hoi-TEST&lt;/test&gt;
</pre>
<p>It may be seen as a matter of taste what resolvers the generated document
inherits.  For XSLT, the output document inherits the resolvers of the input
document and not those of the stylesheet.  Therefore, the last result does not
inherit any resolvers at all.</p>
</div>
<div class="section">
<h1><a id="i-o-access-control-in-xslt" name="i-o-access-control-in-xslt">I/O access control in XSLT</a></h1>
<p>By default, XSLT supports all extension functions from libxslt and libexslt as
well as Python regular expressions through EXSLT.  Some extensions enable
style sheets to read and write files on the local file system.</p>
<p>XSLT has a mechanism to control the access to certain I/O operations during
the transformation process.  This is most interesting where XSL scripts come
from potentially insecure sources and must be prevented from modifying the
local file system.  Note, however, that there is no way to keep them from
eating up your precious CPU time, so this should not stop you from thinking
about what XSLT you execute.</p>
<p>Access control is configured using the <tt class="docutils literal"><span class="pre">XSLTAccessControl</span></tt> class.  It can be
called with a number of keyword arguments that allow or deny specific
operations:</p>
<pre class="literal-block">
&gt;&gt;&gt; transform = etree.XSLT(honk_doc)
Resolved url honk:test as prefix honk
&gt;&gt;&gt; result = transform(normal_doc)
Resolved url hoi:test as prefix hoi

&gt;&gt;&gt; ac = etree.XSLTAccessControl(read_network=False)
&gt;&gt;&gt; transform = etree.XSLT(honk_doc, access_control=ac)
Resolved url honk:test as prefix honk
&gt;&gt;&gt; result = transform(normal_doc)
Traceback (most recent call last):
  [...]
XSLTApplyError: xsltLoadDocument: read rights for hoi:test denied
</pre>
<p>There are a few things to keep in mind:</p>
<ul class="simple">
<li>XSL parsing (<tt class="docutils literal"><span class="pre">xsl:import</span></tt>, etc.) is not affected by this mechanism</li>
<li><tt class="docutils literal"><span class="pre">read_file=False</span></tt> does not imply <tt class="docutils literal"><span class="pre">write_file=False</span></tt>, all controls are
independent.</li>
<li><tt class="docutils literal"><span class="pre">read_file</span></tt> only applies to files in the file system.  Any other scheme
for URLs is controlled by the <tt class="docutils literal"><span class="pre">*_network</span></tt> keywords.</li>
<li>If you need more fine-grained control than switching access on and off, you
should consider writing a custom document loader that returns empty
documents or raises exceptions if access is denied.</li>
</ul>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2008-12-12.

</div>
</body>
</html>