1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" |
---|
2 | "http://www.w3.org/TR/html4/loose.dtd"> |
---|
3 | <html> |
---|
4 | <head> |
---|
5 | <title>The XSLT C library for Gnome</title> |
---|
6 | <meta name="GENERATOR" content="amaya 5.1"> |
---|
7 | <meta http-equiv="Content-Type" content="text/html"> |
---|
8 | </head> |
---|
9 | |
---|
10 | <body bgcolor="#ffffff"> |
---|
11 | <h1 align="center">The XSLT C library for Gnome</h1> |
---|
12 | |
---|
13 | <h1 style="text-align: center">libxslt</h1> |
---|
14 | |
---|
15 | <p>Libxslt is the <a href="http://www.w3.org/TR/xslt">XSLT</a> C library |
---|
16 | developed for the Gnome project. XSLT itself is a an XML language to define |
---|
17 | transformation for XML. Libxslt is based on <a |
---|
18 | href="http://xmlsoft.org/">libxml2</a> the XML C library developed for the |
---|
19 | Gnome project. It also implements most of the <a |
---|
20 | href="http://www.exslt.org/">EXSLT</a> set of processor-portable extensions |
---|
21 | functions and some of Saxon's evaluate and expressions extensions.</p> |
---|
22 | |
---|
23 | <p>People can either embed the library in their application or use xsltproc |
---|
24 | the command line processing tool. This library is free software and can be |
---|
25 | reused in commercial applications (see the <a href="intro.html">intro</a>)</p> |
---|
26 | |
---|
27 | <p>External documents:</p> |
---|
28 | <ul> |
---|
29 | <li>John Fleck wrote <a href="tutorial/libxslttutorial.html">a tutorial for |
---|
30 | libxslt</a></li> |
---|
31 | <li><a href="xsltproc.html">xsltproc user manual</a></li> |
---|
32 | <li><a href="http://xmlsoft.org/">the libxml documentation</a></li> |
---|
33 | </ul> |
---|
34 | |
---|
35 | <p></p> |
---|
36 | |
---|
37 | <p>Logo designed by <a href="mailto:liyanage@access.ch">Marc Liyanage</a>.</p> |
---|
38 | |
---|
39 | <h2><a name="Introducti">Introduction</a></h2> |
---|
40 | |
---|
41 | <p>This document describes <a href="http://xmlsoft.org/XSLT/">libxslt</a>, |
---|
42 | the <a href="http://www.w3.org/TR/xslt">XSLT</a> C library developed for the |
---|
43 | <a href="http://www.gnome.org/">Gnome</a> project.</p> |
---|
44 | |
---|
45 | <p>Here are some key points about libxslt:</p> |
---|
46 | <ul> |
---|
47 | <li>Libxslt is a C implementation</li> |
---|
48 | <li>Libxslt is based on libxml for XML parsing, tree manipulation and XPath |
---|
49 | support</li> |
---|
50 | <li>It is written in plain C, making as few assumptions as possible, and |
---|
51 | sticking closely to ANSI C/POSIX for easy embedding. Should works on |
---|
52 | Linux/Unix/Windows.</li> |
---|
53 | <li>This library is released under the <a |
---|
54 | href="http://www.opensource.org/licenses/mit-license.html">MIT |
---|
55 | Licence</a></li> |
---|
56 | <li>Though not designed primarily with performances in mind, libxslt seems |
---|
57 | to be a relatively fast processor.</li> |
---|
58 | </ul> |
---|
59 | |
---|
60 | <h2><a name="Documentat">Documentation</a></h2> |
---|
61 | |
---|
62 | <p>There are some on-line resources about using libxslt:</p> |
---|
63 | <ol> |
---|
64 | <li>Check the <a href="html/libxslt-lib.html#LIBXSLT-LIB">API |
---|
65 | documentation</a> automatically extracted from code comments (using <a |
---|
66 | href="http://cvs.gnome.org/bonsai/rview.cgi?cvsroot=/cvs/gnome&dir=gtk-doc">gtk |
---|
67 | doc</a>).</li> |
---|
68 | <li>Look at the <a href="http://mail.gnome.org/archives/xslt/">mailing-list |
---|
69 | archive</a>.</li> |
---|
70 | <li>Of course since libxslt is based on libxml, it's a good idea to at |
---|
71 | least read <a href="http://xmlsoft.org/">libxml description</a></li> |
---|
72 | </ol> |
---|
73 | |
---|
74 | <h2><a name="Reporting">Reporting bugs and getting help</a></h2> |
---|
75 | |
---|
76 | <p>If you need help with the XSLT language itself, here are a number of |
---|
77 | useful resources:</p> |
---|
78 | <ul> |
---|
79 | <li>I strongly suggest to subscribe to <a |
---|
80 | href="http://www.mulberrytech.com/xsl/xsl-list">XSL-list</a>, check <a |
---|
81 | href="http://www.biglist.com/lists/xsl-list/archives/">the XSL-list |
---|
82 | archives</a></li> |
---|
83 | <li>The <a href="http://www.dpawson.co.uk/xsl/xslfaq.html">XSL FAQ</a>.</li> |
---|
84 | <li>The <a |
---|
85 | href="http://www.nwalsh.com/docs/tutorials/xsl/xsl/slides.html">tutorial</a> |
---|
86 | written by Paul Grosso and Norman Walsh is a very good on-line |
---|
87 | introdution to the language.</li> |
---|
88 | <li>The <a |
---|
89 | href="http://www.zvon.org/xxl/XSLTutorial/Books/Book1/index.html">only |
---|
90 | Zvon XSLT tutorial</a> details a lot of constructs with examples.</li> |
---|
91 | <li><a href="http://www.jenitennison.com/xslt/index.html">Jeni Tennison's |
---|
92 | XSLT</a> pages provide links to a lot of answers</li> |
---|
93 | <li>the <a href="http://incrementaldevelopment.com/xsltrick/">Gallery of |
---|
94 | XSLT Tricks</a> provides non-standard use case of XSLT</li> |
---|
95 | <li>And I suggest to buy Michael Kay "XSLT Programmer's Reference" book |
---|
96 | published by <a href="http://www.wrox.com/">Wrox</a> if you plan to work |
---|
97 | seriously with XSLT in the future.</li> |
---|
98 | </ul> |
---|
99 | |
---|
100 | <p>Well, bugs or missing features are always possible, and I will make a |
---|
101 | point of fixing them in a timely fashion. The best way to report a bug is to |
---|
102 | use the <a href="http://bugzilla.gnome.org/buglist.cgi?product=libxslt">Gnome |
---|
103 | bug tracking database</a> (make sure to use the "libxslt" module name). I |
---|
104 | look at reports there regularly and it's good to have a reminder when a bug |
---|
105 | is still open. Be sure to specify that the bug is for the package libxslt.</p> |
---|
106 | |
---|
107 | <p>There is also a mailing-list <a |
---|
108 | href="mailto:xslt@gnome.org">xslt@gnome.org</a> for libxslt, with an <a |
---|
109 | href="http://mail.gnome.org/archives/xslt/">on-line archive</a>. To subscribe |
---|
110 | to this list, please visit the <a |
---|
111 | href="http://mail.gnome.org/mailman/listinfo/xslt">associated Web</a> page |
---|
112 | and follow the instructions.</p> |
---|
113 | |
---|
114 | <p>Alternatively, you can just send the bug to the <a |
---|
115 | href="mailto:xslt@gnome.org">xslt@gnome.org</a> list, if it's really libxslt |
---|
116 | related I will approve it.. Please do not send me mail directly especially |
---|
117 | for portability problem, it makes things really harder to track and in some |
---|
118 | cases I'm not the best person to answer a given question, ask the list |
---|
119 | instead. <strong>Do not send code, I won't debug it</strong> (but patches are |
---|
120 | really appreciated!).</p> |
---|
121 | |
---|
122 | <p>Check the following too <span style="color: #E50000">before |
---|
123 | posting</span>:</p> |
---|
124 | <ul> |
---|
125 | <li><a href="search.php">use the search engine</a> to get informations |
---|
126 | related to your problem.</li> |
---|
127 | <li>make sure you are <a href="ftp://xmlsoft.org/">using a recent |
---|
128 | version</a>, and that the problem still shows up in those</li> |
---|
129 | <li>check the <a href="http://mail.gnome.org/archives/xslt/">list |
---|
130 | archives</a> to see if the problem was reported already, in this case |
---|
131 | there is probably a fix available, similarly check the <a |
---|
132 | href="http://bugzilla.gnome.org/buglist.cgi?product=libxslt">registered |
---|
133 | open bugs</a></li> |
---|
134 | <li>make sure you can reproduce the bug with xsltproc, a very useful thing |
---|
135 | to do is run the transformation with -v argument and redirect the |
---|
136 | standard error to a file, then search in this file for the transformation |
---|
137 | logs just preceding the possible problem</li> |
---|
138 | <li>Please send the command showing the error as well as the input and |
---|
139 | stylesheet (as an attachment)</li> |
---|
140 | </ul> |
---|
141 | |
---|
142 | <p>Then send the bug with associated informations to reproduce it to the <a |
---|
143 | href="mailto:xslt@gnome.org">xslt@gnome.org</a> list; if it's really libxslt |
---|
144 | related I will approve it. Please do not send mail to me directly, it makes |
---|
145 | things really hard to track and in some cases I am not the best person to |
---|
146 | answer a given question, ask on the list.</p> |
---|
147 | |
---|
148 | <p>To <span style="color: #E50000">be really clear about support</span>:</p> |
---|
149 | <ul> |
---|
150 | <li>Support or help <span style="color: #E50000">request MUST be sent to |
---|
151 | the list or on bugzilla</span> in case of problems, so that the Question |
---|
152 | and Answers can be shared publicly. Failing to do so carries the implicit |
---|
153 | message "I want free support but I don't want to share the benefits with |
---|
154 | others" and is not welcome.</li> |
---|
155 | <li>There is <span style="color: #E50000">no garantee for support</span>, |
---|
156 | if your question remains unanswered after a week, repost it, making sure |
---|
157 | you gave all the detail needed and the informations requested.</li> |
---|
158 | <li>Failing to provide informations as requested or double checking first |
---|
159 | for prior feedback also carries the implicit message "the time of the |
---|
160 | library maintainers is less valuable than my time" and might not be |
---|
161 | welcome.</li> |
---|
162 | </ul> |
---|
163 | |
---|
164 | <p>Of course, bugs reports with a suggested patch for fixing them will |
---|
165 | probably be processed faster.</p> |
---|
166 | |
---|
167 | <p>If you're looking for help, a quick look at <a |
---|
168 | href="http://mail.gnome.org/archives/xslt/">the list archive</a> may actually |
---|
169 | provide the answer, I usually send source samples when answering libxslt |
---|
170 | usage questions. The <a |
---|
171 | href="html/libxslt-lib.html#LIBXSLT-LIB">auto-generated documentation</a> is |
---|
172 | not as polished as I would like (I need to learn more about Docbook), but |
---|
173 | it's a good starting point.</p> |
---|
174 | |
---|
175 | <h2><a name="help">How to help</a></h2> |
---|
176 | |
---|
177 | <p>You can help the project in various ways, the best thing to do first is to |
---|
178 | subscribe to the mailing-list as explained before, check the <a |
---|
179 | href="http://mail.gnome.org/archives/xslt/">archives </a>and the <a |
---|
180 | href="http://bugzilla.gnome.org/buglist.cgi?product=libxslt">Gnome bug |
---|
181 | database:</a>:</p> |
---|
182 | <ol> |
---|
183 | <li>provide patches when you find problems</li> |
---|
184 | <li>provide the diffs when you port libxslt to a new platform. They may not |
---|
185 | be integrated in all cases but help pinpointing portability problems |
---|
186 | and</li> |
---|
187 | <li>provide documentation fixes (either as patches to the code comments or |
---|
188 | as HTML diffs).</li> |
---|
189 | <li>provide new documentations pieces (translations, examples, etc ...)</li> |
---|
190 | <li>Check the TODO file and try to close one of the items</li> |
---|
191 | <li>take one of the points raised in the archive or the bug database and |
---|
192 | provide a fix. <a href="mailto:daniel@veillard.com">Get in touch with me |
---|
193 | </a>before to avoid synchronization problems and check that the suggested |
---|
194 | fix will fit in nicely :-)</li> |
---|
195 | </ol> |
---|
196 | |
---|
197 | <h2><a name="Downloads">Downloads</a></h2> |
---|
198 | |
---|
199 | <p>The latest versions of libxslt can be found on <a |
---|
200 | href="ftp://xmlsoft.org/">xmlsoft.org</a> (<a |
---|
201 | href="ftp://speakeasy.rpmfind.net/pub/libxml/">Seattle</a>, <a |
---|
202 | href="ftp://fr.rpmfind.net/pub/libxml/">France</a>) or on the <a |
---|
203 | href="ftp://ftp.gnome.org/pub/GNOME/MIRRORS.html">Gnome FTP server</a> as a |
---|
204 | <a href="ftp://ftp.gnome.org/pub/GNOME/sources/libxslt/1.0/">source |
---|
205 | archive</a>, Antonin Sprinzl also provides <a |
---|
206 | href="ftp://gd.tuwien.ac.at/pub/libxml/">a mirror in Austria</a>. (NOTE that |
---|
207 | you need the <a href="http://rpmfind.net/linux/RPM/libxml2.html">libxml2</a>, |
---|
208 | <a href="http://rpmfind.net/linux/RPM/libxml2-devel.html">libxml2-devel</a>, |
---|
209 | <a href="http://rpmfind.net/linux/RPM/libxslt.html">libxslt</a> and <a |
---|
210 | href="http://rpmfind.net/linux/RPM/libxslt-devel.html">libxslt-devel</a> |
---|
211 | packages installed to compile applications using libxslt.) <a |
---|
212 | href="mailto:igor@zlatkovic.com">Igor Zlatkovic</a> is now the maintainer of |
---|
213 | the Windows port, <a |
---|
214 | href="http://www.zlatkovic.com/projects/libxml/index.html">he provides |
---|
215 | binaries</a>. <a href="mailto:Gary.Pennington@sun.com">Gary Pennington</a> |
---|
216 | provides <a href="http://garypennington.net/libxml2/">Solaris binaries</a>. |
---|
217 | <a href="mailto:Steve.Ball@zveno.com">Steve Ball</a> provides <a |
---|
218 | href="http://www.zveno.com/open_source/libxml2xslt.html">Mac Os X |
---|
219 | binaries</a>.</p> |
---|
220 | |
---|
221 | <p><a name="Contribs">Contribs:</a></p> |
---|
222 | |
---|
223 | <p>I do accept external contributions, especially if compiling on another |
---|
224 | platform, get in touch with me to upload the package. I will keep them in the |
---|
225 | <a href="ftp://xmlsoft.org/contribs/">contrib directory</a></p> |
---|
226 | |
---|
227 | <p>Libxslt is also available from CVS:</p> |
---|
228 | <ul> |
---|
229 | <li><p>The <a |
---|
230 | href="http://cvs.gnome.org/bonsai/rview.cgi?cvsroot=/cvs/gnome&dir=libxslt">Gnome |
---|
231 | CVS base</a>. Check the <a |
---|
232 | href="http://developer.gnome.org/tools/cvs.html">Gnome CVS Tools</a> |
---|
233 | page; the CVS module is <b>libxslt</b>.</p> |
---|
234 | </li> |
---|
235 | <li><a href="ftp://xmlsoft.org/XSLT/cvs-snapshot.tar.gz">daily snapshots |
---|
236 | from CVS</a> are also provided</li> |
---|
237 | </ul> |
---|
238 | |
---|
239 | <h2><a name="FAQ">FAQ</a></h2> |
---|
240 | <ol> |
---|
241 | <li><em>passing parameters on the xsltproc command line doesn't work</em> |
---|
242 | <p><em>xsltproc --param test alpha foo.xsl foo.xml</em></p> |
---|
243 | <p><em>the param does not get passed and ends up as ""</em></p> |
---|
244 | <p>In a nutshell do a double escaping at the shell prompt:</p> |
---|
245 | <p>xsltproc --param test "'alpha'" foo.xsl foo.xml</p> |
---|
246 | <p>i.e. the string value is surrounded by " and ' then terminated by ' |
---|
247 | and ". Libxslt interpret the parameter values as XPath expressions, so |
---|
248 | the string -><code>alpha</code><- is intepreted as the node set |
---|
249 | matching this string. You really want -><code>'alpha'</code><- to |
---|
250 | be passed to the processor. And to allow this you need to escape the |
---|
251 | quotes at the shell level using -><code>"'alpha'"</code><- .</p> |
---|
252 | <p>or use</p> |
---|
253 | <p>xsltproc --stringparam test alpha foo.xsl foo.xml</p> |
---|
254 | </li> |
---|
255 | </ol> |
---|
256 | |
---|
257 | <h2><a name="News">News</a></h2> |
---|
258 | |
---|
259 | <h3>CVS only : check the <a |
---|
260 | href="http://cvs.gnome.org/lxr/source/libxslt/ChangeLog">Changelog</a> file |
---|
261 | for a really accurate description</h3> |
---|
262 | |
---|
263 | <h3>1.0.24: Jan 14 2003</h3> |
---|
264 | <ul> |
---|
265 | <li>bug fixes: imported global varables, python bindings (Stéphane Bidoul), |
---|
266 | EXSLT memory leak (Charles Bozeman), namespace generation on |
---|
267 | xsl:attribute, space handling with imports (Daniel Stodden), |
---|
268 | extension-element-prefixes (Josh Parsons), comments within xsl:text (Matt |
---|
269 | Sergeant), superfluous xmlns generation, XInclude related bug for |
---|
270 | numbering, EXSLT strings (Alexey Efimov), attribute-sets computation on |
---|
271 | imports, extension module init and shutdown callbacks not called</li> |
---|
272 | <li>HP-UX portability (Alexey Efimov), Windows makefiles (Igor and Stephane |
---|
273 | Bidoul), VMS makefile updates (Craig A. Berry)</li> |
---|
274 | <li>adds xsltGetProfileInformation() (Michael Rothwell)</li> |
---|
275 | <li>fix the API generation scripts</li> |
---|
276 | <li>API to provide the sorting routines (Richard Jinks)</li> |
---|
277 | <li>added XML description of the EXSLT API</li> |
---|
278 | <li>added ESXLT URI (un)escaping (Jörg Walter)</li> |
---|
279 | <li>Some memory leaks have been found and fixed</li> |
---|
280 | <li>document() now support fragment identifiers in URIs</li> |
---|
281 | </ul> |
---|
282 | |
---|
283 | <h3>1.0.23: Nov 17 2002</h3> |
---|
284 | <ul> |
---|
285 | <li>Windows build cleanup (Igor)</li> |
---|
286 | <li>Unix build and RPM packaging cleanup</li> |
---|
287 | <li>Improvement of the python bindings: extension functions and activating |
---|
288 | EXSLT</li> |
---|
289 | <li>various bug fixes: number formatting, portability for bounded string |
---|
290 | functions, CData nodes, key(), @*[...] patterns</li> |
---|
291 | <li>Documentation improvements (John Fleck)</li> |
---|
292 | <li>added libxslt.m4 (Thomas Schraitle)</li> |
---|
293 | </ul> |
---|
294 | |
---|
295 | <h3>1.0.22: Oct 18 2002</h3> |
---|
296 | <ul> |
---|
297 | <li>Updates on the Windows Makefiles</li> |
---|
298 | <li>Added a security module, and a related set of new options to |
---|
299 | xsltproc</li> |
---|
300 | <li>Allowed per transformation error handler.</li> |
---|
301 | <li>Fixed a few bugs: node() semantic, URI escaping, media-type, attribute |
---|
302 | lists</li> |
---|
303 | </ul> |
---|
304 | |
---|
305 | <h3>1.0.21: Sep 26 2002</h3> |
---|
306 | <ul> |
---|
307 | <li>Bug fixes: match="node()", date:difference() (Igor and Charlie |
---|
308 | Bozeman), disable-output-escaping</li> |
---|
309 | <li>Python bindings: style.saveResultToString() from Ralf Mattes</li> |
---|
310 | <li>Logos from Marc Liyanage</li> |
---|
311 | <li>Mem leak fix from Nathan Myers</li> |
---|
312 | <li>Makefile: DESTDIR fix from Christophe Merlet, AMD x86_64 (Mandrake), |
---|
313 | Windows (Igor), Python detection</li> |
---|
314 | <li>Documentation improvements: John Fleck</li> |
---|
315 | </ul> |
---|
316 | |
---|
317 | <h3>1.0.20: Aug 23 2002</h3> |
---|
318 | <ul> |
---|
319 | <li>Windows makefile updates (Igor) and x86-64 (Frederic Crozat)</li> |
---|
320 | <li>fixed HTML meta tag saving for Mac/IE users</li> |
---|
321 | <li>possible leak patches from Nathan Myers</li> |
---|
322 | <li>try to handle document('') as best as possible depending in the |
---|
323 | cases</li> |
---|
324 | <li>Fixed the DocBook stylesheets handling problem</li> |
---|
325 | <li>Fixed a few XSLT reported errors</li> |
---|
326 | </ul> |
---|
327 | |
---|
328 | <h3>1.0.19: July 6 2002</h3> |
---|
329 | <ul> |
---|
330 | <li>EXSLT: dynamic functions and date support bug fixes (Mark Vakoc)</li> |
---|
331 | <li>xsl:number fix: Richard Jinks</li> |
---|
332 | <li>xsl:format-numbers fix: Ken Neighbors</li> |
---|
333 | <li>document('') fix: bug pointed by Eric van der Vlist</li> |
---|
334 | <li>xsl:message with terminate="yes" fixes: William Brack</li> |
---|
335 | <li>xsl:sort order support added: Ken Neighbors</li> |
---|
336 | <li>a few other bug fixes, some of them requiring the latest version of |
---|
337 | libxml2</li> |
---|
338 | </ul> |
---|
339 | |
---|
340 | <h3>1.0.18: May 27 2002</h3> |
---|
341 | <ul> |
---|
342 | <li>a number of bug fixes: attributes, extra namespace declarations |
---|
343 | (DocBook), xsl:include crash (Igor), documentation (Christian Cornelssen, |
---|
344 | Charles Bozeman and Geert Kloosterman), element-available (Richard |
---|
345 | Jinks)</li> |
---|
346 | <li>xsltproc can now list teh registered extensions thanks to Mark |
---|
347 | Vakoc</li> |
---|
348 | <li>there is a new API to save directly to a string |
---|
349 | xsltSaveResultToString() by Morus Walter</li> |
---|
350 | <li>specific error registration function for the python API</li> |
---|
351 | </ul> |
---|
352 | |
---|
353 | <h3>1.0.17: April 29 2002</h3> |
---|
354 | <ul> |
---|
355 | <li>cleanup in code, XSLT debugger support and Makefiles for Windows by |
---|
356 | Igor</li> |
---|
357 | <li>a C++ portability fix by Mark Vakoc</li> |
---|
358 | <li>EXSLT date improvement and regression tests by Charles Bozeman</li> |
---|
359 | <li>attempt to fix a bug in xsltProcessUserParamInternal</li> |
---|
360 | </ul> |
---|
361 | |
---|
362 | <h3>1.0.16: April 15 2002</h3> |
---|
363 | <ul> |
---|
364 | <li>Bug fixes: strip-space, URL in HTML output, error when xsltproc can't |
---|
365 | save</li> |
---|
366 | <li>portability fixes: OSF/1, IEEE on alphas, Windows, Python bindings</li> |
---|
367 | </ul> |
---|
368 | |
---|
369 | <h3>1.0.15: Mar 25 2002</h3> |
---|
370 | <ul> |
---|
371 | <li>Bugfixes: XPath, python Makefile, recursive attribute sets, @foo[..] |
---|
372 | templates</li> |
---|
373 | <li>Debug of memory alocation with valgind</li> |
---|
374 | <li>serious profiling leading to significant improvement for DocBook |
---|
375 | processing</li> |
---|
376 | <li>revamp of the Windows build</li> |
---|
377 | </ul> |
---|
378 | |
---|
379 | <h3>1.0.14: Mar 18 2002</h3> |
---|
380 | <ul> |
---|
381 | <li>Improvement in the XPath engine (libxml2-2.4.18)</li> |
---|
382 | <li>Nasty bug fix related to exslt:node-set</li> |
---|
383 | <li>Fixed the python Makefiles, cleanup of doc comments, Windows |
---|
384 | portability fixes</li> |
---|
385 | </ul> |
---|
386 | |
---|
387 | <h3>1.0.13: Mar 8 2002</h3> |
---|
388 | <ul> |
---|
389 | <li>a number of bug fixes including "namespace node have no parents"</li> |
---|
390 | <li>Improvement of the Python bindings</li> |
---|
391 | <li>Charles Bozeman provided fixes and regression tests for exslt date |
---|
392 | functions.</li> |
---|
393 | </ul> |
---|
394 | |
---|
395 | <h3>1.0.12: Feb 11 2002</h3> |
---|
396 | <ul> |
---|
397 | <li>Fixed the makefiles especially the python module ones</li> |
---|
398 | <li>half a dozen bugs fixes including 2 old ones</li> |
---|
399 | </ul> |
---|
400 | |
---|
401 | <h3>1.0.11: Feb 8 2002</h3> |
---|
402 | <ul> |
---|
403 | <li>Change of Licence to the <a |
---|
404 | href="http://www.opensource.org/licenses/mit-license.html">MIT |
---|
405 | Licence</a></li> |
---|
406 | <li>Added a beta version of the Python bindings, including support to |
---|
407 | extend the engine with functions written in Python</li> |
---|
408 | <li>A number of bug fixes</li> |
---|
409 | <li>Charlie Bozeman provided more EXSLT functions</li> |
---|
410 | <li>Portability fixes</li> |
---|
411 | </ul> |
---|
412 | |
---|
413 | <h3>1.0.10: Jan 14 2002</h3> |
---|
414 | <ul> |
---|
415 | <li>Windows fixes for Win32 from Igor</li> |
---|
416 | <li>Fixed the Solaris compilation trouble (Albert)</li> |
---|
417 | <li>Documentation changes and updates: John Fleck</li> |
---|
418 | <li>Added a stringparam option to avoid escaping hell at the shell |
---|
419 | level</li> |
---|
420 | <li>A few bug fixes</li> |
---|
421 | </ul> |
---|
422 | |
---|
423 | <h3>1.0.9: Dec 7 2001</h3> |
---|
424 | <ul> |
---|
425 | <li>Makefile patches from Peter Williams</li> |
---|
426 | <li>attempt to fix the compilation problem associated to prelinking</li> |
---|
427 | <li>obsoleted libxsltbreakpoint now deprecated and frozen to 1.0.8 API</li> |
---|
428 | <li>xsltproc return codes are now significant, John Fleck updated the |
---|
429 | documentation</li> |
---|
430 | <li>patch to allow as much as 40 steps in patterns (Marc Tardif), should be |
---|
431 | made dynamic really</li> |
---|
432 | <li>fixed a bug raised by Nik Clayton when using doctypes with HTML |
---|
433 | output</li> |
---|
434 | <li>patches from Keith Isdale to interface with xsltdebugger</li> |
---|
435 | </ul> |
---|
436 | |
---|
437 | <h3>1.0.8: Nov 26 2001</h3> |
---|
438 | <ul> |
---|
439 | <li>fixed an annoying header problem, removed a few bugs and some code |
---|
440 | cleanup</li> |
---|
441 | <li>patches for Windows and update of Windows Makefiles by Igor</li> |
---|
442 | <li>OpenVMS port instructions from John A Fotheringham</li> |
---|
443 | <li>fixed some Makefiles annoyance and libraries prelinking |
---|
444 | informations</li> |
---|
445 | </ul> |
---|
446 | |
---|
447 | <h3>1.0.7: Nov 10 2001</h3> |
---|
448 | <ul> |
---|
449 | <li>remove a compilation problem with LIBXSLT_PUBLIC</li> |
---|
450 | <li>Finishing the integration steps for Keith Isdale debugger</li> |
---|
451 | <li>fixes the handling of indent="no" on HTML output</li> |
---|
452 | <li>fixes on the configure script and RPM spec file</li> |
---|
453 | </ul> |
---|
454 | |
---|
455 | <h3>1.0.6: Oct 30 2001</h3> |
---|
456 | <ul> |
---|
457 | <li>bug fixes on number formatting (Thomas), date/time functions (Bruce |
---|
458 | Miller)</li> |
---|
459 | <li>update of the Windows Makefiles (Igor)</li> |
---|
460 | <li>fixed DOCTYPE generation rules for HTML output (me)</li> |
---|
461 | </ul> |
---|
462 | |
---|
463 | <h3>1.0.5: Oct 10 2001</h3> |
---|
464 | <ul> |
---|
465 | <li>some portability fixes, including Windows makefile updates from |
---|
466 | Igor</li> |
---|
467 | <li>fixed a dozen bugs on XSLT and EXSLT (me and Thomas Broyer)</li> |
---|
468 | <li>support for Saxon's evaluate and expressions extensions added (initial |
---|
469 | contribution from Darren Graves)</li> |
---|
470 | <li>better handling of XPath evaluation errors</li> |
---|
471 | </ul> |
---|
472 | |
---|
473 | <h3>1.0.4: Sep 12 2001</h3> |
---|
474 | <ul> |
---|
475 | <li>Documentation updates from John fleck</li> |
---|
476 | <li>bug fixes (DocBook FO generation should be fixed) and portability |
---|
477 | improvements</li> |
---|
478 | <li>Thomas Broyer improved the existing EXSLT support and added String, |
---|
479 | Time and Date core functions support</li> |
---|
480 | </ul> |
---|
481 | |
---|
482 | <h3>1.0.3: Aug 23 2001</h3> |
---|
483 | <ul> |
---|
484 | <li>XML Catalog support see the doc</li> |
---|
485 | <li>New NaN/Infinity floating point code</li> |
---|
486 | <li>A few bug fixes</li> |
---|
487 | </ul> |
---|
488 | |
---|
489 | <h3>1.0.2: Aug 15 2001</h3> |
---|
490 | <ul> |
---|
491 | <li>lot of bug fixes, increased the testsuite</li> |
---|
492 | <li>a large chunk of EXSLT is implemented</li> |
---|
493 | <li>improvements on the extension framework</li> |
---|
494 | <li>documentation improvements</li> |
---|
495 | <li>Windows MSC projects files should be up-to-date</li> |
---|
496 | <li>handle attributes inherited from the DTD by default</li> |
---|
497 | </ul> |
---|
498 | |
---|
499 | <h3>1.0.1: July 24 2001</h3> |
---|
500 | <ul> |
---|
501 | <li>initial EXSLT framework</li> |
---|
502 | <li>better error reporting</li> |
---|
503 | <li>fixed the profiler on Windows</li> |
---|
504 | <li>bug fixes</li> |
---|
505 | </ul> |
---|
506 | |
---|
507 | <h3>1.0.0: July 10 2001</h3> |
---|
508 | <ul> |
---|
509 | <li>a lot of cleanup, a lot of regression tests added or fixed</li> |
---|
510 | <li>added a documentation for <a href="extensions.html">writing |
---|
511 | extensions</a></li> |
---|
512 | <li>fixed some variable evaluation problems (with William)</li> |
---|
513 | <li>added profiling of stylesheet execution accessible as the xsltproc |
---|
514 | --profile option</li> |
---|
515 | <li>fixed element-available() and the implementation of the various |
---|
516 | chunking methods present, Norm Walsh provided a lot of feedback</li> |
---|
517 | <li>exclude-result-prefixes and namespaces output should now work as |
---|
518 | expected</li> |
---|
519 | <li>added support of embedded stylesheet as described in section 2.7 of the |
---|
520 | spec</li> |
---|
521 | </ul> |
---|
522 | |
---|
523 | <h3>0.14.0: July 5 2001</h3> |
---|
524 | <ul> |
---|
525 | <li>lot of bug fixes, and code cleanup</li> |
---|
526 | <li>completion of the little XSLT-1.0 features left unimplemented</li> |
---|
527 | <li>Added and implemented the extension API suggested by Thomas Broyer</li> |
---|
528 | <li>the Windows MSC environment should be complete</li> |
---|
529 | <li>tested and optimized with a really large document (DocBook Definitive |
---|
530 | Guide) libxml/libxslt should really be faster on serious workloads</li> |
---|
531 | </ul> |
---|
532 | |
---|
533 | <h3>0.13.0: June 26 2001</h3> |
---|
534 | <ul> |
---|
535 | <li>lots of cleanups</li> |
---|
536 | <li>fixed a C++ compilation problem</li> |
---|
537 | <li>couple of fixes to xsltSaveTo()</li> |
---|
538 | <li>try to fix Docbook-xslt-1.4 and chunking, updated the regression test |
---|
539 | with them</li> |
---|
540 | <li>fixed pattern compilation and priorities problems</li> |
---|
541 | <li>Patches for Windows and MSC project mostly contributed by Yon Derek</li> |
---|
542 | <li>update to the Tutorial by John Fleck</li> |
---|
543 | <li>William fixed bugs in templates and for-each functions</li> |
---|
544 | <li>added a new interface xsltRunStylesheet() for a more flexible output |
---|
545 | (incomplete), added -o option to xsltproc</li> |
---|
546 | </ul> |
---|
547 | |
---|
548 | <h3>0.12.0: June 18 2001</h3> |
---|
549 | <ul> |
---|
550 | <li>fixed a dozen of bugs reported</li> |
---|
551 | <li>HTML generation should be quite better (requires libxml-2.3.11 upgrade |
---|
552 | too)</li> |
---|
553 | <li>William fixed some problems with document()</li> |
---|
554 | <li>Fix namespace nodes selection and copy (requires libxml-2.3.11 upgrade |
---|
555 | too)</li> |
---|
556 | <li>John Fleck added a<a href="tutorial/libxslttutorial.html"> |
---|
557 | tutorial</a></li> |
---|
558 | <li>Fixes for namespace handling when evaluating variables</li> |
---|
559 | <li>XInclude global flag added to process XInclude on document() if |
---|
560 | requested</li> |
---|
561 | <li>made xsltproc --version more detailed</li> |
---|
562 | </ul> |
---|
563 | |
---|
564 | <h3>0.11.0: June 1 2001</h3> |
---|
565 | |
---|
566 | <p>Mostly a bug fix release.</p> |
---|
567 | <ul> |
---|
568 | <li>integration of catalogs from xsltproc</li> |
---|
569 | <li>added --version to xsltproc for bug reporting</li> |
---|
570 | <li>fixed errors when handling ID in external parsed entities</li> |
---|
571 | <li>document() should hopefully work correctly but ...</li> |
---|
572 | <li>fixed bug with PI and comments processing</li> |
---|
573 | <li>William fixed the XPath string functions when using unicode</li> |
---|
574 | </ul> |
---|
575 | |
---|
576 | <h3>0.10.0: May 19 2001</h3> |
---|
577 | <ul> |
---|
578 | <li>cleanups to make stylesheet read-only (not 100% complete)</li> |
---|
579 | <li>fixed URI resolution in document()</li> |
---|
580 | <li>force all XPath expression to be compiled at stylesheet parsing time, |
---|
581 | even if unused ...</li> |
---|
582 | <li>Fixed HTML default output detection</li> |
---|
583 | <li>Fixed double attribute generation #54446</li> |
---|
584 | <li>Fixed {{ handling in attributes #54451</li> |
---|
585 | <li>More tests and speedups for DocBook document transformations</li> |
---|
586 | <li>Fixed a really bad race like bug in xsltCopyTreeList()</li> |
---|
587 | <li>added a documentation on the libxslt internals</li> |
---|
588 | <li>William Brack and Bjorn Reese improved format-number()</li> |
---|
589 | <li>Fixed multiple sort, it should really work now</li> |
---|
590 | <li>added a --docbook option for SGML DocBook input (hackish)</li> |
---|
591 | <li>a number of other bug fixes and regression test added as people were |
---|
592 | submitting them</li> |
---|
593 | </ul> |
---|
594 | |
---|
595 | <h3>0.9.0: May 3 2001</h3> |
---|
596 | <ul> |
---|
597 | <li>lot of various bugfixes, extended the regression suite</li> |
---|
598 | <li>xsltproc should work with multiple params</li> |
---|
599 | <li>added an option to use xsltproc with HTML input</li> |
---|
600 | <li>improved the stylesheet compilation, processing of complex stylesheets |
---|
601 | should be faster</li> |
---|
602 | <li>using the same stylesheet for concurrent processing on multithreaded |
---|
603 | programs should work now</li> |
---|
604 | <li>fixed another batch of namespace handling problems</li> |
---|
605 | <li>Implemented multiple level of sorting</li> |
---|
606 | </ul> |
---|
607 | |
---|
608 | <h3>0.8.0: Apr 22 2001</h3> |
---|
609 | <ul> |
---|
610 | <li>fixed ansidecl.h problem</li> |
---|
611 | <li>fixed unparsed-entity-uri() and generate-id()</li> |
---|
612 | <li>sort semantic fixes and priority prob from William M. Brack</li> |
---|
613 | <li>fixed namespace handling problems in XPath expression computations |
---|
614 | (requires libxml-2.3.7)</li> |
---|
615 | <li>fixes to current() and key()</li> |
---|
616 | <li>other, smaller fixes, lots of testing with N Walsh DocBook HTML |
---|
617 | stylesheets</li> |
---|
618 | </ul> |
---|
619 | |
---|
620 | <h3>0.7.0: Apr 10 2001</h3> |
---|
621 | <ul> |
---|
622 | <li>cleanup using stricter compiler flags</li> |
---|
623 | <li>command line parameter passing</li> |
---|
624 | <li>fix to xsltApplyTemplates from William M. Brack</li> |
---|
625 | <li>added the XSLTMark in the regression tests as well as document()</li> |
---|
626 | </ul> |
---|
627 | |
---|
628 | <h3>0.6.0: Mar 22 2001</h3> |
---|
629 | <ul> |
---|
630 | <li>another beta</li> |
---|
631 | <li>requires 2.3.5, which provide XPath expression compilation support</li> |
---|
632 | <li>document() extension should function properly</li> |
---|
633 | <li>fixed a number or reported bugs</li> |
---|
634 | </ul> |
---|
635 | |
---|
636 | <h3>0.5.0: Mar 10 2001</h3> |
---|
637 | <ul> |
---|
638 | <li>fifth beta</li> |
---|
639 | <li>some optimization work, for the moment 2 XSLT transform cannot use the |
---|
640 | same stylesheet at the same time (to be fixed)</li> |
---|
641 | <li>fixed problems with handling of tree results</li> |
---|
642 | <li>fixed a reported strip-spaces problem</li> |
---|
643 | <li>added more reported/fixed bugs to the test suite</li> |
---|
644 | <li>incorporated William M. Brack fix for imports and global variables as |
---|
645 | well as patch for with-param support in apply-templates</li> |
---|
646 | <li>a bug fix on for-each</li> |
---|
647 | </ul> |
---|
648 | |
---|
649 | <h3>0.4.0: Mar 1 2001</h3> |
---|
650 | <ul> |
---|
651 | <li>fourth beta test, released at the same time of libxml2-2.3.3</li> |
---|
652 | <li>bug fixes</li> |
---|
653 | <li>some optimization</li> |
---|
654 | <li>started implement extension support, not finished</li> |
---|
655 | <li>implemented but not tested multiple file output</li> |
---|
656 | </ul> |
---|
657 | |
---|
658 | <h3>0.3.0: Feb 24 2001</h3> |
---|
659 | <ul> |
---|
660 | <li>third beta test, released at the same time of libxml2-2.3.2</li> |
---|
661 | <li>lot of bug fixes</li> |
---|
662 | <li>some optimization</li> |
---|
663 | <li>added DocBook XSL based testsuite</li> |
---|
664 | </ul> |
---|
665 | |
---|
666 | <h3>0.2.0: Feb 15 2001</h3> |
---|
667 | <ul> |
---|
668 | <li>second beta version, released at the same time as libxml2-2.3.1</li> |
---|
669 | <li>getting close to feature completion, lot of bug fixes, some in the HTML |
---|
670 | and XPath support of libxml</li> |
---|
671 | <li>start becoming usable for real work. This version can now regenerate |
---|
672 | the XML 2e HTML from the original XML sources and the associated |
---|
673 | stylesheets (in <a |
---|
674 | href="http://www.w3.org/TR/REC-xml#b4d250b6c21">section I of the XML |
---|
675 | REC</a>)</li> |
---|
676 | <li>Still misses extension element/function/prefixes support. Support of |
---|
677 | key() and document() is not complete</li> |
---|
678 | </ul> |
---|
679 | |
---|
680 | <h3>0.1.0: Feb 8 2001</h3> |
---|
681 | <ul> |
---|
682 | <li>first beta version, released at the same time as libxml2-2.3.0</li> |
---|
683 | <li>lots of bug fixes, first "testing" version, but incomplete</li> |
---|
684 | </ul> |
---|
685 | |
---|
686 | <h3>0.0.1: Jan 25 2001</h3> |
---|
687 | <ul> |
---|
688 | <li>first alpha version released at the same time as libxml2-2.2.12</li> |
---|
689 | <li>Framework in place, should work on simple examples, but far from being |
---|
690 | feature complete</li> |
---|
691 | </ul> |
---|
692 | |
---|
693 | <h2><a name="xsltproc">The xsltproc tool</a></h2> |
---|
694 | |
---|
695 | <p>This program is the simplest way to use libxslt: from the command line. It |
---|
696 | is also used for doing the regression tests of the library.</p> |
---|
697 | |
---|
698 | <p>It takes as first argument the path or URL to an XSLT stylesheet, the next |
---|
699 | arguments are filenames or URIs of the inputs to be processed. The output of |
---|
700 | the processing is redirected on the standard output. There is actually a few |
---|
701 | more options available:</p> |
---|
702 | <pre>orchis:~ -> xsltproc |
---|
703 | Usage: xsltproc [options] stylesheet file [file ...] |
---|
704 | Options: |
---|
705 | --version or -V: show the version of libxml and libxslt used |
---|
706 | --verbose or -v: show logs of what's happening |
---|
707 | --output file or -o file: save to a given file |
---|
708 | --timing: display the time used |
---|
709 | --repeat: run the transformation 20 times |
---|
710 | --debug: dump the tree of the result instead |
---|
711 | --novalid: skip the Dtd loading phase |
---|
712 | --noout: do not dump the result |
---|
713 | --maxdepth val : increase the maximum depth |
---|
714 | --html: the input document is(are) an HTML file(s) |
---|
715 | --docbook: the input document is SGML docbook |
---|
716 | --param name value : pass a (parameter,value) pair |
---|
717 | --nonet refuse to fetch DTDs or entities over network |
---|
718 | --warnnet warn against fetching over the network |
---|
719 | --catalogs : use the catalogs from $SGML_CATALOG_FILES |
---|
720 | --xinclude : do XInclude processing on document intput |
---|
721 | --profile or --norman : dump profiling informations |
---|
722 | orchis:~ -></pre> |
---|
723 | |
---|
724 | <h2><a name="DocBook">DocBook</a></h2> |
---|
725 | |
---|
726 | <p><a href="http://www.oasis-open.org/committees/docbook/">DocBook</a> is an |
---|
727 | XML/SGML vocabulary particularly well suited to books and papers about |
---|
728 | computer hardware and software.</p> |
---|
729 | |
---|
730 | <p>xsltproc and libxslt are not specifically dependant on DocBook, but since |
---|
731 | a lot of people use xsltproc and libxml2 for DocBook formatting, here are a |
---|
732 | few pointers and informations which may be helpful:</p> |
---|
733 | <ul> |
---|
734 | <li>The <a href="http://www.oasis-open.org/committees/docbook/">DocBook |
---|
735 | homepage at Oasis</a> you should find pointers there on all the lastest |
---|
736 | versions of the DTDs and XSLT stylesheets</li> |
---|
737 | <li><a href="http://www.docbook.org/">DocBook: The Definitive Guide</a> is |
---|
738 | the official reference documentation for DocBook.</li> |
---|
739 | <li><a |
---|
740 | href="https://sourceforge.net/docman/index.php?group_id=21935">DocBook |
---|
741 | Open Repository</a> contains a lot of informations about DocBook</li> |
---|
742 | <li>Here is a <a href="/buildDocBookCatalog">shell script</a> to generate |
---|
743 | XML Catalogs for DocBook 4.1.2 . If it can write to the /etc/xml/ |
---|
744 | directory, it will set-up /etc/xml/catalog and /etc/xml/docbook based on |
---|
745 | the resources found on the system. Otherwise it will just create |
---|
746 | ~/xmlcatalog and ~/dbkxmlcatalog and doing: |
---|
747 | <p><code>export XMLCATALOG=$HOME/xmlcatalog</code></p> |
---|
748 | <p>should allow to process DocBook documentations without requiring |
---|
749 | network accesses for the DTd or stylesheets</p> |
---|
750 | </li> |
---|
751 | <li>I have uploaded <a href="ftp://xmlsoft.org/test/dbk412catalog.tar.gz">a |
---|
752 | small tarball</a> containing XML Catalogs for DocBook 4.1.2 which seems |
---|
753 | to work fine for me too</li> |
---|
754 | <li>Informations on installing a <a |
---|
755 | href="http://ourworld.compuserve.com/homepages/hoenicka_markus/ntsgml.html">Windows |
---|
756 | DocBook processing setup</a> based on Cygwin (using the binaries from the |
---|
757 | official Windows port should be possible too)</li> |
---|
758 | <li>Alexander Kirillov's page on <a |
---|
759 | href="http://www.math.sunysb.edu/~kirillov/dbxml/">Using DocBook XML |
---|
760 | 4.1.2</a> (RPM packages)</li> |
---|
761 | <li>Tim Waugh's <a href="http://cyberelk.net/tim/xmlto/">xmlto front-end |
---|
762 | conversion script</a></li> |
---|
763 | <li>Linux Documentation Project <a |
---|
764 | href="http://www.linuxdoc.org/HOWTO/mini/DocBook-Install/"> |
---|
765 | DocBook-Install-mini-HOWTO</a></li> |
---|
766 | <li>ScrollKeeper the open documentation cataloging project has a <a |
---|
767 | href="http://scrollkeeper.sourceforge.net/docbook.shtml">DocBook |
---|
768 | section</a></li> |
---|
769 | <li>Dan York presentation on <a |
---|
770 | href="http://www.lodestar2.com/people/dyork/talks/2001/xugo/docbook/index.html">Publishing |
---|
771 | using DocBook XML</a></li> |
---|
772 | </ul> |
---|
773 | |
---|
774 | <p>Do not use the --docbook option of xsltproc to process XML DocBook |
---|
775 | documents, this option is only intended to provide some (limited) support of |
---|
776 | the SGML version of DocBook.</p> |
---|
777 | |
---|
778 | <p>Points which are not DocBook specific but still worth mentionning |
---|
779 | again:</p> |
---|
780 | <ul> |
---|
781 | <li>if you think DocBook processing time is too slow, make sure you have |
---|
782 | XML Catalogs pointing to a local installation of the DTD of DocBook. |
---|
783 | Check the <a href="http://xmlsoft.org/catalog.html">XML Catalog page</a> |
---|
784 | to understand more on this subject.</li> |
---|
785 | <li>before processing a new document, use the command |
---|
786 | <p><code>xmllint --valid --noout path_to_document</code></p> |
---|
787 | <p>to make sure that your input is valid DocBook. And fixes the errors |
---|
788 | before processing further. Note that XSLT processing may work correctly |
---|
789 | with some forms of validity errors left, but in general it can give |
---|
790 | troubles on output.</p> |
---|
791 | </li> |
---|
792 | </ul> |
---|
793 | |
---|
794 | <h2><a name="API">The programming API</a></h2> |
---|
795 | |
---|
796 | <p>Okay this section is clearly incomplete. But integrating libxslt into your |
---|
797 | application should be relatively easy. First check the few steps described |
---|
798 | below, then for more detailed informations, look at the<a |
---|
799 | href="html/libxslt-lib.html"> generated pages</a> for the API and the source |
---|
800 | of libxslt/xsltproc.c and the <a |
---|
801 | href="tutorial/libxslttutorial.html">tutorial</a>.</p> |
---|
802 | |
---|
803 | <p>Basically doing an XSLT transformation can be done in a few steps:</p> |
---|
804 | <ol> |
---|
805 | <li>configure the parser for XSLT: |
---|
806 | <p>xmlSubstituteEntitiesDefault(1);</p> |
---|
807 | <p>xmlLoadExtDtdDefaultValue = 1;</p> |
---|
808 | </li> |
---|
809 | <li>parse the stylesheet with xsltParseStylesheetFile()</li> |
---|
810 | <li>parse the document with xmlParseFile()</li> |
---|
811 | <li>apply the stylesheet using xsltApplyStylesheet()</li> |
---|
812 | <li>save the result using xsltSaveResultToFile() if needed set |
---|
813 | xmlIndentTreeOutput to 1</li> |
---|
814 | </ol> |
---|
815 | |
---|
816 | <p>Steps 2,3, and 5 will probably need to be changed depending on you |
---|
817 | processing needs and environment for example if reading/saving from/to |
---|
818 | memory, or if you want to apply XInclude processing to the stylesheet or |
---|
819 | input documents.</p> |
---|
820 | |
---|
821 | <h2><a name="Python">Python and bindings</a></h2> |
---|
822 | |
---|
823 | <p>There is a number of language bindings and wrappers available for libxml2, |
---|
824 | the list below is not exhaustive. Please contact the <a |
---|
825 | href="http://mail.gnome.org/mailman/listinfo/xml-bindings">xml-bindings@gnome.org</a> |
---|
826 | (<a href="http://mail.gnome.org/archives/xml-bindings/">archives</a>) in |
---|
827 | order to get updates to this list or to discuss the specific topic of libxml2 |
---|
828 | or libxslt wrappers or bindings:</p> |
---|
829 | <ul> |
---|
830 | <li><a |
---|
831 | href="http://mail.gnome.org/archives/xml/2001-March/msg00014.html">Matt |
---|
832 | Sergeant</a> developped <a href="http://axkit.org/download/">XML::LibXML |
---|
833 | and XML::LibXSLT</a>, a perl wrapper for libxml2/libxslt as part of the |
---|
834 | <a href="http://axkit.com/">AxKit XML application server</a></li> |
---|
835 | <li><a href="mailto:dkuhlman@cutter.rexx.com">Dave Kuhlman</a> provides and |
---|
836 | earlier version of the libxml/libxslt <a |
---|
837 | href="http://www.rexx.com/~dkuhlman">wrappers for Python</a></li> |
---|
838 | <li>Petr Kozelka provides <a |
---|
839 | href="http://sourceforge.net/projects/libxml2-pas">Pascal units to glue |
---|
840 | libxml2</a> with Kylix, Delphi and other Pascal compilers</li> |
---|
841 | <li>Wai-Sun "Squidster" Chia provides <a |
---|
842 | href="http://www.rubycolor.org/arc/redist/">bindings for Ruby</a> and |
---|
843 | libxml2 bindings are also available in Ruby through the <a |
---|
844 | href="http://libgdome-ruby.berlios.de/">libgdome-ruby</a> module |
---|
845 | maintained by Tobias Peters.</li> |
---|
846 | <li>Steve Ball and contributors maintains <a |
---|
847 | href="http://tclxml.sourceforge.net/">libxml2 and libxslt bindings for |
---|
848 | Tcl</a></li> |
---|
849 | </ul> |
---|
850 | |
---|
851 | <p>The libxslt Python module depends on the <a |
---|
852 | href="http://xmlsoft.org/python.html">libxml2 Python</a> module.</p> |
---|
853 | |
---|
854 | <p>The distribution includes a set of Python bindings, which are garanteed to |
---|
855 | be maintained as part of the library in the future, though the Python |
---|
856 | interface have not yet reached the maturity of the C API.</p> |
---|
857 | |
---|
858 | <p><a href="mailto:stephane.bidoul@softwareag.com">Stéphane Bidoul</a> |
---|
859 | maintains <a href="http://users.skynet.be/sbi/libxml-python/">a Windows port |
---|
860 | of the Python bindings</a>.</p> |
---|
861 | |
---|
862 | <p>Note to people interested in building bindings, the API is formalized as |
---|
863 | <a href="libxslt-api.xml">an XML API description file</a> which allows to |
---|
864 | automate a large part of the Python bindings, this includes function |
---|
865 | descriptions, enums, structures, typedefs, etc... The Python script used to |
---|
866 | build the bindings is python/generator.py in the source distribution.</p> |
---|
867 | |
---|
868 | <p>To install the Python bindings there are 2 options:</p> |
---|
869 | <ul> |
---|
870 | <li>If you use an RPM based distribution, simply install the <a |
---|
871 | href="http://rpmfind.net/linux/rpm2html/search.php?query=libxml2-python">libxml2-python |
---|
872 | RPM</a> and the <a |
---|
873 | href="http://rpmfind.net/linux/rpm2html/search.php?query=libxslt-python">libxslt-python |
---|
874 | RPM</a>.</li> |
---|
875 | <li>Otherwise use the <a href="ftp://xmlsoft.org/python/">libxml2-python |
---|
876 | module distribution</a> corresponding to your installed version of |
---|
877 | libxml2 and libxslt. Note that to install it you will need both libxml2 |
---|
878 | and libxslt installed and run "python setup.py build install" in the |
---|
879 | module tree.</li> |
---|
880 | </ul> |
---|
881 | |
---|
882 | <p>The distribution includes a set of examples and regression tests for the |
---|
883 | python bindings in the <code>python/tests</code> directory. Here are some |
---|
884 | excepts from those tests:</p> |
---|
885 | |
---|
886 | <h3>basic.py:</h3> |
---|
887 | |
---|
888 | <p>This is a basic test of XSLT interfaces: loading a stylesheet and a |
---|
889 | document, transforming the document and saving the result.</p> |
---|
890 | <pre>import libxml2 |
---|
891 | import libxslt |
---|
892 | |
---|
893 | styledoc = libxml2.parseFile("test.xsl") |
---|
894 | style = libxslt.parseStylesheetDoc(styledoc) |
---|
895 | doc = libxml2.parseFile("test.xml") |
---|
896 | result = style.applyStylesheet(doc, None) |
---|
897 | style.saveResultToFilename("foo", result, 0) |
---|
898 | style.freeStylesheet() |
---|
899 | doc.freeDoc() |
---|
900 | result.freeDoc()</pre> |
---|
901 | |
---|
902 | <p>The Python module is called libxslt, you will also need the libxml2 module |
---|
903 | for the operations on XML trees. Let's have a look at the objects manipulated |
---|
904 | in that example and how is the processing done:</p> |
---|
905 | <ul> |
---|
906 | <li><code>styledoc</code> : is a libxml2 document tree. It is obtained by |
---|
907 | parsing the XML file "test.xsl" containing the stylesheet.</li> |
---|
908 | <li><code>style</code> : this is a precompiled stylesheet ready to be used |
---|
909 | by the following transformations (note the plural form, multiple |
---|
910 | transformations can resuse the same stylesheet).</li> |
---|
911 | <li><code>doc</code> : this is the document to apply the transformation to. |
---|
912 | In this case it is simply generated by parsing it from a file but any |
---|
913 | other processing is possible as long as one get a libxml2 Doc. Note that |
---|
914 | HTML tree are suitable for XSLT processing in libxslt. This is actually |
---|
915 | how this page is generated !</li> |
---|
916 | <li><code>result</code> : this is a document generated by applying the |
---|
917 | stylesheet to the document. Note that some of the stylesheet informations |
---|
918 | may be related to the serialization of that document and as in this |
---|
919 | example a specific saveResultToFilename() method of the stylesheet should |
---|
920 | be used to save it to a file (in that case to "foo").</li> |
---|
921 | </ul> |
---|
922 | |
---|
923 | <p>Also note the need to explicitely deallocate documents with freeDoc() |
---|
924 | except for the stylesheet document which is freed when its compiled form is |
---|
925 | garbage collected.</p> |
---|
926 | |
---|
927 | <h3>extfunc.py:</h3> |
---|
928 | |
---|
929 | <p>This one is a far more complex test. It shows how to modify the behaviour |
---|
930 | of an XSLT transformation by passing parameters and how to extend the XSLT |
---|
931 | engine with functions defined in python:</p> |
---|
932 | <pre>import libxml2 |
---|
933 | import libxslt |
---|
934 | import string |
---|
935 | |
---|
936 | nodeName = None |
---|
937 | def f(ctx, str): |
---|
938 | global nodeName |
---|
939 | |
---|
940 | # |
---|
941 | # Small check to verify the context is correcly accessed |
---|
942 | # |
---|
943 | try: |
---|
944 | pctxt = libxslt.xpathParserContext(_obj=ctx) |
---|
945 | ctxt = pctxt.context() |
---|
946 | tctxt = ctxt.transformContext() |
---|
947 | nodeName = tctxt.insertNode().name |
---|
948 | except: |
---|
949 | pass |
---|
950 | |
---|
951 | return string.upper(str) |
---|
952 | |
---|
953 | libxslt.registerExtModuleFunction("foo", "http://example.com/foo", f)</pre> |
---|
954 | |
---|
955 | <p>This code defines and register an extension function. Note that the |
---|
956 | function can be bound to any name (foo) and how the binding is also |
---|
957 | associated to a namespace name "http://example.com/foo". From an XSLT point |
---|
958 | of view the function just returns an upper case version of the string passed |
---|
959 | as a parameter. But the first part of the function also read some contextual |
---|
960 | information from the current XSLT processing environement, in that case it |
---|
961 | looks for the current insertion node in the resulting output (either the |
---|
962 | resulting document or the Result Value Tree being generated), and saves it to |
---|
963 | a global variable for checking that the access actually worked.</p> |
---|
964 | |
---|
965 | <p>For more informations on the xpathParserContext and transformContext |
---|
966 | objects check the <a href="internals.html">libray internals description</a>. |
---|
967 | The pctxt is actually an object from a class derived from the |
---|
968 | libxml2.xpathParserContext() with just a couple more properties including the |
---|
969 | possibility to look up the XSLT transformation context from the XPath |
---|
970 | context.</p> |
---|
971 | <pre>styledoc = libxml2.parseDoc(""" |
---|
972 | <xsl:stylesheet version='1.0' |
---|
973 | xmlns:xsl='http://www.w3.org/1999/XSL/Transform' |
---|
974 | xmlns:foo='http://example.com/foo' |
---|
975 | xsl:exclude-result-prefixes='foo'> |
---|
976 | |
---|
977 | <xsl:param name='bar'>failure</xsl:param> |
---|
978 | <xsl:template match='/'> |
---|
979 | <article><xsl:value-of select='foo:foo($bar)'/></article> |
---|
980 | </xsl:template> |
---|
981 | </xsl:stylesheet> |
---|
982 | """)</pre> |
---|
983 | |
---|
984 | <p>Here is a simple example of how to read an XML document from a python |
---|
985 | string with libxml2. Note how this stylesheet:</p> |
---|
986 | <ul> |
---|
987 | <li>Uses a global parameter <code>bar</code></li> |
---|
988 | <li>Reference the extension function f</li> |
---|
989 | <li>how the Namespace name "http://example.com/foo" has to be bound to a |
---|
990 | prefix</li> |
---|
991 | <li>how that prefix is excluded from the output</li> |
---|
992 | <li>how the function is called from the select</li> |
---|
993 | </ul> |
---|
994 | <pre>style = libxslt.parseStylesheetDoc(styledoc) |
---|
995 | doc = libxml2.parseDoc("<doc/>") |
---|
996 | result = style.applyStylesheet(doc, { "bar": "'success'" }) |
---|
997 | style.freeStylesheet() |
---|
998 | doc.freeDoc()</pre> |
---|
999 | |
---|
1000 | <p>that part is identical, to the basic example except that the |
---|
1001 | transformation is passed a dictionnary of parameters. Note that the string |
---|
1002 | passed "success" had to be quoted, otherwise it is interpreted as an XPath |
---|
1003 | query for the childs of root named "success".</p> |
---|
1004 | <pre>root = result.children |
---|
1005 | if root.name != "article": |
---|
1006 | print "Unexpected root node name" |
---|
1007 | sys.exit(1) |
---|
1008 | if root.content != "SUCCESS": |
---|
1009 | print "Unexpected root node content, extension function failed" |
---|
1010 | sys.exit(1) |
---|
1011 | if nodeName != 'article': |
---|
1012 | print "The function callback failed to access its context" |
---|
1013 | sys.exit(1) |
---|
1014 | |
---|
1015 | result.freeDoc()</pre> |
---|
1016 | |
---|
1017 | <p>That part just verifies that the transformation worked, that the parameter |
---|
1018 | got properly passed to the engine, that the function f() got called and that |
---|
1019 | it properly accessed the context to find the name of the insertion node.</p> |
---|
1020 | |
---|
1021 | <h3>pyxsltproc.py:</h3> |
---|
1022 | |
---|
1023 | <p>this module is a bit too long to be described there but it is basically a |
---|
1024 | rewrite of the xsltproc command line interface of libxslt in Python. It |
---|
1025 | provides nearly all the functionalities of xsltproc and can be used as a base |
---|
1026 | module to write Python customized XSLT processors. One of the thing to notice |
---|
1027 | are:</p> |
---|
1028 | <pre>libxml2.lineNumbersDefault(1) |
---|
1029 | libxml2.substituteEntitiesDefault(1)</pre> |
---|
1030 | |
---|
1031 | <p>those two calls in the main() function are needed to force the libxml2 |
---|
1032 | processor to generate DOM trees compliant with the XPath data model.</p> |
---|
1033 | |
---|
1034 | <h2><a name="Internals">Library internals</a></h2> |
---|
1035 | |
---|
1036 | <h3>Table of contents</h3> |
---|
1037 | <ul> |
---|
1038 | <li><a href="internals.html#Introducti">Introduction</a></li> |
---|
1039 | <li><a href="internals.html#Basics">Basics</a></li> |
---|
1040 | <li><a href="internals.html#Keep">Keep it simple stupid</a></li> |
---|
1041 | <li><a href="internals.html#libxml">The libxml nodes</a></li> |
---|
1042 | <li><a href="internals.html#XSLT">The XSLT processing steps</a></li> |
---|
1043 | <li><a href="internals.html#XSLT1">The XSLT stylesheet compilation</a></li> |
---|
1044 | <li><a href="internals.html#XSLT2">The XSLT template compilation</a></li> |
---|
1045 | <li><a href="internals.html#processing">The processing itself</a></li> |
---|
1046 | <li><a href="internals.html#XPath">XPath expressions compilation</a></li> |
---|
1047 | <li><a href="internals.html#XPath1">XPath interpretation</a></li> |
---|
1048 | <li><a href="internals.html#Descriptio">Description of XPath |
---|
1049 | Objects</a></li> |
---|
1050 | <li><a href="internals.html#XPath3">XPath functions</a></li> |
---|
1051 | <li><a href="internals.html#stack">The variables stack frame</a></li> |
---|
1052 | <li><a href="internals.html#Extension">Extension support</a></li> |
---|
1053 | <li><a href="internals.html#Futher">Further reading</a></li> |
---|
1054 | <li><a href="internals.html#TODOs">TODOs</a></li> |
---|
1055 | </ul> |
---|
1056 | |
---|
1057 | <h3><a name="Introducti2">Introduction</a></h3> |
---|
1058 | |
---|
1059 | <p>This document describes the processing of <a |
---|
1060 | href="http://xmlsoft.org/XSLT/">libxslt</a>, the <a |
---|
1061 | href="http://www.w3.org/TR/xslt">XSLT</a> C library developed for the <a |
---|
1062 | href="http://www.gnome.org/">Gnome</a> project.</p> |
---|
1063 | |
---|
1064 | <p>Note: this documentation is by definition incomplete and I am not good at |
---|
1065 | spelling, grammar, so patches and suggestions are <a |
---|
1066 | href="mailto:veillard@redhat.com">really welcome</a>.</p> |
---|
1067 | |
---|
1068 | <h3><a name="Basics1">Basics</a></h3> |
---|
1069 | |
---|
1070 | <p>XSLT is a transformation language. It takes an input document and a |
---|
1071 | stylesheet document and generates an output document:</p> |
---|
1072 | |
---|
1073 | <p align="center"><img src="processing.gif" |
---|
1074 | alt="the XSLT processing model"></p> |
---|
1075 | |
---|
1076 | <p>Libxslt is written in C. It relies on <a |
---|
1077 | href="http://www.xmlsoft.org/">libxml</a>, the XML C library for Gnome, for |
---|
1078 | the following operations:</p> |
---|
1079 | <ul> |
---|
1080 | <li>parsing files</li> |
---|
1081 | <li>building the in-memory DOM structure associated with the documents |
---|
1082 | handled</li> |
---|
1083 | <li>the XPath implementation</li> |
---|
1084 | <li>serializing back the result document to XML and HTML. (Text is handled |
---|
1085 | directly.)</li> |
---|
1086 | </ul> |
---|
1087 | |
---|
1088 | <h3><a name="Keep1">Keep it simple stupid</a></h3> |
---|
1089 | |
---|
1090 | <p>Libxslt is not very specialized. It is built under the assumption that all |
---|
1091 | nodes from the source and output document can fit in the virtual memory of |
---|
1092 | the system. There is a big trade-off there. It is fine for reasonably sized |
---|
1093 | documents but may not be suitable for large sets of data. The gain is that it |
---|
1094 | can be used in a relatively versatile way. The input or output may never be |
---|
1095 | serialized, but the size of documents it can handle are limited by the size |
---|
1096 | of the memory available.</p> |
---|
1097 | |
---|
1098 | <p>More specialized memory handling approaches are possible, like building |
---|
1099 | the input tree from a serialization progressively as it is consumed, |
---|
1100 | factoring repetitive patterns, or even on-the-fly generation of the output as |
---|
1101 | the input is parsed but it is possible only for a limited subset of the |
---|
1102 | stylesheets. In general the implementation of libxslt follows the following |
---|
1103 | pattern:</p> |
---|
1104 | <ul> |
---|
1105 | <li>KISS (keep it simple stupid)</li> |
---|
1106 | <li>when there is a clear bottleneck optimize on top of this simple |
---|
1107 | framework and refine only as much as is needed to reach the expected |
---|
1108 | result</li> |
---|
1109 | </ul> |
---|
1110 | |
---|
1111 | <p>The result is not that bad, clearly one can do a better job but more |
---|
1112 | specialized too. Most optimization like building the tree on-demand would |
---|
1113 | need serious changes to the libxml XPath framework. An easy step would be to |
---|
1114 | serialize the output directly (or call a set of SAX-like output handler to |
---|
1115 | keep this a flexible interface) and hence avoid the memory consumption of the |
---|
1116 | result.</p> |
---|
1117 | |
---|
1118 | <h3><a name="libxml">The libxml nodes</a></h3> |
---|
1119 | |
---|
1120 | <p>DOM-like trees, as used and generated by libxml and libxslt, are |
---|
1121 | relatively complex. Most node types follow the given structure except a few |
---|
1122 | variations depending on the node type:</p> |
---|
1123 | |
---|
1124 | <p align="center"><img src="node.gif" alt="description of a libxml node"></p> |
---|
1125 | |
---|
1126 | <p>Nodes carry a <strong>name</strong> and the node <strong>type</strong> |
---|
1127 | indicates the kind of node it represents, the most common ones are:</p> |
---|
1128 | <ul> |
---|
1129 | <li>document nodes</li> |
---|
1130 | <li>element nodes</li> |
---|
1131 | <li>text nodes</li> |
---|
1132 | </ul> |
---|
1133 | |
---|
1134 | <p>For the XSLT processing, entity nodes should not be generated (i.e. they |
---|
1135 | should be replaced by their content). Most nodes also contains the following |
---|
1136 | "navigation" informations:</p> |
---|
1137 | <ul> |
---|
1138 | <li>the containing <strong>doc</strong>ument</li> |
---|
1139 | <li>the <strong>parent</strong> node</li> |
---|
1140 | <li>the first <strong>children</strong> node</li> |
---|
1141 | <li>the <strong>last</strong> children node</li> |
---|
1142 | <li>the <strong>prev</strong>ious sibling</li> |
---|
1143 | <li>the following sibling (<strong>next</strong>)</li> |
---|
1144 | </ul> |
---|
1145 | |
---|
1146 | <p>Elements nodes carries the list of attributes in the properties, an |
---|
1147 | attribute itself holds the navigation pointers and the children list (the |
---|
1148 | attribute value is not represented as a simple string to allow usage of |
---|
1149 | entities references).</p> |
---|
1150 | |
---|
1151 | <p>The <strong>ns</strong> points to the namespace declaration for the |
---|
1152 | namespace associated to the node, <strong>nsDef</strong> is the linked list |
---|
1153 | of namespace declaration present on element nodes.</p> |
---|
1154 | |
---|
1155 | <p>Most nodes also carry an <strong>_private</strong> pointer which can be |
---|
1156 | used by the application to hold specific data on this node.</p> |
---|
1157 | |
---|
1158 | <h3><a name="XSLT">The XSLT processing steps</a></h3> |
---|
1159 | |
---|
1160 | <p>There are a few steps which are clearly decoupled at the interface |
---|
1161 | level:</p> |
---|
1162 | <ol> |
---|
1163 | <li>parse the stylesheet and generate a DOM tree</li> |
---|
1164 | <li>take the stylesheet tree and build a compiled version of it (the |
---|
1165 | compilation phase)</li> |
---|
1166 | <li>take the input and generate a DOM tree</li> |
---|
1167 | <li>process the stylesheet against the input tree and generate an output |
---|
1168 | tree</li> |
---|
1169 | <li>serialize the output tree</li> |
---|
1170 | </ol> |
---|
1171 | |
---|
1172 | <p>A few things should be noted here:</p> |
---|
1173 | <ul> |
---|
1174 | <li>the steps 1/ 3/ and 5/ are optional</li> |
---|
1175 | <li>the stylesheet obtained at 2/ can be reused by multiple processing 4/ |
---|
1176 | (and this should also work in threaded programs)</li> |
---|
1177 | <li>the tree provided in 2/ should never be freed using xmlFreeDoc, but by |
---|
1178 | freeing the stylesheet.</li> |
---|
1179 | <li>the input tree 4/ is not modified except the _private field which may |
---|
1180 | be used for labelling keys if used by the stylesheet</li> |
---|
1181 | </ul> |
---|
1182 | |
---|
1183 | <h3><a name="XSLT1">The XSLT stylesheet compilation</a></h3> |
---|
1184 | |
---|
1185 | <p>This is the second step described. It takes a stylesheet tree, and |
---|
1186 | "compiles" it. This associates to each node a structure stored in the |
---|
1187 | _private field and containing information computed in the stylesheet:</p> |
---|
1188 | |
---|
1189 | <p align="center"><img src="stylesheet.gif" |
---|
1190 | alt="a compiled XSLT stylesheet"></p> |
---|
1191 | |
---|
1192 | <p>One xsltStylesheet structure is generated per document parsed for the |
---|
1193 | stylesheet. XSLT documents allow includes and imports of other documents, |
---|
1194 | imports are stored in the <strong>imports</strong> list (hence keeping the |
---|
1195 | tree hierarchy of includes which is very important for a proper XSLT |
---|
1196 | processing model) and includes are stored in the <strong>doclist</strong> |
---|
1197 | list. An imported stylesheet has a parent link to allow browsing of the |
---|
1198 | tree.</p> |
---|
1199 | |
---|
1200 | <p>The DOM tree associated to the document is stored in <strong>doc</strong>. |
---|
1201 | It is preprocessed to remove ignorable empty nodes and all the nodes in the |
---|
1202 | XSLT namespace are subject to precomputing. This usually consist of |
---|
1203 | extracting all the context information from the context tree (attributes, |
---|
1204 | namespaces, XPath expressions), and storing them in an xsltStylePreComp |
---|
1205 | structure associated to the <strong>_private</strong> field of the node.</p> |
---|
1206 | |
---|
1207 | <p>A couple of notable exceptions to this are XSLT template nodes (more on |
---|
1208 | this later) and attribute value templates. If they are actually templates, |
---|
1209 | the value cannot be computed at compilation time. (Some preprocessing could |
---|
1210 | be done like isolation and preparsing of the XPath subexpressions but it's |
---|
1211 | not done, yet.)</p> |
---|
1212 | |
---|
1213 | <p>The xsltStylePreComp structure also allows storing of the precompiled form |
---|
1214 | of an XPath expression that can be associated to an XSLT element (more on |
---|
1215 | this later).</p> |
---|
1216 | |
---|
1217 | <h3><a name="XSLT2">The XSLT template compilation</a></h3> |
---|
1218 | |
---|
1219 | <p>A proper handling of templates lookup is one of the keys of fast XSLT |
---|
1220 | processing. (Given a node in the source document this is the process of |
---|
1221 | finding which templates should be applied to this node.) Libxslt follows the |
---|
1222 | hint suggested in the <a href="http://www.w3.org/TR/xslt#patterns">5.2 |
---|
1223 | Patterns</a> section of the XSLT Recommendation, i.e. it doesn't evaluate it |
---|
1224 | as an XPath expression but tokenizes it and compiles it as a set of rules to |
---|
1225 | be evaluated on a candidate node. There usually is an indication of the node |
---|
1226 | name in the last step of this evaluation and this is used as a key check for |
---|
1227 | the match. As a result libxslt builds a relatively more complex set of |
---|
1228 | structures for the templates:</p> |
---|
1229 | |
---|
1230 | <p align="center"><img src="templates.gif" |
---|
1231 | alt="The templates related structure"></p> |
---|
1232 | |
---|
1233 | <p>Let's describe a bit more closely what is built. First the xsltStylesheet |
---|
1234 | structure holds a pointer to the template hash table. All the XSLT patterns |
---|
1235 | compiled in this stylesheet are indexed by the value of the the target |
---|
1236 | element (or attribute, pi ...) name, so when a element or an attribute "foo" |
---|
1237 | needs to be processed the lookup is done using the name as a key.</p> |
---|
1238 | |
---|
1239 | <p>Each of the patterns is compiled into an xsltCompMatch structure. It holds |
---|
1240 | the set of rules based on the tokenization of the pattern stored in reverse |
---|
1241 | order (matching is easier this way). It also holds some information about the |
---|
1242 | previous matches used to speed up the process when one iterates over a set of |
---|
1243 | siblings. (This optimization may be defeated by trashing when running |
---|
1244 | threaded computation, it's unclear that this is a big deal in practice.) |
---|
1245 | Predicate expressions are not compiled at this stage, they may be at run-time |
---|
1246 | if needed, but in this case they are compiled as full XPath expressions (the |
---|
1247 | use of some fixed predicate can probably be optimized, they are not yet).</p> |
---|
1248 | |
---|
1249 | <p>The xsltCompMatch are then stored in the hash table, the clash list is |
---|
1250 | itself sorted by priority of the template to implement "naturally" the XSLT |
---|
1251 | priority rules.</p> |
---|
1252 | |
---|
1253 | <p>Associated to the compiled pattern is the xsltTemplate itself containing |
---|
1254 | the information required for the processing of the pattern including, of |
---|
1255 | course, a pointer to the list of elements used for building the pattern |
---|
1256 | result.</p> |
---|
1257 | |
---|
1258 | <p>Last but not least a number of patterns do not fit in the hash table |
---|
1259 | because they are not associated to a name, this is the case for patterns |
---|
1260 | applying to the root, any element, any attributes, text nodes, pi nodes, keys |
---|
1261 | etc. Those are stored independently in the stylesheet structure as separate |
---|
1262 | linked lists of xsltCompMatch.</p> |
---|
1263 | |
---|
1264 | <h3><a name="processing">The processing itself</a></h3> |
---|
1265 | |
---|
1266 | <p>The processing is defined by the XSLT specification (the basis of the |
---|
1267 | algorithm is explained in <a |
---|
1268 | href="http://www.w3.org/TR/xslt#section-Introduction">the Introduction</a> |
---|
1269 | section). Basically it works by taking the root of the input document and |
---|
1270 | applying the following algorithm:</p> |
---|
1271 | <ol> |
---|
1272 | <li>Finding the template applying to it. This is a lookup in the template |
---|
1273 | hash table, walking the hash list until the node satisfies all the steps |
---|
1274 | of the pattern, then checking the appropriate(s) global templates to see |
---|
1275 | if there isn't a higher priority rule to apply</li> |
---|
1276 | <li>If there is no template, apply the default rule (recurse on the |
---|
1277 | children)</li> |
---|
1278 | <li>else walk the content list of the selected templates, for each of them: |
---|
1279 | <ul> |
---|
1280 | <li>if the node is in the XSLT namespace then the node has a _private |
---|
1281 | field pointing to the preprocessed values, jump to the specific |
---|
1282 | code</li> |
---|
1283 | <li>if the node is in an extension namespace, look up the associated |
---|
1284 | behavior</li> |
---|
1285 | <li>otherwise copy the node.</li> |
---|
1286 | </ul> |
---|
1287 | <p>The closure is usually done through the XSLT |
---|
1288 | <strong>apply-templates</strong> construct recursing by applying the |
---|
1289 | adequate template on the input node children or on the result of an |
---|
1290 | associated XPath selection lookup.</p> |
---|
1291 | </li> |
---|
1292 | </ol> |
---|
1293 | |
---|
1294 | <p>Note that large parts of the input tree may not be processed by a given |
---|
1295 | stylesheet and that on the opposite some may be processed multiple times. |
---|
1296 | (This often is the case when a Table of Contents is built).</p> |
---|
1297 | |
---|
1298 | <p>The module <code>transform.c</code> is the one implementing most of this |
---|
1299 | logic. <strong>xsltApplyStylesheet()</strong> is the entry point, it |
---|
1300 | allocates an xsltTransformContext containing the following:</p> |
---|
1301 | <ul> |
---|
1302 | <li>a pointer to the stylesheet being processed</li> |
---|
1303 | <li>a stack of templates</li> |
---|
1304 | <li>a stack of variables and parameters</li> |
---|
1305 | <li>an XPath context</li> |
---|
1306 | <li>the template mode</li> |
---|
1307 | <li>current document</li> |
---|
1308 | <li>current input node</li> |
---|
1309 | <li>current selected node list</li> |
---|
1310 | <li>the current insertion points in the output document</li> |
---|
1311 | <li>a couple of hash tables for extension elements and functions</li> |
---|
1312 | </ul> |
---|
1313 | |
---|
1314 | <p>Then a new document gets allocated (HTML or XML depending on the type of |
---|
1315 | output), the user parameters and global variables and parameters are |
---|
1316 | evaluated. Then <strong>xsltProcessOneNode()</strong> which implements the |
---|
1317 | 1-2-3 algorithm is called on the root element of the input. Step 1/ is |
---|
1318 | implemented by calling <strong>xsltGetTemplate()</strong>, step 2/ is |
---|
1319 | implemented by <strong>xsltDefaultProcessOneNode()</strong> and step 3/ is |
---|
1320 | implemented by <strong>xsltApplyOneTemplate()</strong>.</p> |
---|
1321 | |
---|
1322 | <h3><a name="XPath">XPath expression compilation</a></h3> |
---|
1323 | |
---|
1324 | <p>The XPath support is actually implemented in the libxml module (where it |
---|
1325 | is reused by the XPointer implementation). XPath is a relatively classic |
---|
1326 | expression language. The only uncommon feature is that it is working on XML |
---|
1327 | trees and hence has specific syntax and types to handle them.</p> |
---|
1328 | |
---|
1329 | <p>XPath expressions are compiled using <strong>xmlXPathCompile()</strong>. |
---|
1330 | It will take an expression string in input and generate a structure |
---|
1331 | containing the parsed expression tree, for example the expression:</p> |
---|
1332 | <pre>/doc/chapter[title='Introduction']</pre> |
---|
1333 | |
---|
1334 | <p>will be compiled as</p> |
---|
1335 | <pre>Compiled Expression : 10 elements |
---|
1336 | SORT |
---|
1337 | COLLECT 'child' 'name' 'node' chapter |
---|
1338 | COLLECT 'child' 'name' 'node' doc |
---|
1339 | ROOT |
---|
1340 | PREDICATE |
---|
1341 | SORT |
---|
1342 | EQUAL = |
---|
1343 | COLLECT 'child' 'name' 'node' title |
---|
1344 | NODE |
---|
1345 | ELEM Object is a string : Introduction |
---|
1346 | COLLECT 'child' 'name' 'node' title |
---|
1347 | NODE</pre> |
---|
1348 | |
---|
1349 | <p>This can be tested using the <code>testXPath</code> command (in the |
---|
1350 | libxml codebase) using the <code>--tree</code> option.</p> |
---|
1351 | |
---|
1352 | <p>Again, the KISS approach is used. No optimization is done. This could be |
---|
1353 | an interesting thing to add. <a |
---|
1354 | href="http://www-106.ibm.com/developerworks/library/x-xslt2/?dwzone=x?open&l=132%2ct=gr%2c+p=saxon">Michael |
---|
1355 | Kay describes</a> a lot of possible and interesting optimizations done in |
---|
1356 | Saxon which would be possible at this level. I'm unsure they would provide |
---|
1357 | much gain since the expressions tends to be relatively simple in general and |
---|
1358 | stylesheets are still hand generated. Optimizations at the interpretation |
---|
1359 | sounds likely to be more efficient.</p> |
---|
1360 | |
---|
1361 | <h3><a name="XPath1">XPath interpretation</a></h3> |
---|
1362 | |
---|
1363 | <p>The interpreter is implemented by <strong>xmlXPathCompiledEval()</strong> |
---|
1364 | which is the front-end to <strong>xmlXPathCompOpEval()</strong> the function |
---|
1365 | implementing the evaluation of the expression tree. This evaluation follows |
---|
1366 | the KISS approach again. It's recursive and calls |
---|
1367 | <strong>xmlXPathNodeCollectAndTest()</strong> to collect nodes set when |
---|
1368 | evaluating a <code>COLLECT</code> node.</p> |
---|
1369 | |
---|
1370 | <p>An evaluation is done within the framework of an XPath context stored in |
---|
1371 | an <strong>xmlXPathContext</strong> structure, in the framework of a |
---|
1372 | transformation the context is maintained within the XSLT context. Its content |
---|
1373 | follows the requirements from the XPath specification:</p> |
---|
1374 | <ul> |
---|
1375 | <li>the current document</li> |
---|
1376 | <li>the current node</li> |
---|
1377 | <li>a hash table of defined variables (but not used by XSLT)</li> |
---|
1378 | <li>a hash table of defined functions</li> |
---|
1379 | <li>the proximity position (the place of the node in the current node |
---|
1380 | list)</li> |
---|
1381 | <li>the context size (the size of the current node list)</li> |
---|
1382 | <li>the array of namespace declarations in scope (there also is a namespace |
---|
1383 | hash table but it is not used in the XSLT transformation).</li> |
---|
1384 | </ul> |
---|
1385 | |
---|
1386 | <p>For the purpose of XSLT an <strong>extra</strong> pointer has been added |
---|
1387 | allowing to retrieve the XSLT transformation context. When an XPath |
---|
1388 | evaluation is about to be performed, an XPath parser context is allocated |
---|
1389 | containing and XPath object stack (this is actually an XPath evaluation |
---|
1390 | context, this is a remain of the time where there was no separate parsing and |
---|
1391 | evaluation phase in the XPath implementation). Here is an overview of the set |
---|
1392 | of contexts associated to an XPath evaluation within an XSLT |
---|
1393 | transformation:</p> |
---|
1394 | |
---|
1395 | <p align="center"><img src="contexts.gif" |
---|
1396 | alt="The set of contexts associated "></p> |
---|
1397 | |
---|
1398 | <p>Clearly this is a bit too complex and confusing and should be refactored |
---|
1399 | at the next set of binary incompatible releases of libxml. For example the |
---|
1400 | xmlXPathCtxt has a lot of unused parts and should probably be merged with |
---|
1401 | xmlXPathParserCtxt.</p> |
---|
1402 | |
---|
1403 | <h3><a name="Descriptio">Description of XPath Objects</a></h3> |
---|
1404 | |
---|
1405 | <p>An XPath expression manipulates XPath objects. XPath defines the default |
---|
1406 | types boolean, numbers, strings and node sets. XSLT adds the result tree |
---|
1407 | fragment type which is basically an unmodifiable node set.</p> |
---|
1408 | |
---|
1409 | <p>Implementation-wise, libxml follows again a KISS approach, the |
---|
1410 | xmlXPathObject is a structure containing a type description and the various |
---|
1411 | possibilities. (Using an enum could have gained some bytes.) In the case of |
---|
1412 | node sets (or result tree fragments), it points to a separate xmlNodeSet |
---|
1413 | object which contains the list of pointers to the document nodes:</p> |
---|
1414 | |
---|
1415 | <p align="center"><img src="object.gif" |
---|
1416 | alt="An Node set object pointing to "></p> |
---|
1417 | |
---|
1418 | <p>The <a href="http://xmlsoft.org/html/libxml-xpath.html">XPath API</a> (and |
---|
1419 | its <a href="http://xmlsoft.org/html/libxml-xpathinternals.html">'internal' |
---|
1420 | part</a>) includes a number of functions to create, copy, compare, convert or |
---|
1421 | free XPath objects.</p> |
---|
1422 | |
---|
1423 | <h3><a name="XPath3">XPath functions</a></h3> |
---|
1424 | |
---|
1425 | <p>All the XPath functions available to the interpreter are registered in the |
---|
1426 | function hash table linked from the XPath context. They all share the same |
---|
1427 | signature:</p> |
---|
1428 | <pre>void xmlXPathFunc (xmlXPathParserContextPtr ctxt, int nargs);</pre> |
---|
1429 | |
---|
1430 | <p>The first argument is the XPath interpretation context, holding the |
---|
1431 | interpretation stack. The second argument defines the number of objects |
---|
1432 | passed on the stack for the function to consume (last argument is on top of |
---|
1433 | the stack).</p> |
---|
1434 | |
---|
1435 | <p>Basically an XPath function does the following:</p> |
---|
1436 | <ul> |
---|
1437 | <li>check <code>nargs</code> for proper handling of errors or functions |
---|
1438 | with variable numbers of parameters</li> |
---|
1439 | <li>pop the parameters from the stack using <code>obj = |
---|
1440 | valuePop(ctxt);</code></li> |
---|
1441 | <li>do the function specific computation</li> |
---|
1442 | <li>push the result parameter on the stack using <code>valuePush(ctxt, |
---|
1443 | res);</code></li> |
---|
1444 | <li>free up the input parameters with |
---|
1445 | <code>xmlXPathFreeObject(obj);</code></li> |
---|
1446 | <li>return</li> |
---|
1447 | </ul> |
---|
1448 | |
---|
1449 | <p>Sometime the work can be done directly by modifying in-situ the top object |
---|
1450 | on the stack <code>ctxt->value</code>.</p> |
---|
1451 | |
---|
1452 | <h3><a name="stack">The XSLT variables stack frame</a></h3> |
---|
1453 | |
---|
1454 | <p>Not to be confused with XPath object stack, this stack holds the XSLT |
---|
1455 | variables and parameters as they are defined through the recursive calls of |
---|
1456 | call-template, apply-templates and default templates. This is used to define |
---|
1457 | the scope of variables being called.</p> |
---|
1458 | |
---|
1459 | <p>This part seems to be the most urgent attention right now, first it is |
---|
1460 | done in a very inefficient way since the location of the variables and |
---|
1461 | parameters within the stylesheet tree is still done at run time (it really |
---|
1462 | should be done statically at compile time), and I am still unsure that my |
---|
1463 | understanding of the template variables and parameter scope is actually |
---|
1464 | right.</p> |
---|
1465 | |
---|
1466 | <p>This part of the documentation is still to be written once this part of |
---|
1467 | the code will be stable. <span |
---|
1468 | style="background-color: #FF0000">TODO</span></p> |
---|
1469 | |
---|
1470 | <h3><a name="Extension">Extension support</a></h3> |
---|
1471 | |
---|
1472 | <p>There is a separate document explaining <a href="extensions.html">how the |
---|
1473 | extension support works</a>.</p> |
---|
1474 | |
---|
1475 | <h3><a name="Futher">Further reading</a></h3> |
---|
1476 | |
---|
1477 | <p>Michael Kay wrote <a |
---|
1478 | href="http://www-106.ibm.com/developerworks/library/x-xslt2/?dwzone=x?open&l=132%2ct=gr%2c+p=saxon">a |
---|
1479 | really interesting article on Saxon internals</a> and the work he did on |
---|
1480 | performance issues. I wishes I had read it before starting libxslt design (I |
---|
1481 | would probably have avoided a few mistakes and progressed faster). A lot of |
---|
1482 | the ideas in his papers should be implemented or at least tried in |
---|
1483 | libxslt.</p> |
---|
1484 | |
---|
1485 | <p>The <a href="http://xmlsoft.org/">libxml documentation</a>, especially <a |
---|
1486 | href="http://xmlsoft.org/xmlio.html">the I/O interfaces</a> and the <a |
---|
1487 | href="http://xmlsoft.org/xmlmem.html">memory management</a>.</p> |
---|
1488 | |
---|
1489 | <h3><a name="TODOs">TODOs</a></h3> |
---|
1490 | |
---|
1491 | <p>redesign the XSLT stack frame handling. Far too much work is done at |
---|
1492 | execution time. Similarly for the attribute value templates handling, at |
---|
1493 | least the embedded subexpressions ought to be precompiled.</p> |
---|
1494 | |
---|
1495 | <p>Allow output to be saved to a SAX like output (this notion of SAX like API |
---|
1496 | for output should be added directly to libxml).</p> |
---|
1497 | |
---|
1498 | <p>Implement and test some of the optimization explained by Michael Kay |
---|
1499 | especially:</p> |
---|
1500 | <ul> |
---|
1501 | <li>static slot allocation on the stack frame</li> |
---|
1502 | <li>specific boolean interpretation of an XPath expression</li> |
---|
1503 | <li>some of the sorting optimization</li> |
---|
1504 | <li>Lazy evaluation of location path. (this may require more changes but |
---|
1505 | sounds really interesting. XT does this too.)</li> |
---|
1506 | <li>Optimization of an expression tree (This could be done as a completely |
---|
1507 | independent module.)</li> |
---|
1508 | </ul> |
---|
1509 | |
---|
1510 | <p></p> |
---|
1511 | |
---|
1512 | <p>Error reporting, there is a lot of case where the XSLT specification |
---|
1513 | specify that a given construct is an error are not checked adequately by |
---|
1514 | libxslt. Basically one should do a complete pass on the XSLT spec again and |
---|
1515 | add all tests to the stylesheet compilation. Using the DTD provided in the |
---|
1516 | appendix and making direct checks using the libxml validation API sounds a |
---|
1517 | good idea too (though one should take care of not raising errors for |
---|
1518 | elements/attributes in different namespaces).</p> |
---|
1519 | |
---|
1520 | <p>Double check all the places where the stylesheet compiled form might be |
---|
1521 | modified at run time (extra removal of blanks nodes, hint on the |
---|
1522 | xsltCompMatch).</p> |
---|
1523 | |
---|
1524 | <p></p> |
---|
1525 | |
---|
1526 | <h2><a name="Extensions">Writing extensions</a></h2> |
---|
1527 | |
---|
1528 | <h3>Table of content</h3> |
---|
1529 | <ul> |
---|
1530 | <li><a href="extensions.html#Introducti">Introduction</a></li> |
---|
1531 | <li><a href="extensions.html#Basics">Basics</a></li> |
---|
1532 | <li><a href="extensions.html#Keep">Extension modules</a></li> |
---|
1533 | <li><a href="extensions.html#Registerin">Registering a module</a></li> |
---|
1534 | <li><a href="extensions.html#module">Loading a module</a></li> |
---|
1535 | <li><a href="extensions.html#Registerin1">Registering an extension |
---|
1536 | function</a></li> |
---|
1537 | <li><a href="extensions.html#Implementi">Implementing an extension |
---|
1538 | function</a></li> |
---|
1539 | <li><a href="extensions.html#Examples">Examples for extension |
---|
1540 | functions</a></li> |
---|
1541 | <li><a href="extensions.html#Registerin2">Registering an extension |
---|
1542 | element</a></li> |
---|
1543 | <li><a href="extensions.html#Implementi1">Implementing an extension |
---|
1544 | element</a></li> |
---|
1545 | <li><a href="extensions.html#Example">Example for extension |
---|
1546 | elements</a></li> |
---|
1547 | <li><a href="extensions.html#shutdown">The shutdown of a module</a></li> |
---|
1548 | <li><a href="extensions.html#Future">Future work</a></li> |
---|
1549 | </ul> |
---|
1550 | |
---|
1551 | <h3><a name="Introducti1">Introduction</a></h3> |
---|
1552 | |
---|
1553 | <p>This document describes the work needed to write extensions to the |
---|
1554 | standard XSLT library for use with <a |
---|
1555 | href="http://xmlsoft.org/XSLT/">libxslt</a>, the <a |
---|
1556 | href="http://www.w3.org/TR/xslt">XSLT</a> C library developed for the <a |
---|
1557 | href="http://www.gnome.org/">Gnome</a> project.</p> |
---|
1558 | |
---|
1559 | <p>Before starting reading this document it is highly recommended to get |
---|
1560 | familiar with <a href="internals.html">the libxslt internals</a>.</p> |
---|
1561 | |
---|
1562 | <p>Note: this documentation is by definition incomplete and I am not good at |
---|
1563 | spelling, grammar, so patches and suggestions are <a |
---|
1564 | href="mailto:veillard@redhat.com">really welcome</a>.</p> |
---|
1565 | |
---|
1566 | <h3><a name="Basics">Basics</a></h3> |
---|
1567 | |
---|
1568 | <p>The <a href="http://www.w3.org/TR/xslt">XSLT specification</a> provides |
---|
1569 | two <a href="http://www.w3.org/TR/xslt">ways to extend an XSLT engine</a>:</p> |
---|
1570 | <ul> |
---|
1571 | <li>providing <a href="http://www.w3.org/TR/xslt">new extension |
---|
1572 | functions</a> which can be called from XPath expressions</li> |
---|
1573 | <li>providing <a href="http://www.w3.org/TR/xslt">new extension |
---|
1574 | elements</a> which can be inserted in stylesheets</li> |
---|
1575 | </ul> |
---|
1576 | |
---|
1577 | <p>In both cases the extensions need to be associated to a new namespace, |
---|
1578 | i.e. an URI used as the name for the extension's namespace (there is no need |
---|
1579 | to have a resource there for this to work).</p> |
---|
1580 | |
---|
1581 | <p>libxslt provides a few extensions itself, either in libxslt namespace |
---|
1582 | "http://xmlsoft.org/XSLT/" or in other namespace for well known extensions |
---|
1583 | provided by other XSLT processors like Saxon, Xalan or XT.</p> |
---|
1584 | |
---|
1585 | <h3><a name="Keep">Extension modules</a></h3> |
---|
1586 | |
---|
1587 | <p>Since extensions are bound to a namespace name, usually sets of extensions |
---|
1588 | coming from a given source are using the same namespace name defining in |
---|
1589 | practice a group of extensions providing elements, functions or both. From |
---|
1590 | libxslt point of view those are considered as an "extension module", and most |
---|
1591 | of the APIs work at a module point of view.</p> |
---|
1592 | |
---|
1593 | <p>Registration of new functions or elements are bound to the activation of |
---|
1594 | the module, this is currently done by declaring the namespace as an extension |
---|
1595 | by using the attribute <code>extension-element-prefixes</code> on the |
---|
1596 | <code><a href="http://www.w3.org/TR/xslt">xsl:stylesheet</a></code> |
---|
1597 | element.</p> |
---|
1598 | |
---|
1599 | <p>And extension module is defined by 3 objects:</p> |
---|
1600 | <ul> |
---|
1601 | <li>the namespace name associated</li> |
---|
1602 | <li>an initialization function</li> |
---|
1603 | <li>a shutdown function</li> |
---|
1604 | </ul> |
---|
1605 | |
---|
1606 | <h3><a name="Registerin">Registering a module</a></h3> |
---|
1607 | |
---|
1608 | <p>Currently a libxslt module has to be compiled within the application using |
---|
1609 | libxslt, there is no code to load dynamically shared libraries associated to |
---|
1610 | namespace (this may be added but is likely to become a portability |
---|
1611 | nightmare).</p> |
---|
1612 | |
---|
1613 | <p>So the current way to register a module is to link the code implementing |
---|
1614 | it with the application and to call a registration function:</p> |
---|
1615 | <pre>int xsltRegisterExtModule(const xmlChar *URI, |
---|
1616 | xsltExtInitFunction initFunc, |
---|
1617 | xsltExtShutdownFunction shutdownFunc);</pre> |
---|
1618 | |
---|
1619 | <p>The associated header is read by:</p> |
---|
1620 | <pre>#include<libxslt/extensions.h></pre> |
---|
1621 | |
---|
1622 | <p>which also defines the type for the initialization and shutdown |
---|
1623 | functions</p> |
---|
1624 | |
---|
1625 | <h3><a name="module">Loading a module</a></h3> |
---|
1626 | |
---|
1627 | <p>Once the module URI has been registered and if the XSLT processor detects |
---|
1628 | that a given stylesheet needs the functionalities of an extended module, this |
---|
1629 | one is initialized.</p> |
---|
1630 | |
---|
1631 | <p>The xsltExtInitFunction type defines the interface for an initialization |
---|
1632 | function:</p> |
---|
1633 | <pre>/** |
---|
1634 | * xsltExtInitFunction: |
---|
1635 | * @ctxt: an XSLT transformation context |
---|
1636 | * @URI: the namespace URI for the extension |
---|
1637 | * |
---|
1638 | * A function called at initialization time of an XSLT |
---|
1639 | * extension module |
---|
1640 | * |
---|
1641 | * Returns a pointer to the module specific data for this |
---|
1642 | * transformation |
---|
1643 | */ |
---|
1644 | typedef void *(*xsltExtInitFunction)(xsltTransformContextPtr ctxt, |
---|
1645 | const xmlChar *URI);</pre> |
---|
1646 | |
---|
1647 | <p>There are 3 things to notice:</p> |
---|
1648 | <ul> |
---|
1649 | <li>the function gets passed the namespace name URI as an argument, this |
---|
1650 | allow a single function to provide the initialization for multiple |
---|
1651 | logical modules</li> |
---|
1652 | <li>it also gets passed a transformation context, the initialization is |
---|
1653 | done at run time before any processing occurs on the stylesheet but it |
---|
1654 | will be invoked separately each time for each transformation</li> |
---|
1655 | <li>it returns a pointer, this can be used to store module specific |
---|
1656 | informations which can be retrieved later when a function or an element |
---|
1657 | from the extension are used, an obvious example is a connection to a |
---|
1658 | database which should be kept and reused along the transformation. NULL |
---|
1659 | is a perfectly valid return, there is no way to indicate a failure at |
---|
1660 | this level</li> |
---|
1661 | </ul> |
---|
1662 | |
---|
1663 | <p>What this function is expected to do is:</p> |
---|
1664 | <ul> |
---|
1665 | <li>prepare the context for this module (like opening the database |
---|
1666 | connection)</li> |
---|
1667 | <li>register the extensions specific to this module</li> |
---|
1668 | </ul> |
---|
1669 | |
---|
1670 | <h3><a name="Registerin1">Registering an extension function</a></h3> |
---|
1671 | |
---|
1672 | <p>There is a single call to do this registration:</p> |
---|
1673 | <pre>int xsltRegisterExtFunction(xsltTransformContextPtr ctxt, |
---|
1674 | const xmlChar *name, |
---|
1675 | const xmlChar *URI, |
---|
1676 | xmlXPathEvalFunc function);</pre> |
---|
1677 | |
---|
1678 | <p>The registration is bound to a single transformation instance referred by |
---|
1679 | ctxt, name is the UTF8 encoded name for the NCName of the function, and URI |
---|
1680 | is the namespace name for the extension (no checking is done, a module could |
---|
1681 | register functions or elements from a different namespace, but it is not |
---|
1682 | recommended).</p> |
---|
1683 | |
---|
1684 | <h3><a name="Implementi">Implementing an extension function</a></h3> |
---|
1685 | |
---|
1686 | <p>The implementation of the function must have the signature of a libxml |
---|
1687 | XPath function:</p> |
---|
1688 | <pre>/** |
---|
1689 | * xmlXPathEvalFunc: |
---|
1690 | * @ctxt: an XPath parser context |
---|
1691 | * @nargs: the number of arguments passed to the function |
---|
1692 | * |
---|
1693 | * an XPath evaluation function, the parameters are on the |
---|
1694 | * XPath context stack |
---|
1695 | */ |
---|
1696 | |
---|
1697 | typedef void (*xmlXPathEvalFunc)(xmlXPathParserContextPtr ctxt, |
---|
1698 | int nargs);</pre> |
---|
1699 | |
---|
1700 | <p>The context passed to an XPath function is not an XSLT context but an <a |
---|
1701 | href="internals.html#XPath1">XPath context</a>. However it is possible to |
---|
1702 | find one from the other:</p> |
---|
1703 | <ul> |
---|
1704 | <li>The function xsltXPathGetTransformContext provide this lookup facility: |
---|
1705 | <pre>xsltTransformContextPtr |
---|
1706 | xsltXPathGetTransformContext |
---|
1707 | (xmlXPathParserContextPtr ctxt);</pre> |
---|
1708 | </li> |
---|
1709 | <li>The <code>xmlXPathContextPtr</code> associated to an |
---|
1710 | <code>xsltTransformContext</code> is stored in the <code>xpathCtxt</code> |
---|
1711 | field.</li> |
---|
1712 | </ul> |
---|
1713 | |
---|
1714 | <p>The first thing an extension function may want to do is to check the |
---|
1715 | arguments passed on the stack, the <code>nargs</code> will precise how many |
---|
1716 | of them were provided on the XPath expression. The macros valuePop will |
---|
1717 | extract them from the XPath stack:</p> |
---|
1718 | <pre>#include <libxml/xpath.h> |
---|
1719 | #include <libxml/xpathInternals.h> |
---|
1720 | |
---|
1721 | xmlXPathObjectPtr obj = valuePop(ctxt); </pre> |
---|
1722 | |
---|
1723 | <p>Note that <code>ctxt</code> is the XPath context not the XSLT one. It is |
---|
1724 | then possible to examine the content of the value. Check <a |
---|
1725 | href="internals.html#Descriptio">the description of XPath objects</a> if |
---|
1726 | necessary. The following is a common sequcnce checking whether the argument |
---|
1727 | passed is a string and converting it using the built-in XPath |
---|
1728 | <code>string()</code> function if this is not the case:</p> |
---|
1729 | <pre>if (obj->type != XPATH_STRING) { |
---|
1730 | valuePush(ctxt, obj); |
---|
1731 | xmlXPathStringFunction(ctxt, 1); |
---|
1732 | obj = valuePop(ctxt); |
---|
1733 | }</pre> |
---|
1734 | |
---|
1735 | <p>Most common XPath functions are available directly at the C level and are |
---|
1736 | exported either in <code><libxml/xpath.h></code> or in |
---|
1737 | <code><libxml/xpathInternals.h></code>.</p> |
---|
1738 | |
---|
1739 | <p>The extension function may also need to retrieve the data associated to |
---|
1740 | this module instance (the database connection in the previous example) this |
---|
1741 | can be done using the xsltGetExtData:</p> |
---|
1742 | <pre>void * xsltGetExtData(xsltTransformContextPtr ctxt, |
---|
1743 | const xmlChar *URI);</pre> |
---|
1744 | |
---|
1745 | <p>again the URI to be provided is the one used which was used when |
---|
1746 | registering the module.</p> |
---|
1747 | |
---|
1748 | <p>Once the function finishes, don't forget to:</p> |
---|
1749 | <ul> |
---|
1750 | <li>push the return value on the stack using <code>valuePush(ctxt, |
---|
1751 | obj)</code></li> |
---|
1752 | <li>deallocate the parameters passed to the function using |
---|
1753 | <code>xmlXPathFreeObject(obj)</code></li> |
---|
1754 | </ul> |
---|
1755 | |
---|
1756 | <h3><a name="Examples">Examples for extension functions</a></h3> |
---|
1757 | |
---|
1758 | <p>The module libxslt/functions.c containsthe sources of the XSLT built-in |
---|
1759 | functions, including document(), key(), generate-id(), etc. as well as a full |
---|
1760 | example module at the end. Here is the test function implementation for the |
---|
1761 | libxslt:test function:</p> |
---|
1762 | <pre>/** |
---|
1763 | * xsltExtFunctionTest: |
---|
1764 | * @ctxt: the XPath Parser context |
---|
1765 | * @nargs: the number of arguments |
---|
1766 | * |
---|
1767 | * function libxslt:test() for testing the extensions support. |
---|
1768 | */ |
---|
1769 | static void |
---|
1770 | xsltExtFunctionTest(xmlXPathParserContextPtr ctxt, int nargs) |
---|
1771 | { |
---|
1772 | xsltTransformContextPtr tctxt; |
---|
1773 | void *data; |
---|
1774 | |
---|
1775 | tctxt = xsltXPathGetTransformContext(ctxt); |
---|
1776 | if (tctxt == NULL) { |
---|
1777 | xsltGenericError(xsltGenericErrorContext, |
---|
1778 | "xsltExtFunctionTest: failed to get the transformation context\n"); |
---|
1779 | return; |
---|
1780 | } |
---|
1781 | data = xsltGetExtData(tctxt, (const xmlChar *) XSLT_DEFAULT_URL); |
---|
1782 | if (data == NULL) { |
---|
1783 | xsltGenericError(xsltGenericErrorContext, |
---|
1784 | "xsltExtFunctionTest: failed to get module data\n"); |
---|
1785 | return; |
---|
1786 | } |
---|
1787 | #ifdef WITH_XSLT_DEBUG_FUNCTION |
---|
1788 | xsltGenericDebug(xsltGenericDebugContext, |
---|
1789 | "libxslt:test() called with %d args\n", nargs); |
---|
1790 | #endif |
---|
1791 | }</pre> |
---|
1792 | |
---|
1793 | <h3><a name="Registerin2">Registering an extension element</a></h3> |
---|
1794 | |
---|
1795 | <p>There is a single call to do this registration:</p> |
---|
1796 | <pre>int xsltRegisterExtElement(xsltTransformContextPtr ctxt, |
---|
1797 | const xmlChar *name, |
---|
1798 | const xmlChar *URI, |
---|
1799 | xsltTransformFunction function);</pre> |
---|
1800 | |
---|
1801 | <p>It is similar to the mechanism used to register an extension function, |
---|
1802 | except that the signature of an extension element implementation is |
---|
1803 | different.</p> |
---|
1804 | |
---|
1805 | <p>The registration is bound to a single transformation instance referred by |
---|
1806 | ctxt, name is the UTF8 encoded name for the NCName of the element, and URI is |
---|
1807 | the namespace name for the extension (no checking is done, a module could |
---|
1808 | register elements for a different namespace, but it is not recommended).</p> |
---|
1809 | |
---|
1810 | <h3><a name="Implementi1">Implementing an extension element</a></h3> |
---|
1811 | |
---|
1812 | <p>The implementation of the element must have the signature of an XSLT |
---|
1813 | transformation function:</p> |
---|
1814 | <pre>/** |
---|
1815 | * xsltTransformFunction: |
---|
1816 | * @ctxt: the XSLT transformation context |
---|
1817 | * @node: the input node |
---|
1818 | * @inst: the stylesheet node |
---|
1819 | * @comp: the compiled information from the stylesheet |
---|
1820 | * |
---|
1821 | * signature of the function associated to elements part of the |
---|
1822 | * stylesheet language like xsl:if or xsl:apply-templates. |
---|
1823 | */ |
---|
1824 | typedef void (*xsltTransformFunction) |
---|
1825 | (xsltTransformContextPtr ctxt, |
---|
1826 | xmlNodePtr node, |
---|
1827 | xmlNodePtr inst, |
---|
1828 | xsltStylePreCompPtr comp);</pre> |
---|
1829 | |
---|
1830 | <p>The first argument is the XSLT transformation context. The second and |
---|
1831 | third arguments are xmlNodePtr i.e. internal memory <a |
---|
1832 | href="internals.html#libxml">representation of XML nodes</a>. They are |
---|
1833 | respectively <code>node</code> from the the input document being transformed |
---|
1834 | by the stylesheet and <code>inst</code> the extension element in the |
---|
1835 | stylesheet. The last argument is <code>comp</code> a pointer to a precompiled |
---|
1836 | representation of <code>inst</code> but usually for extension function this |
---|
1837 | value is <code>NULL</code> by default (it could be added and associated to |
---|
1838 | the instruction in <code>inst->_private</code>).</p> |
---|
1839 | |
---|
1840 | <p>The same functions are available from a function implementing an extension |
---|
1841 | element as in an extension function, including |
---|
1842 | <code>xsltGetExtData()</code>.</p> |
---|
1843 | |
---|
1844 | <p>The goal of extension element being usually to enrich the generated |
---|
1845 | output, it is expected that they will grow the currently generated output |
---|
1846 | tree, this can be done by grabbing ctxt->insert which is the current |
---|
1847 | libxml node being generated (Note this can also be the intermediate value |
---|
1848 | tree being built for example to initialize a variable, the processing should |
---|
1849 | be similar). The functions for libxml tree manipulation from <a |
---|
1850 | href="http://xmlsoft.org/html/libxml-tree.html"><libxml/tree.h></a> can |
---|
1851 | be employed to extend or modify the tree, but it is required to preserve the |
---|
1852 | insertion node and its ancestors since there is existing pointers to those |
---|
1853 | elements still in use in the XSLT template execution stack.</p> |
---|
1854 | |
---|
1855 | <h3><a name="Example">Example for extension elements</a></h3> |
---|
1856 | |
---|
1857 | <p>The module libxslt/transform.c containsthe sources of the XSLT built-in |
---|
1858 | elements, including xsl:element, xsl:attribute, xsl:if, etc. There is a small |
---|
1859 | but full example in functions.c providing the implementation for the |
---|
1860 | libxslt:test element, it will output a comment in the result tree:</p> |
---|
1861 | <pre>/** |
---|
1862 | * xsltExtElementTest: |
---|
1863 | * @ctxt: an XSLT processing context |
---|
1864 | * @node: The current node |
---|
1865 | * @inst: the instruction in the stylesheet |
---|
1866 | * @comp: precomputed informations |
---|
1867 | * |
---|
1868 | * Process a libxslt:test node |
---|
1869 | */ |
---|
1870 | static void |
---|
1871 | xsltExtElementTest(xsltTransformContextPtr ctxt, xmlNodePtr node, |
---|
1872 | xmlNodePtr inst, |
---|
1873 | xsltStylePreCompPtr comp) |
---|
1874 | { |
---|
1875 | xmlNodePtr comment; |
---|
1876 | |
---|
1877 | if (ctxt == NULL) { |
---|
1878 | xsltGenericError(xsltGenericErrorContext, |
---|
1879 | "xsltExtElementTest: no transformation context\n"); |
---|
1880 | return; |
---|
1881 | } |
---|
1882 | if (node == NULL) { |
---|
1883 | xsltGenericError(xsltGenericErrorContext, |
---|
1884 | "xsltExtElementTest: no current node\n"); |
---|
1885 | return; |
---|
1886 | } |
---|
1887 | if (inst == NULL) { |
---|
1888 | xsltGenericError(xsltGenericErrorContext, |
---|
1889 | "xsltExtElementTest: no instruction\n"); |
---|
1890 | return; |
---|
1891 | } |
---|
1892 | if (ctxt->insert == NULL) { |
---|
1893 | xsltGenericError(xsltGenericErrorContext, |
---|
1894 | "xsltExtElementTest: no insertion point\n"); |
---|
1895 | return; |
---|
1896 | } |
---|
1897 | comment = |
---|
1898 | xmlNewComment((const xmlChar *) |
---|
1899 | "libxslt:test element test worked"); |
---|
1900 | xmlAddChild(ctxt->insert, comment); |
---|
1901 | }</pre> |
---|
1902 | |
---|
1903 | <h3><a name="shutdown">The shutdown of a module</a></h3> |
---|
1904 | |
---|
1905 | <p>When the XSLT processor ends a transformation, the shutdown function (if |
---|
1906 | it exists) of all the modules initialized are called.The |
---|
1907 | xsltExtShutdownFunction type defines the interface for a shutdown |
---|
1908 | function:</p> |
---|
1909 | <pre>/** |
---|
1910 | * xsltExtShutdownFunction: |
---|
1911 | * @ctxt: an XSLT transformation context |
---|
1912 | * @URI: the namespace URI for the extension |
---|
1913 | * @data: the data associated to this module |
---|
1914 | * |
---|
1915 | * A function called at shutdown time of an XSLT extension module |
---|
1916 | */ |
---|
1917 | typedef void (*xsltExtShutdownFunction) (xsltTransformContextPtr ctxt, |
---|
1918 | const xmlChar *URI, |
---|
1919 | void *data);</pre> |
---|
1920 | |
---|
1921 | <p>this is really similar to a module initialization function except a third |
---|
1922 | argument is passed, it's the value that was returned by the initialization |
---|
1923 | function. This allow to deallocate resources from the module for example |
---|
1924 | close the connection to the database to keep the same example.</p> |
---|
1925 | |
---|
1926 | <h3><a name="Future">Future work</a></h3> |
---|
1927 | |
---|
1928 | <p>Well some of the pieces missing:</p> |
---|
1929 | <ul> |
---|
1930 | <li>a way to load shared libraries to instanciate new modules</li> |
---|
1931 | <li>a better detection of extension function usage and their registration |
---|
1932 | without having to use the extension prefix which ought to be reserved to |
---|
1933 | element extensions.</li> |
---|
1934 | <li>more examples</li> |
---|
1935 | <li>implementations of the <a href="http://www.exslt.org/">EXSLT</a> common |
---|
1936 | extension libraries, Thomas Broyer nearly finished implementing them.</li> |
---|
1937 | </ul> |
---|
1938 | |
---|
1939 | <p></p> |
---|
1940 | |
---|
1941 | <h2><a name="Contributi">Contributions</a></h2> |
---|
1942 | <ul> |
---|
1943 | <li>Bjorn Reese is the author of the number support and worked on the |
---|
1944 | XSLTMark support</li> |
---|
1945 | <li>William Brack was an early adopted, contributed a number of patches and |
---|
1946 | spent quite some time debugging non-trivial problems in early versions of |
---|
1947 | libxslt</li> |
---|
1948 | <li><a href="mailto:igor@zlatkovic.com">Igor Zlatkovic</a> is now the |
---|
1949 | maintainer of the Windows port, <a |
---|
1950 | href="http://www.zlatkovic.com/projects/libxml/index.html">he provides |
---|
1951 | binaries</a></li> |
---|
1952 | <li>Thomas Broyer provided a lot of suggestions, and drafted most of the |
---|
1953 | extension API</li> |
---|
1954 | <li>John Fleck maintains <a href="tutorial/libxslttutorial.html">a tutorial |
---|
1955 | for libxslt</a></li> |
---|
1956 | <li><a |
---|
1957 | href="http://mail.gnome.org/archives/xml/2001-March/msg00014.html">Matt |
---|
1958 | Sergeant</a> developed <a |
---|
1959 | href="http://axkit.org/download/">XML::LibXSLT</a>, a perl wrapper for |
---|
1960 | libxml2/libxslt as part of the <a href="http://axkit.com/">AxKit XML |
---|
1961 | application server</a></li> |
---|
1962 | <li>there is a module for <a |
---|
1963 | href="http://acs-misc.sourceforge.net/nsxml.html">libxml/libxslt support |
---|
1964 | in OpenNSD/AOLServer</a></li> |
---|
1965 | <li><a href="mailto:dkuhlman@cutter.rexx.com">Dave Kuhlman</a> provides |
---|
1966 | libxml/libxslt <a href="http://www.rexx.com/~dkuhlman">wrappers for |
---|
1967 | Python</a></li> |
---|
1968 | <li>Steve Ball and contributors maintains <a |
---|
1969 | href="http://tclxml.sourceforge.net/">libxml2</a> and <a |
---|
1970 | href="http://tclxml.sourceforge.net/tclxslt.html">libxslt</a> bindings |
---|
1971 | for Tcl</li> |
---|
1972 | <li>If you want to use libxslt in a Mac OS X/Cocoa or Objective-C |
---|
1973 | framework, Marc Liyanage provides <a |
---|
1974 | href="http://www.entropy.ch/software/macosx/#testxslt">an application |
---|
1975 | TestXSLT for XSLT and XML editing</a> including wrapper classes for the |
---|
1976 | XML parser and XSLT processor.</li> |
---|
1977 | </ul> |
---|
1978 | |
---|
1979 | <p>I'm still waiting for someone to contribute a simple XSLT processing |
---|
1980 | module for Apache :-)</p> |
---|
1981 | |
---|
1982 | <p></p> |
---|
1983 | |
---|
1984 | <p><a href="mailto:daniel@veillard.com">Daniel Veillard</a></p> |
---|
1985 | </body> |
---|
1986 | </html> |
---|