Added pointer to Tcl bindings, Daniel
[platform/upstream/libxslt.git] / doc / python.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
2 <html>
3 <head>
4 <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
5 <style type="text/css"><!--
6 TD {font-size: 14pt; font-family: Verdana,Arial,Helvetica}
7 BODY {font-size: 14pt; font-family: Verdana,Arial,Helvetica; margin-top: 2em; margin-left: 0em; margin-right: 0em}
8 H1 {font-size: 20pt; font-family: Verdana,Arial,Helvetica}
9 H2 {font-size: 18pt; font-family: Verdana,Arial,Helvetica}
10 H3 {font-size: 16pt; font-family: Verdana,Arial,Helvetica}
11 A:link, A:visited, A:active { text-decoration: underline }
12 --></style>
13 <title>Python and bindings</title>
14 </head>
15 <body bgcolor="#8b7765" text="#000000" link="#000000" vlink="#000000">
16 <table border="0" width="100%" cellpadding="5" cellspacing="0" align="center"><tr>
17 <td width="100">
18 <a href="http://www.gnome.org/"><img src="smallfootonly.gif" alt="Gnome Logo"></a><a href="http://www.redhat.com"><img src="redhat.gif" alt="Red Hat Logo"></a>
19 </td>
20 <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">
21 <h1>The XSLT C library for Gnome</h1>
22 <h2>Python and bindings</h2>
23 </td></tr></table></td></tr></table></td>
24 </tr></table>
25 <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>
26 <td valign="top" width="200" bgcolor="#8b7765"><table border="0" cellspacing="0" cellpadding="1" width="100%" bgcolor="#000000"><tr><td>
27 <table width="100%" border="0" cellspacing="1" cellpadding="3">
28 <tr><td colspan="1" bgcolor="#eecfa1" align="center"><center><b>Main Menu</b></center></td></tr>
29 <tr><td bgcolor="#fffacd"><ul>
30 <li><a href="index.html">Home</a></li>
31 <li><a href="intro.html">Introduction</a></li>
32 <li><a href="docs.html">Documentation</a></li>
33 <li><a href="bugs.html">Reporting bugs and getting help</a></li>
34 <li><a href="help.html">How to help</a></li>
35 <li><a href="downloads.html">Downloads</a></li>
36 <li><a href="FAQ.html">FAQ</a></li>
37 <li><a href="news.html">News</a></li>
38 <li><a href="xsltproc2.html">The xsltproc tool</a></li>
39 <li><a href="docbook.html">DocBook</a></li>
40 <li><a href="API.html">The programming API</a></li>
41 <li><a href="python.html">Python and bindings</a></li>
42 <li><a href="internals.html">Library internals</a></li>
43 <li><a href="extensions.html">Writing extensions</a></li>
44 <li><a href="contribs.html">Contributions</a></li>
45 <li>
46 <a href="xslt.html">flat page</a>, <a href="site.xsl">stylesheet</a>
47 </li>
48 </ul></td></tr>
49 </table>
50 <table width="100%" border="0" cellspacing="1" cellpadding="3">
51 <tr><td colspan="1" bgcolor="#eecfa1" align="center"><center><b>API Indexes</b></center></td></tr>
52 <tr><td bgcolor="#fffacd"><ul>
53 <li><a href="APIchunk0.html">Alphabetic</a></li>
54 <li><a href="APIconstructors.html">Constructors</a></li>
55 <li><a href="APIfunctions.html">Functions/Types</a></li>
56 <li><a href="APIfiles.html">Modules</a></li>
57 <li><a href="APIsymbols.html">Symbols</a></li>
58 </ul></td></tr>
59 </table>
60 <table width="100%" border="0" cellspacing="1" cellpadding="3">
61 <tr><td colspan="1" bgcolor="#eecfa1" align="center"><center><b>Related links</b></center></td></tr>
62 <tr><td bgcolor="#fffacd"><ul>
63 <li><a href="tutorial/libxslttutorial.html">Tutorial</a></li>
64 <li><a href="xsltproc.html">Man page for xsltproc</a></li>
65 <li><a href="http://mail.gnome.org/archives/xslt/">Mail archive</a></li>
66 <li><a href="http://xmlsoft.org/">XML libxml</a></li>
67 <li><a href="http://phd.cs.unibo.it/gdome2/">DOM gdome2</a></li>
68 <li><a href="ftp://xmlsoft.org/">FTP</a></li>
69 <li><a href="http://www.fh-frankfurt.de/~igor/projects/libxml/">Windows binaries</a></li>
70 <li><a href="http://garypennington.net/libxml2/">Solaris binaries</a></li>
71 <li><a href="http://bugzilla.gnome.org/buglist.cgi?product=libxslt">Bug Tracker</a></li>
72 <li><a href="http://xsldbg.sourceforge.net/">Xsldbg Debugger</a></li>
73 </ul></td></tr>
74 </table>
75 </td></tr></table></td>
76 <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">
77 <p>There is a number of language bindings and wrappers available for libxml2,
78 the list below is not exhaustive. Please contact the <a href="http://mail.gnome.org/mailman/listinfo/xml-bindings">xml-bindings@gnome.org</a>
79 (<a href="http://mail.gnome.org/archives/xml-bindings/">archives</a>) in
80 order to get updates to this list or to discuss the specific topic of libxml2
81 or libxslt wrappers or bindings:</p>
82 <ul>
83 <li>
84 <a href="http://mail.gnome.org/archives/xml/2001-March/msg00014.html">Matt
85     Sergeant</a>
86      developped <a href="http://axkit.org/download/">XML::LibXML and
87      XML::LibXSLT</a>, a perl wrapper for libxml2/libxslt as part of the <a href="http://axkit.com/">AxKit XML application server</a>
88 </li>
89 <li>
90 <a href="mailto:dkuhlman@cutter.rexx.com">Dave Kuhlman</a>
91      provides and earlier version of the libxml/libxslt <a href="http://www.rexx.com/~dkuhlman">wrappers for Python</a>
92 </li>
93 <li>Petr Kozelka provides <a href="http://sourceforge.net/projects/libxml2-pas">Pascal units to glue
94     libxml2</a> with Kylix, Delphi and other Pascal compilers</li>
95 <li>Wai-Sun &quot;Squidster&quot; Chia provides <a href="http://www.rubycolor.org/arc/redist/">bindings for Ruby</a>  and
96     libxml2 bindings are also available in Ruby through the <a href="http://libgdome-ruby.berlios.de/">libgdome-ruby</a> module
97     maintained by Tobias Peters.</li>
98 <li>Steve Ball and contributors maintains
99     <a href="http://tclxml.sourceforge.net/">libxml2 and libxslt bindings for
100     Tcl</a>
101 </li>
102 </ul>
103 <p>The libxslt Python module depends on the <a href="http://xmlsoft.org/python.html">libxml2 Python</a> module.
104 </p>
105 <p>The distribution includes a set of Python bindings, which are garanteed to
106 be maintained as part of the library in the future, though the Python
107 interface have not yet reached the maturity of the C API. The distribution
108 includes a set of examples and regression tests for the python bindings in
109 the <code>python/tests</code> directory. Here are some excepts from those
110 tests:</p>
111 <h3>basic.py:</h3>
112 <p>This is a basic test of XSLT interfaces: loading a stylesheet and
113 a document, transforming the document and saving the result.</p>
114 <pre>import libxml2
115 import libxslt
116
117 styledoc = libxml2.parseFile(&quot;test.xsl&quot;)
118 style = libxslt.parseStylesheetDoc(styledoc)
119 doc = libxml2.parseFile(&quot;test.xml&quot;)
120 result = style.applyStylesheet(doc, None)
121 style.saveResultToFilename(&quot;foo&quot;, result, 0)
122 style.freeStylesheet()
123 doc.freeDoc()
124 result.freeDoc()</pre>
125 <p>The Python module is called libxslt, you will also need the libxml2 module
126 for the operations on XML trees. Let's have a look at the objects manipulated
127 in that example and how is the processing done:</p>
128 <ul>
129 <li>
130 <code>styledoc</code>: is a libxml2 document tree. It is obtained by
131     parsing the XML file &quot;test.xsl&quot; containing the stylesheet.</li>
132 <li>
133 <code>style</code>: this is a precompiled stylesheet ready to be used
134     by the following transformations (note the plural form, multiple
135     transformations can resuse the same stylesheet).</li>
136 <li>
137 <code>doc</code>: this is the document to apply the transformation to.
138     In this case it is simply generated by parsing it from a file but any
139     other processing is possible as long as one get a libxml2 Doc. Note
140     that HTML tree are suitable for XSLT processing in libxslt. This is
141     actually how this page is generated !</li>
142 <li>
143 <code>result</code>: this is a document generated by applying the
144     stylesheet to the document. Note that some of the stylesheet informations
145     may be related to the serialization of that document and as in this
146     example a specific saveResultToFilename() method of the stylesheet
147     should be used to save it to a file (in that case to &quot;foo&quot;).</li>
148 </ul>
149 <p>Also note the need to explicitely deallocate documents with freeDoc()
150 except for the stylesheet document which is freed when its compiled form
151 is garbage collected.</p>
152 <h3>extfunc.py:</h3>
153 <p>This one is a far more complex test. It shows how to modify the behaviour
154 of an XSLT transformation by passing parameters and how to extend the XSLT
155 engine with functions defined in python:</p>
156 <pre>import libxml2
157 import libxslt
158 import string
159
160 nodeName = None
161 def f(ctx, str):
162     global nodeName
163
164     #
165     # Small check to verify the context is correcly accessed
166     #
167     try:
168         pctxt = libxslt.xpathParserContext(_obj=ctx)
169         ctxt = pctxt.context()
170         tctxt = ctxt.transformContext()
171         nodeName = tctxt.insertNode().name
172     except:
173         pass
174
175     return string.upper(str)
176
177 libxslt.registerExtModuleFunction(&quot;foo&quot;, &quot;http://example.com/foo&quot;, f)</pre>
178 <p> This code defines and register an extension function. Note that the
179 function can be bound to any name (foo) and how the binding is also
180 associated to a namespace name &quot;http://example.com/foo&quot;. From an
181 XSLT point of view the function just returns an upper case version of the
182 string passed as a parameter. But the first part of the function also 
183 read some contextual information from the current XSLT processing environement,
184 in that case it looks for the current insertion node in the resulting output
185 (either the resulting document or the Result Value Tree being generated), and
186 saves it to a global variable for checking that the access actually worked.
187 </p>
188 <p> For more informations on the xpathParserContext and transformContext
189 objects check the <a href="internals.html">libray internals description</a>.
190 The pctxt is actually an object from a class derived from the
191 libxml2.xpathParserContext() with just a couple more properties including
192 the possibility to look up the XSLT transformation context from the XPath
193 context.
194 </p>
195 <pre>
196 styledoc = libxml2.parseDoc(&quot;&quot;&quot;
197 &lt;xsl:stylesheet version='1.0'
198   xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
199   xmlns:foo='http://example.com/foo'
200   xsl:exclude-result-prefixes='foo'&gt;
201
202   &lt;xsl:param name='bar'&gt;failure&lt;/xsl:param&gt;
203   &lt;xsl:template match='/'&gt;
204     &lt;article&gt;&lt;xsl:value-of select='foo:foo($bar)'/&gt;&lt;/article&gt;
205   &lt;/xsl:template&gt;
206 &lt;/xsl:stylesheet&gt;
207 &quot;&quot;&quot;)</pre>
208 <p> Here is a simple example of how to read an XML document from a python
209 string with libxml2. Note how this stylesheet:
210 </p>
211 <ul>
212 <li> Uses a global parameter <code>bar</code>
213 </li>
214 <li> Reference the extension function f 
215 </li>
216 <li> how the Namespace name &quot;http://example.com/foo&quot; has to be bound to
217      a prefix
218 </li>
219 <li> how that prefix is excluded from the output 
220 </li>
221 <li> how the function is called from the select 
222 </li>
223 </ul>
224 <pre>style = libxslt.parseStylesheetDoc(styledoc)
225 doc = libxml2.parseDoc(&quot;&lt;doc/&gt;&quot;)
226 result = style.applyStylesheet(doc, { &quot;bar&quot;: &quot;'success'&quot; })
227 style.freeStylesheet()
228 doc.freeDoc()</pre>
229 <p> that part is identical, to the basic example except that the
230 transformation is passed a dictionnary of parameters. Note that the
231 string passed &quot;success&quot; had to be quoted, otherwise it is interpreted
232 as an XPath query for the childs of root named &quot;success&quot;.
233 </p>
234 <pre>
235 root = result.children
236 if root.name != &quot;article&quot;:
237     print &quot;Unexpected root node name&quot;
238     sys.exit(1)
239 if root.content != &quot;SUCCESS&quot;:
240     print &quot;Unexpected root node content, extension function failed&quot;
241     sys.exit(1)
242 if nodeName != 'article':
243     print &quot;The function callback failed to access its context&quot;
244     sys.exit(1)
245
246 result.freeDoc()
247 </pre>
248 <p> That part just verifies that the transformation worked, that the parameter
249 got properly passed to the engine, that the function f() got called and that
250 it properly accessed the context to find the name of the insertion node.
251
252 </p>
253 <h3>pyxsltproc.py:</h3>
254 <p> this module is a bit too long to be described there but it is basically
255 a rewrite of the xsltproc command line interface of libxslt in Python. It
256 provides nearly all the functionalities of xsltproc and can be used as a base
257 module to write Python customized XSLT processors. One of the thing
258 to notice are:
259 </p>
260 <pre>libxml2.lineNumbersDefault(1)
261 libxml2.substituteEntitiesDefault(1)
262 </pre>
263 <p> those two calls in the main() function are needed to force the libxml2
264 processor to generate DOM trees compliant with the XPath data model.
265
266 </p>
267 <p><a href="mailto:daniel@veillard.com">Daniel Veillard</a></p>
268 </td></tr></table></td></tr></table></td></tr></table></td>
269 </tr></table></td></tr></table>
270 </body>
271 </html>