blob: 7d451c57ae78eafa78f5ceb4e7fac01009895f57 [file] [log] [blame]
Daniel Veillard1177ca42003-04-26 22:29:54 +00001<?xml version="1.0" encoding="ISO-8859-1"?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /><link rel="SHORTCUT ICON" href="/favicon.ico" /><style type="text/css">
Daniel Veillard373a4752002-02-21 14:46:29 +00004TD {font-family: Verdana,Arial,Helvetica}
5BODY {font-family: Verdana,Arial,Helvetica; margin-top: 2em; margin-left: 0em; margin-right: 0em}
6H1 {font-family: Verdana,Arial,Helvetica}
7H2 {font-family: Verdana,Arial,Helvetica}
8H3 {font-family: Verdana,Arial,Helvetica}
Daniel Veillard6dbcaf82002-02-20 14:37:47 +00009A:link, A:visited, A:active { text-decoration: underline }
Daniel Veillard69839ba2006-06-06 13:27:03 +000010</style><title>Python and bindings</title></head><body bgcolor="#8b7765" text="#000000" link="#a06060" vlink="#000000"><table border="0" width="100%" cellpadding="5" cellspacing="0" align="center"><tr><td width="120"><a href="http://swpat.ffii.org/"><img src="epatents.png" alt="Action against software patents" /></a></td><td width="180"><a href="http://www.gnome.org/"><img src="gnome2.png" alt="Gnome2 Logo" /></a><a href="http://www.w3.org/Status"><img src="w3c.png" alt="W3C Logo" /></a><a href="http://www.redhat.com/"><img src="redhat.gif" alt="Red Hat Logo" /></a><div align="left"><a href="http://xmlsoft.org/"><img src="Libxml2-Logo-180x168.gif" alt="Made with Libxml2 Logo" /></a></div></td><td><table border="0" width="90%" cellpadding="2" cellspacing="0" align="center" bgcolor="#000000"><tr><td><table width="100%" border="0" cellspacing="1" cellpadding="3" bgcolor="#fffacd"><tr><td align="center"><h1>The XML C parser and toolkit of Gnome</h1><h2>Python and bindings</h2></td></tr></table></td></tr></table></td></tr></table><table border="0" cellpadding="4" cellspacing="0" width="100%" align="center"><tr><td bgcolor="#8b7765"><table border="0" cellspacing="0" cellpadding="2" width="100%"><tr><td valign="top" width="200" bgcolor="#8b7765"><table border="0" cellspacing="0" cellpadding="1" width="100%" bgcolor="#000000"><tr><td><table width="100%" border="0" cellspacing="1" cellpadding="3"><tr><td colspan="1" bgcolor="#eecfa1" align="center"><center><b>Developer Menu</b></center></td></tr><tr><td bgcolor="#fffacd"><form action="search.php" enctype="application/x-www-form-urlencoded" method="get"><input name="query" type="text" size="20" value="" /><input name="submit" type="submit" value="Search ..." /></form><ul><li><a href="index.html" style="font-weight:bold">Main Menu</a></li><li><a href="html/index.html" style="font-weight:bold">Reference Manual</a></li><li><a href="examples/index.html" style="font-weight:bold">Code Examples</a></li><li><a href="guidelines.html">XML Guidelines</a></li><li><a href="tutorial/index.html">Tutorial</a></li><li><a href="xmlreader.html">The Reader Interface</a></li><li><a href="ChangeLog.html">ChangeLog</a></li><li><a href="XSLT.html">XSLT</a></li><li><a href="python.html">Python and bindings</a></li><li><a href="architecture.html">libxml2 architecture</a></li><li><a href="tree.html">The tree output</a></li><li><a href="interface.html">The SAX interface</a></li><li><a href="xmlmem.html">Memory Management</a></li><li><a href="xmlio.html">I/O Interfaces</a></li><li><a href="library.html">The parser interfaces</a></li><li><a href="entities.html">Entities or no entities</a></li><li><a href="namespaces.html">Namespaces</a></li><li><a href="upgrade.html">Upgrading 1.x code</a></li><li><a href="threads.html">Thread safety</a></li><li><a href="DOM.html">DOM Principles</a></li><li><a href="example.html">A real example</a></li><li><a href="xml.html">flat page</a>, <a href="site.xsl">stylesheet</a></li></ul></td></tr></table><table width="100%" border="0" cellspacing="1" cellpadding="3"><tr><td colspan="1" bgcolor="#eecfa1" align="center"><center><b>API Indexes</b></center></td></tr><tr><td bgcolor="#fffacd"><ul><li><a href="APIchunk0.html">Alphabetic</a></li><li><a href="APIconstructors.html">Constructors</a></li><li><a href="APIfunctions.html">Functions/Types</a></li><li><a href="APIfiles.html">Modules</a></li><li><a href="APIsymbols.html">Symbols</a></li></ul></td></tr></table><table width="100%" border="0" cellspacing="1" cellpadding="3"><tr><td colspan="1" bgcolor="#eecfa1" align="center"><center><b>Related links</b></center></td></tr><tr><td bgcolor="#fffacd"><ul><li><a href="http://mail.gnome.org/archives/xml/">Mail archive</a></li><li><a href="http://xmlsoft.org/XSLT/">XSLT libxslt</a></li><li><a href="http://phd.cs.unibo.it/gdome2/">DOM gdome2</a></li><li><a href="http://www.aleksey.com/xmlsec/">XML-DSig xmlsec</a></li><li><a href="ftp://xmlsoft.org/">FTP</a></li><li><a href="http://www.zlatkovic.com/projects/libxml/">Windows binaries</a></li><li><a href="http://www.blastwave.org/packages.php/libxml2">Solaris binaries</a></li><li><a href="http://www.explain.com.au/oss/libxml2xslt.html">MacOsX binaries</a></li><li><a href="http://libxmlplusplus.sourceforge.net/">C++ bindings</a></li><li><a href="http://www.zend.com/php5/articles/php5-xmlphp.php#Heading4">PHP bindings</a></li><li><a href="http://sourceforge.net/projects/libxml2-pas/">Pascal bindings</a></li><li><a href="http://libxml.rubyforge.org/">Ruby bindings</a></li><li><a href="http://tclxml.sourceforge.net/">Tcl bindings</a></li><li><a href="http://bugzilla.gnome.org/buglist.cgi?product=libxml2">Bug Tracker</a></li></ul></td></tr></table></td></tr></table></td><td valign="top" bgcolor="#8b7765"><table border="0" cellspacing="0" cellpadding="1" width="100%"><tr><td><table border="0" cellspacing="0" cellpadding="1" width="100%" bgcolor="#000000"><tr><td><table border="0" cellpadding="3" cellspacing="1" width="100%"><tr><td bgcolor="#fffacd"><p>There are a number of language bindings and wrappers available forlibxml2,
11the list below is not exhaustive. Please contact the <a href="http://mail.gnome.org/mailman/listinfo/xml-bindings">xml-bindings@gnome.org</a>(<a href="http://mail.gnome.org/archives/xml-bindings/">archives</a>) inorder to
12get updates to this list or to discuss the specific topic of libxml2or
13libxslt wrappers or bindings:</p><ul><li><a href="http://libxmlplusplus.sourceforge.net/">Libxml++</a>seems
14 themost up-to-date C++ bindings for libxml2, check the <a href="http://libxmlplusplus.sourceforge.net/reference/html/hierarchy.html">documentation</a>and
15 the <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/libxmlplusplus/libxml%2b%2b/examples/">examples</a>.</li>
16 <li>There is another <a href="http://libgdome-cpp.berlios.de/">C++
17 wrapperbased on the gdome2 bindings</a>maintained by Tobias Peters.</li>
Daniel Veillard0b28e882002-07-24 23:47:05 +000018 <li>and a third C++ wrapper by Peter Jones &lt;pjones@pmade.org&gt;
Daniel Veillard1177ca42003-04-26 22:29:54 +000019 <p>Website: <a href="http://pmade.org/pjones/software/xmlwrapp/">http://pmade.org/pjones/software/xmlwrapp/</a></p>
Daniel Veillard0b28e882002-07-24 23:47:05 +000020 </li>
Daniel Veillard69839ba2006-06-06 13:27:03 +000021 <li><a href="http://mail.gnome.org/archives/xml/2001-March/msg00014.html">MattSergeant</a>developed
22 <a href="http://axkit.org/download/">XML::LibXSLT</a>, a Perl wrapper
23 forlibxml2/libxslt as part of the <a href="http://axkit.com/">AxKit
24 XMLapplication server</a>.</li>
25 <li>If you're interested into scripting XML processing, have a look at <a href="http://xsh.sourceforge.net/">XSH</a>an XML editing shell based
26 onLibxml2 Perl bindings.</li>
27 <li><a href="mailto:dkuhlman@cutter.rexx.com">Dave Kuhlman</a>provides
28 anearlier version of the libxml/libxslt <a href="http://www.rexx.com/~dkuhlman">wrappers for Python</a>.</li>
29 <li>Gopal.V and Peter Minten develop <a href="http://savannah.gnu.org/projects/libxmlsharp">libxml#</a>, a set
30 ofC# libxml2 bindings.</li>
31 <li>Petr Kozelka provides <a href="http://sourceforge.net/projects/libxml2-pas">Pascal units to
32 gluelibxml2</a>with Kylix, Delphi and other Pascal compilers.</li>
33 <li>Uwe Fechner also provides <a href="http://sourceforge.net/projects/idom2-pas/">idom2</a>, a
34 DOM2implementation for Kylix2/D5/D6 from Borland.</li>
35 <li>There is <a href="http://libxml.rubyforge.org/">bindings for
36 Ruby</a>and libxml2 bindings are also available in Ruby through the <a href="http://libgdome-ruby.berlios.de/">libgdome-ruby</a>modulemaintained
37 by Tobias Peters.</li>
38 <li>Steve Ball and contributors maintains <a href="http://tclxml.sourceforge.net/">libxml2 and libxslt bindings
39 forTcl</a>.</li>
Daniel Veillard142fb212005-04-07 12:48:10 +000040 <li>libxml2 and libxslt is the default XML library for PHP5.</li>
Daniel Veillard69839ba2006-06-06 13:27:03 +000041 <li><a href="http://savannah.gnu.org/projects/classpathx/">LibxmlJ</a>isan
42 effort to create a 100% JAXP-compatible Java wrapper for libxml2
43 andlibxslt as part of GNU ClasspathX project.</li>
44 <li>Patrick McPhee provides Rexx bindings fof libxml2 and libxslt, look
45 for<a href="http://www.interlog.com/~ptjm/software.html">RexxXML</a>.</li>
46 <li><a href="http://www.satimage.fr/software/en/xml_suite.html">Satimage</a>provides
47 <a href="http://www.satimage.fr/software/en/downloads_osaxen.html">XMLLibosax</a>.
48 This is an osax for Mac OS X with a set of commands toimplement in
49 AppleScript the XML DOM, XPATH and XSLT. Also includescommands for
50 Property-lists (Apple's fast lookup table XML format.)</li>
51 <li>Francesco Montorsi developped <a href="https://sourceforge.net/project/showfiles.php?group_id=51305&amp;package_id=45182">wxXml2</a>wrappers
52 that interface libxml2, allowing wxWidgets applications toload/save/edit
53 XML instances.</li>
54</ul><p>The distribution includes a set of Python bindings, which are guaranteedto
55be maintained as part of the library in the future, though the
56Pythoninterface have not yet reached the completeness of the C API.</p><p>Note that some of the Python purist dislike the default set of
57Pythonbindings, rather than complaining I suggest they have a look at <a href="http://codespeak.net/lxml/">lxml the more pythonic bindings for
58libxml2and libxslt</a>and <a href="http://codespeak.net/mailman/listinfo/lxml-dev">help
59MartijnFaassen</a>complete those.</p><p><a href="mailto:stephane.bidoul@softwareag.com">Stéphane
60Bidoul</a>maintains <a href="http://users.skynet.be/sbi/libxml-python/">a
61Windows portof the Python bindings</a>.</p><p>Note to people interested in building bindings, the API is formalized as<a href="libxml2-api.xml">an XML API description file</a>which allows toautomate
62a large part of the Python bindings, this includes functiondescriptions,
63enums, structures, typedefs, etc... The Python script used tobuild the
64bindings is python/generator.py in the source distribution.</p><p>To install the Python bindings there are 2 options:</p><ul><li>If you use an RPM based distribution, simply install the <a href="http://rpmfind.net/linux/rpm2html/search.php?query=libxml2-python">libxml2-pythonRPM</a>(and
65 if needed the <a href="http://rpmfind.net/linux/rpm2html/search.php?query=libxslt-python">libxslt-pythonRPM</a>).</li>
66 <li>Otherwise use the <a href="ftp://xmlsoft.org/libxml2/python/">libxml2-pythonmodule
67 distribution</a>corresponding to your installed version oflibxml2 and
68 libxslt. Note that to install it you will need both libxml2and libxslt
69 installed and run "python setup.py build install" in themodule tree.</li>
70</ul><p>The distribution includes a set of examples and regression tests for
71thepython bindings in the <code>python/tests</code>directory. Here are
72someexcerpts from those tests:</p><h3>tst.py:</h3><p>This is a basic test of the file interface and DOM navigation:</p><pre>import libxml2, sys
Daniel Veillard6dbcaf82002-02-20 14:37:47 +000073
Daniel Veillard024f1992003-12-10 16:43:49 +000074doc = libxml2.parseFile("tst.xml")
75if doc.name != "tst.xml":
76 print "doc.name failed"
Daniel Veillard6dbcaf82002-02-20 14:37:47 +000077 sys.exit(1)
78root = doc.children
Daniel Veillard024f1992003-12-10 16:43:49 +000079if root.name != "doc":
80 print "root.name failed"
Daniel Veillard6dbcaf82002-02-20 14:37:47 +000081 sys.exit(1)
82child = root.children
Daniel Veillard024f1992003-12-10 16:43:49 +000083if child.name != "foo":
84 print "child.name failed"
Daniel Veillard6dbcaf82002-02-20 14:37:47 +000085 sys.exit(1)
Daniel Veillard69839ba2006-06-06 13:27:03 +000086doc.freeDoc()</pre><p>The Python module is called libxml2; parseFile is the equivalent
87ofxmlParseFile (most of the bindings are automatically generated, and the
88xmlprefix is removed and the casing convention are kept). All node seen at
89thebinding level share the same subset of accessors:</p><ul><li><code>name</code>: returns the node name</li>
90 <li><code>type</code>: returns a string indicating the node type</li>
91 <li><code>content</code>: returns the content of the node, it is based
92 onxmlNodeGetContent() and hence is recursive.</li>
93 <li><code>parent</code>, <code>children</code>,
94 <code>last</code>,<code>next</code>, <code>prev</code>,
95 <code>doc</code>,<code>properties</code>: pointing to the associated
96 element in the tree,those may return None in case no such link
97 exists.</li>
98</ul><p>Also note the need to explicitly deallocate documents with freeDoc()
99.Reference counting for libxml2 trees would need quite a lot of work
100tofunction properly, and rather than risk memory leaks if not
101implementedcorrectly it sounds safer to have an explicit function to free a
102tree. Thewrapper python objects like doc, root or child are them
103automatically garbagecollected.</p><h3>validate.py:</h3><p>This test check the validation interfaces and redirection of
104errormessages:</p><pre>import libxml2
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000105
Daniel Veillard63d83142002-05-20 06:51:05 +0000106#deactivate error messages from the validation
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000107def noerr(ctx, str):
108 pass
109
110libxml2.registerErrorHandler(noerr, None)
111
Daniel Veillard024f1992003-12-10 16:43:49 +0000112ctxt = libxml2.createFileParserCtxt("invalid.xml")
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000113ctxt.validate(1)
114ctxt.parseDocument()
115doc = ctxt.doc()
116valid = ctxt.isValid()
117doc.freeDoc()
118if valid != 0:
Daniel Veillard69839ba2006-06-06 13:27:03 +0000119 print "validity check failed"</pre><p>The first thing to notice is the call to registerErrorHandler(), itdefines
120a new error handler global to the library. It is used to avoid seeingthe
121error messages when trying to validate the invalid document.</p><p>The main interest of that test is the creation of a parser context
122withcreateFileParserCtxt() and how the behaviour can be changed before
123callingparseDocument() . Similarly the informations resulting from the
124parsing phaseare also available using context methods.</p><p>Contexts like nodes are defined as class and the libxml2 wrappers maps
125theC function interfaces in terms of objects method as much as possible.
126Thebest to get a complete view of what methods are supported is to look at
127thelibxml2.py module containing all the wrappers.</p><h3>push.py:</h3><p>This test show how to activate the push parser interface:</p><pre>import libxml2
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000128
Daniel Veillard024f1992003-12-10 16:43:49 +0000129ctxt = libxml2.createPushParser(None, "&lt;foo", 4, "test.xml")
130ctxt.parseChunk("/&gt;", 2, 1)
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000131doc = ctxt.doc()
132
Daniel Veillard69839ba2006-06-06 13:27:03 +0000133doc.freeDoc()</pre><p>The context is created with a special call based on
134thexmlCreatePushParser() from the C library. The first argument is an
135optionalSAX callback object, then the initial set of data, the length and the
136name ofthe resource in case URI-References need to be computed by the
137parser.</p><p>Then the data are pushed using the parseChunk() method, the last
138callsetting the third argument terminate to 1.</p><h3>pushSAX.py:</h3><p>this test show the use of the event based parsing interfaces. In this
139casethe parser does not build a document, but provides callback information
140asthe parser makes progresses analyzing the data being provided:</p><pre>import libxml2
Daniel Veillard024f1992003-12-10 16:43:49 +0000141log = ""
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000142
143class callback:
144 def startDocument(self):
145 global log
Daniel Veillard024f1992003-12-10 16:43:49 +0000146 log = log + "startDocument:"
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000147
148 def endDocument(self):
149 global log
Daniel Veillard024f1992003-12-10 16:43:49 +0000150 log = log + "endDocument:"
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000151
152 def startElement(self, tag, attrs):
153 global log
Daniel Veillard024f1992003-12-10 16:43:49 +0000154 log = log + "startElement %s %s:" % (tag, attrs)
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000155
156 def endElement(self, tag):
157 global log
Daniel Veillard024f1992003-12-10 16:43:49 +0000158 log = log + "endElement %s:" % (tag)
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000159
160 def characters(self, data):
161 global log
Daniel Veillard024f1992003-12-10 16:43:49 +0000162 log = log + "characters: %s:" % (data)
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000163
164 def warning(self, msg):
165 global log
Daniel Veillard024f1992003-12-10 16:43:49 +0000166 log = log + "warning: %s:" % (msg)
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000167
168 def error(self, msg):
169 global log
Daniel Veillard024f1992003-12-10 16:43:49 +0000170 log = log + "error: %s:" % (msg)
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000171
172 def fatalError(self, msg):
173 global log
Daniel Veillard024f1992003-12-10 16:43:49 +0000174 log = log + "fatalError: %s:" % (msg)
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000175
176handler = callback()
177
Daniel Veillard024f1992003-12-10 16:43:49 +0000178ctxt = libxml2.createPushParser(handler, "&lt;foo", 4, "test.xml")
179chunk = " url='tst'&gt;b"
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000180ctxt.parseChunk(chunk, len(chunk), 0)
Daniel Veillard024f1992003-12-10 16:43:49 +0000181chunk = "ar&lt;/foo&gt;"
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000182ctxt.parseChunk(chunk, len(chunk), 1)
183
Daniel Veillard024f1992003-12-10 16:43:49 +0000184reference = "startDocument:startElement foo {'url': 'tst'}:" + \
185 "characters: bar:endElement foo:endDocument:"
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000186if log != reference:
Daniel Veillard024f1992003-12-10 16:43:49 +0000187 print "Error got: %s" % log
Daniel Veillard69839ba2006-06-06 13:27:03 +0000188 print "Expected: %s" % reference</pre><p>The key object in that test is the handler, it provides a number of
189entrypoints which can be called by the parser as it makes progresses to
190indicatethe information set obtained. The full set of callback is larger than
191whatthe callback class in that specific example implements (see the
192SAXdefinition for a complete list). The wrapper will only call those supplied
193bythe object when activated. The startElement receives the names of the
194elementand a dictionary containing the attributes carried by this element.</p><p>Also note that the reference string generated from the callback shows
195asingle character call even though the string "bar" is passed to the
196parserfrom 2 different call to parseChunk()</p><h3>xpath.py:</h3><p>This is a basic test of XPath wrappers support</p><pre>import libxml2
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000197
Daniel Veillard024f1992003-12-10 16:43:49 +0000198doc = libxml2.parseFile("tst.xml")
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000199ctxt = doc.xpathNewContext()
Daniel Veillard024f1992003-12-10 16:43:49 +0000200res = ctxt.xpathEval("//*")
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000201if len(res) != 2:
Daniel Veillard024f1992003-12-10 16:43:49 +0000202 print "xpath query: wrong node set size"
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000203 sys.exit(1)
Daniel Veillard024f1992003-12-10 16:43:49 +0000204if res[0].name != "doc" or res[1].name != "foo":
205 print "xpath query: wrong node set value"
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000206 sys.exit(1)
207doc.freeDoc()
Daniel Veillard69839ba2006-06-06 13:27:03 +0000208ctxt.xpathFreeContext()</pre><p>This test parses a file, then create an XPath context to evaluate
209XPathexpression on it. The xpathEval() method execute an XPath query and
210returnsthe result mapped in a Python way. String and numbers are natively
211converted,and node sets are returned as a tuple of libxml2 Python nodes
212wrappers. Likethe document, the XPath context need to be freed explicitly,
213also not thatthe result of the XPath query may point back to the document
214tree and hencethe document must be freed after the result of the query is
215used.</p><h3>xpathext.py:</h3><p>This test shows how to extend the XPath engine with functions written
216inpython:</p><pre>import libxml2
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000217
218def foo(ctx, x):
219 return x + 1
220
Daniel Veillard024f1992003-12-10 16:43:49 +0000221doc = libxml2.parseFile("tst.xml")
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000222ctxt = doc.xpathNewContext()
Daniel Veillard024f1992003-12-10 16:43:49 +0000223libxml2.registerXPathFunction(ctxt._o, "foo", None, foo)
224res = ctxt.xpathEval("foo(1)")
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000225if res != 2:
Daniel Veillard024f1992003-12-10 16:43:49 +0000226 print "xpath extension failure"
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000227doc.freeDoc()
Daniel Veillard69839ba2006-06-06 13:27:03 +0000228ctxt.xpathFreeContext()</pre><p>Note how the extension function is registered with the context (but
229thatpart is not yet finalized, this may change slightly in the future).</p><h3>tstxpath.py:</h3><p>This test is similar to the previous one but shows how the
230extensionfunction can access the XPath evaluation context:</p><pre>def foo(ctx, x):
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000231 global called
232
233 #
234 # test that access to the XPath evaluation contexts
235 #
236 pctxt = libxml2.xpathParserContext(_obj=ctx)
237 ctxt = pctxt.context()
238 called = ctxt.function()
Daniel Veillard69839ba2006-06-06 13:27:03 +0000239 return x + 1</pre><p>All the interfaces around the XPath parser(or rather evaluation)
240contextare not finalized, but it should be sufficient to do contextual work
241at theevaluation point.</p><h3>Memory debugging:</h3><p>last but not least, all tests starts with the following prologue:</p><pre>#memory debug specific
Daniel Veillard1177ca42003-04-26 22:29:54 +0000242libxml2.debugMemory(1)</pre><p>and ends with the following epilogue:</p><pre>#memory debug specific
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000243libxml2.cleanupParser()
244if libxml2.debugMemory(1) == 0:
Daniel Veillard024f1992003-12-10 16:43:49 +0000245 print "OK"
Daniel Veillard6dbcaf82002-02-20 14:37:47 +0000246else:
Daniel Veillard024f1992003-12-10 16:43:49 +0000247 print "Memory leak %d bytes" % (libxml2.debugMemory(1))
Daniel Veillard69839ba2006-06-06 13:27:03 +0000248 libxml2.dumpMemory()</pre><p>Those activate the memory debugging interface of libxml2 where
249allallocated block in the library are tracked. The prologue then cleans up
250thelibrary state and checks that all allocated memory has been freed. If not
251itcalls dumpMemory() which saves that list in a <code>.memdump</code>file.</p><p><a href="bugs.html">Daniel Veillard</a></p></td></tr></table></td></tr></table></td></tr></table></td></tr></table></td></tr></table></body></html>