1 | <?xml version="1.0" encoding="ISO-8859-1"?>
|
---|
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
---|
3 | <html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /><style type="text/css">
|
---|
4 | TD {font-family: Verdana,Arial,Helvetica}
|
---|
5 | BODY {font-family: Verdana,Arial,Helvetica; margin-top: 2em; margin-left: 0em; margin-right: 0em}
|
---|
6 | H1 {font-family: Verdana,Arial,Helvetica}
|
---|
7 | H2 {font-family: Verdana,Arial,Helvetica}
|
---|
8 | H3 {font-family: Verdana,Arial,Helvetica}
|
---|
9 | A:link, A:visited, A:active { text-decoration: underline }
|
---|
10 | </style><title>Writing extensions</title></head><body bgcolor="#8b7765" text="#000000" link="#a06060" vlink="#000000"><table border="0" width="100%" cellpadding="5" cellspacing="0" align="center"><tr><td width="120"><a href="http://swpat.ffii.org/"><img src="epatents.png" alt="Action against software patents" /></a></td><td width="180"><a href="http://www.gnome.org/"><img src="gnome2.png" alt="GNOME2 Logo" /></a><a href="http://www.w3.org/Status"><img src="w3c.png" alt="W3C logo" /></a><a href="http://www.redhat.com"><img src="redhat.gif" alt="Red Hat Logo" /></a><div align="left"><a href="http://xmlsoft.org/XSLT/"><img src="Libxslt-Logo-180x168.gif" alt="Made with Libxslt Logo" /></a></div></td><td><table border="0" width="90%" cellpadding="2" cellspacing="0" align="center" bgcolor="#000000"><tr><td><table width="100%" border="0" cellspacing="1" cellpadding="3" bgcolor="#fffacd"><tr><td align="center"><h1>The XSLT C library for GNOME</h1><h2>Writing extensions</h2></td></tr></table></td></tr></table></td></tr></table><table border="0" cellpadding="4" cellspacing="0" width="100%" align="center"><tr><td bgcolor="#8b7765"><table border="0" cellspacing="0" cellpadding="2" width="100%"><tr><td valign="top" width="200" bgcolor="#8b7765"><table border="0" cellspacing="0" cellpadding="1" width="100%" bgcolor="#000000"><tr><td><table width="100%" border="0" cellspacing="1" cellpadding="3"><tr><td colspan="1" bgcolor="#eecfa1" align="center"><center><b>Main Menu</b></center></td></tr><tr><td bgcolor="#fffacd"><form action="search.php" enctype="application/x-www-form-urlencoded" method="get"><input name="query" type="text" size="20" value="" /><input name="submit" type="submit" value="Search ..." /></form><ul><li><a href="index.html">Home</a></li><li><a href="intro.html">Introduction</a></li><li><a href="docs.html">Documentation</a></li><li><a href="bugs.html">Reporting bugs and getting help</a></li><li><a href="help.html">How to help</a></li><li><a href="downloads.html">Downloads</a></li><li><a href="FAQ.html">FAQ</a></li><li><a href="news.html">News</a></li><li><a href="xsltproc2.html">The xsltproc tool</a></li><li><a href="docbook.html">DocBook</a></li><li><a href="API.html">The programming API</a></li><li><a href="python.html">Python and bindings</a></li><li><a href="internals.html">Library internals</a></li><li><a href="extensions.html">Writing extensions</a></li><li><a href="contribs.html">Contributions</a></li><li><a href="EXSLT/index.html" style="font-weight:bold">libexslt</a></li><li><a href="xslt.html">flat page</a>, <a href="site.xsl">stylesheet</a></li><li><a href="html/index.html" style="font-weight:bold">API Menu</a></li><li><a href="ChangeLog.html">ChangeLog</a></li></ul></td></tr></table><table width="100%" border="0" cellspacing="1" cellpadding="3"><tr><td colspan="1" bgcolor="#eecfa1" align="center"><center><b>Related links</b></center></td></tr><tr><td bgcolor="#fffacd"><ul><li><a href="tutorial/libxslttutorial.html">Tutorial</a>,
|
---|
11 | <a href="tutorial2/libxslt_pipes.html">Tutorial2</a></li><li><a href="xsltproc.html">Man page for xsltproc</a></li><li><a href="http://mail.gnome.org/archives/xslt/">Mail archive</a></li><li><a href="http://xmlsoft.org/">XML libxml2</a></li><li><a href="ftp://xmlsoft.org/">FTP</a></li><li><a href="http://www.zlatkovic.com/projects/libxml/">Windows binaries</a></li><li><a href="http://garypennington.net/libxml2/">Solaris binaries</a></li><li><a href="http://www.explain.com.au/oss/libxml2xslt.html">MacOsX binaries</a></li><li><a href="http://bugzilla.gnome.org/buglist.cgi?product=libxslt">Bug Tracker</a></li><li><a href="http://codespeak.net/lxml/">lxml Python bindings</a></li><li><a href="http://cpan.uwinnipeg.ca/dist/XML-LibXSLT">Perl XSLT bindings</a></li><li><a href="http://www.zend.com/php5/articles/php5-xmlphp.php#Heading17">XSLT with PHP</a></li><li><a href="http://www.mod-xslt2.com/">Apache module</a></li><li><a href="http://sourceforge.net/projects/libxml2-pas/">Pascal bindings</a></li><li><a href="http://xsldbg.sourceforge.net/">Xsldbg Debugger</a></li></ul></td></tr></table><table width="100%" border="0" cellspacing="1" cellpadding="3"><tr><td colspan="1" bgcolor="#eecfa1" align="center"><center><b>API Indexes</b></center></td></tr><tr><td bgcolor="#fffacd"><ul><li><a href="APIchunk0.html">Alphabetic</a></li><li><a href="APIconstructors.html">Constructors</a></li><li><a href="APIfunctions.html">Functions/Types</a></li><li><a href="APIfiles.html">Modules</a></li><li><a href="APIsymbols.html">Symbols</a></li></ul></td></tr></table></td></tr></table></td><td valign="top" bgcolor="#8b7765"><table border="0" cellspacing="0" cellpadding="1" width="100%"><tr><td><table border="0" cellspacing="0" cellpadding="1" width="100%" bgcolor="#000000"><tr><td><table border="0" cellpadding="3" cellspacing="1" width="100%"><tr><td bgcolor="#fffacd"><h3>Table of content</h3><ul><li><a href="extensions.html#Introducti">Introduction</a></li>
|
---|
12 | <li><a href="extensions.html#Basics">Basics</a></li>
|
---|
13 | <li><a href="extensions.html#Keep">Extension modules</a></li>
|
---|
14 | <li><a href="extensions.html#Registerin">Registering a module</a></li>
|
---|
15 | <li><a href="extensions.html#module">Loading a module</a></li>
|
---|
16 | <li><a href="extensions.html#Registerin1">Registering an extension
|
---|
17 | function</a></li>
|
---|
18 | <li><a href="extensions.html#Implementi">Implementing an extension
|
---|
19 | function</a></li>
|
---|
20 | <li><a href="extensions.html#Examples">Examples for extension
|
---|
21 | functions</a></li>
|
---|
22 | <li><a href="extensions.html#Registerin2">Registering an extension
|
---|
23 | element</a></li>
|
---|
24 | <li><a href="extensions.html#Implementi1">Implementing an extension
|
---|
25 | element</a></li>
|
---|
26 | <li><a href="extensions.html#Example">Example for extension
|
---|
27 | elements</a></li>
|
---|
28 | <li><a href="extensions.html#shutdown">The shutdown of a module</a></li>
|
---|
29 | <li><a href="extensions.html#Future">Future work</a></li>
|
---|
30 | </ul><h3><a name="Introducti1" id="Introducti1">Introduction</a></h3><p>This document describes the work needed to write extensions to the
|
---|
31 | standard XSLT library for use with <a href="http://xmlsoft.org/XSLT/">libxslt</a>, the <a href="http://www.w3.org/TR/xslt">XSLT</a> C library developed for the <a href="http://www.gnome.org/">GNOME</a> project.</p><p>Before starting reading this document it is highly recommended to get
|
---|
32 | familiar with <a href="internals.html">the libxslt internals</a>.</p><p>Note: this documentation is by definition incomplete and I am not good at
|
---|
33 | spelling, grammar, so patches and suggestions are <a href="mailto:[email protected]">really welcome</a>.</p><h3><a name="Basics" id="Basics">Basics</a></h3><p>The <a href="http://www.w3.org/TR/xslt">XSLT specification</a> provides
|
---|
34 | two <a href="http://www.w3.org/TR/xslt">ways to extend an XSLT engine</a>:</p><ul><li>providing <a href="http://www.w3.org/TR/xslt">new extension
|
---|
35 | functions</a> which can be called from XPath expressions</li>
|
---|
36 | <li>providing <a href="http://www.w3.org/TR/xslt">new extension
|
---|
37 | elements</a> which can be inserted in stylesheets</li>
|
---|
38 | </ul><p>In both cases the extensions need to be associated to a new namespace,
|
---|
39 | i.e. an URI used as the name for the extension's namespace (there is no need
|
---|
40 | to have a resource there for this to work).</p><p>libxslt provides a few extensions itself, either in the libxslt namespace
|
---|
41 | "http://xmlsoft.org/XSLT/namespace" or in namespaces for other well known
|
---|
42 | extensions provided by other XSLT processors like Saxon, Xalan or XT.</p><h3><a name="Keep" id="Keep">Extension modules</a></h3><p>Since extensions are bound to a namespace name, usually sets of extensions
|
---|
43 | coming from a given source are using the same namespace name defining in
|
---|
44 | practice a group of extensions providing elements, functions or both. From
|
---|
45 | the libxslt point of view those are considered as an "extension module", and
|
---|
46 | most of the APIs work at a module point of view.</p><p>Registration of new functions or elements are bound to the activation of
|
---|
47 | the module. This is currently done by declaring the namespace as an extension
|
---|
48 | by using the attribute <code>extension-element-prefixes</code> on the
|
---|
49 | <code><a href="http://www.w3.org/TR/xslt">xsl:stylesheet</a></code>
|
---|
50 | element.</p><p>An extension module is defined by 3 objects:</p><ul><li>the namespace name associated</li>
|
---|
51 | <li>an initialization function</li>
|
---|
52 | <li>a shutdown function</li>
|
---|
53 | </ul><h3><a name="Registerin" id="Registerin">Registering a module</a></h3><p>Currently a libxslt module has to be compiled within the application using
|
---|
54 | libxslt. There is no code to load dynamically shared libraries associated to
|
---|
55 | a namespace (this may be added but is likely to become a portability
|
---|
56 | nightmare).</p><p>The current way to register a module is to link the code implementing it
|
---|
57 | with the application and to call a registration function:</p><pre>int xsltRegisterExtModule(const xmlChar *URI,
|
---|
58 | xsltExtInitFunction initFunc,
|
---|
59 | xsltExtShutdownFunction shutdownFunc);</pre><p>The associated header is read by:</p><pre>#include<libxslt/extensions.h></pre><p>which also defines the type for the initialization and shutdown
|
---|
60 | functions</p><h3><a name="module" id="module">Loading a module</a></h3><p>Once the module URI has been registered and if the XSLT processor detects
|
---|
61 | that a given stylesheet needs the functionalities of an extended module, this
|
---|
62 | one is initialized.</p><p>The xsltExtInitFunction type defines the interface for an initialization
|
---|
63 | function:</p><pre>/**
|
---|
64 | * xsltExtInitFunction:
|
---|
65 | * @ctxt: an XSLT transformation context
|
---|
66 | * @URI: the namespace URI for the extension
|
---|
67 | *
|
---|
68 | * A function called at initialization time of an XSLT
|
---|
69 | * extension module
|
---|
70 | *
|
---|
71 | * Returns a pointer to the module specific data for this
|
---|
72 | * transformation
|
---|
73 | */
|
---|
74 | typedef void *(*xsltExtInitFunction)(xsltTransformContextPtr ctxt,
|
---|
75 | const xmlChar *URI);</pre><p>There are 3 things to notice:</p><ul><li>The function gets passed the namespace name URI as an argument. This
|
---|
76 | allows a single function to provide the initialization for multiple
|
---|
77 | logical modules.</li>
|
---|
78 | <li>It also gets passed a transformation context. The initialization is
|
---|
79 | done at run time before any processing occurs on the stylesheet but it
|
---|
80 | will be invoked separately each time for each transformation.</li>
|
---|
81 | <li>It returns a pointer. This can be used to store module specific
|
---|
82 | information which can be retrieved later when a function or an element
|
---|
83 | from the extension is used. An obvious example is a connection to a
|
---|
84 | database which should be kept and reused along with the transformation.
|
---|
85 | NULL is a perfectly valid return; there is no way to indicate a failure
|
---|
86 | at this level</li>
|
---|
87 | </ul><p>What this function is expected to do is:</p><ul><li>prepare the context for this module (like opening the database
|
---|
88 | connection)</li>
|
---|
89 | <li>register the extensions specific to this module</li>
|
---|
90 | </ul><h3><a name="Registerin1" id="Registerin1">Registering an extension function</a></h3><p>There is a single call to do this registration:</p><pre>int xsltRegisterExtFunction(xsltTransformContextPtr ctxt,
|
---|
91 | const xmlChar *name,
|
---|
92 | const xmlChar *URI,
|
---|
93 | xmlXPathEvalFunc function);</pre><p>The registration is bound to a single transformation instance referred by
|
---|
94 | ctxt, name is the UTF8 encoded name for the NCName of the function, and URI
|
---|
95 | is the namespace name for the extension (no checking is done, a module could
|
---|
96 | register functions or elements from a different namespace, but it is not
|
---|
97 | recommended).</p><h3><a name="Implementi" id="Implementi">Implementing an extension function</a></h3><p>The implementation of the function must have the signature of a libxml
|
---|
98 | XPath function:</p><pre>/**
|
---|
99 | * xmlXPathEvalFunc:
|
---|
100 | * @ctxt: an XPath parser context
|
---|
101 | * @nargs: the number of arguments passed to the function
|
---|
102 | *
|
---|
103 | * an XPath evaluation function, the parameters are on the
|
---|
104 | * XPath context stack
|
---|
105 | */
|
---|
106 |
|
---|
107 | typedef void (*xmlXPathEvalFunc)(xmlXPathParserContextPtr ctxt,
|
---|
108 | int nargs);</pre><p>The context passed to an XPath function is not an XSLT context but an <a href="internals.html#XPath1">XPath context</a>. However it is possible to
|
---|
109 | find one from the other:</p><ul><li>The function xsltXPathGetTransformContext provides this lookup facility:
|
---|
110 | <pre>xsltTransformContextPtr
|
---|
111 | xsltXPathGetTransformContext
|
---|
112 | (xmlXPathParserContextPtr ctxt);</pre>
|
---|
113 | </li>
|
---|
114 | <li>The <code>xmlXPathContextPtr</code> associated to an
|
---|
115 | <code>xsltTransformContext</code> is stored in the <code>xpathCtxt</code>
|
---|
116 | field.</li>
|
---|
117 | </ul><p>The first thing an extension function may want to do is to check the
|
---|
118 | arguments passed on the stack, the <code>nargs</code> parameter will tell how
|
---|
119 | many of them were provided on the XPath expression. The macro valuePop will
|
---|
120 | extract them from the XPath stack:</p><pre>#include <libxml/xpath.h>
|
---|
121 | #include <libxml/xpathInternals.h>
|
---|
122 |
|
---|
123 | xmlXPathObjectPtr obj = valuePop(ctxt); </pre><p>Note that <code>ctxt</code> is the XPath context not the XSLT one. It is
|
---|
124 | then possible to examine the content of the value. Check <a href="internals.html#Descriptio">the description of XPath objects</a> if
|
---|
125 | necessary. The following is a common sequence checking whether the argument
|
---|
126 | passed is a string and converting it using the built-in XPath
|
---|
127 | <code>string()</code> function if this is not the case:</p><pre>if (obj->type != XPATH_STRING) {
|
---|
128 | valuePush(ctxt, obj);
|
---|
129 | xmlXPathStringFunction(ctxt, 1);
|
---|
130 | obj = valuePop(ctxt);
|
---|
131 | }</pre><p>Most common XPath functions are available directly at the C level and are
|
---|
132 | exported either in <code><libxml/xpath.h></code> or in
|
---|
133 | <code><libxml/xpathInternals.h></code>.</p><p>The extension function may also need to retrieve the data associated to
|
---|
134 | this module instance (the database connection in the previous example) this
|
---|
135 | can be done using the xsltGetExtData:</p><pre>void * xsltGetExtData(xsltTransformContextPtr ctxt,
|
---|
136 | const xmlChar *URI);</pre><p>Again the URI to be provided is the one which was used when registering
|
---|
137 | the module.</p><p>Once the function finishes, don't forget to:</p><ul><li>push the return value on the stack using <code>valuePush(ctxt,
|
---|
138 | obj)</code></li>
|
---|
139 | <li>deallocate the parameters passed to the function using
|
---|
140 | <code>xmlXPathFreeObject(obj)</code></li>
|
---|
141 | </ul><h3><a name="Examples" id="Examples">Examples for extension functions</a></h3><p>The module libxslt/functions.c contains the sources of the XSLT built-in
|
---|
142 | functions, including document(), key(), generate-id(), etc. as well as a full
|
---|
143 | example module at the end. Here is the test function implementation for the
|
---|
144 | libxslt:test function:</p><pre>/**
|
---|
145 | * xsltExtFunctionTest:
|
---|
146 | * @ctxt: the XPath Parser context
|
---|
147 | * @nargs: the number of arguments
|
---|
148 | *
|
---|
149 | * function libxslt:test() for testing the extensions support.
|
---|
150 | */
|
---|
151 | static void
|
---|
152 | xsltExtFunctionTest(xmlXPathParserContextPtr ctxt, int nargs)
|
---|
153 | {
|
---|
154 | xsltTransformContextPtr tctxt;
|
---|
155 | void *data;
|
---|
156 |
|
---|
157 | tctxt = xsltXPathGetTransformContext(ctxt);
|
---|
158 | if (tctxt == NULL) {
|
---|
159 | xsltGenericError(xsltGenericErrorContext,
|
---|
160 | "xsltExtFunctionTest: failed to get the transformation context\n");
|
---|
161 | return;
|
---|
162 | }
|
---|
163 | data = xsltGetExtData(tctxt, (const xmlChar *) XSLT_DEFAULT_URL);
|
---|
164 | if (data == NULL) {
|
---|
165 | xsltGenericError(xsltGenericErrorContext,
|
---|
166 | "xsltExtFunctionTest: failed to get module data\n");
|
---|
167 | return;
|
---|
168 | }
|
---|
169 | #ifdef WITH_XSLT_DEBUG_FUNCTION
|
---|
170 | xsltGenericDebug(xsltGenericDebugContext,
|
---|
171 | "libxslt:test() called with %d args\n", nargs);
|
---|
172 | #endif
|
---|
173 | }</pre><h3><a name="Registerin2" id="Registerin2">Registering an extension element</a></h3><p>There is a single call to do this registration:</p><pre>int xsltRegisterExtElement(xsltTransformContextPtr ctxt,
|
---|
174 | const xmlChar *name,
|
---|
175 | const xmlChar *URI,
|
---|
176 | xsltTransformFunction function);</pre><p>It is similar to the mechanism used to register an extension function,
|
---|
177 | except that the signature of an extension element implementation is
|
---|
178 | different.</p><p>The registration is bound to a single transformation instance referred to
|
---|
179 | by ctxt, name is the UTF8 encoded name for the NCName of the element, and URI
|
---|
180 | is the namespace name for the extension (no checking is done, a module could
|
---|
181 | register elements for a different namespace, but it is not recommended).</p><h3><a name="Implementi1" id="Implementi1">Implementing an extension element</a></h3><p>The implementation of the element must have the signature of an XSLT
|
---|
182 | transformation function:</p><pre>/**
|
---|
183 | * xsltTransformFunction:
|
---|
184 | * @ctxt: the XSLT transformation context
|
---|
185 | * @node: the input node
|
---|
186 | * @inst: the stylesheet node
|
---|
187 | * @comp: the compiled information from the stylesheet
|
---|
188 | *
|
---|
189 | * signature of the function associated to elements part of the
|
---|
190 | * stylesheet language like xsl:if or xsl:apply-templates.
|
---|
191 | */
|
---|
192 | typedef void (*xsltTransformFunction)
|
---|
193 | (xsltTransformContextPtr ctxt,
|
---|
194 | xmlNodePtr node,
|
---|
195 | xmlNodePtr inst,
|
---|
196 | xsltStylePreCompPtr comp);</pre><p>The first argument is the XSLT transformation context. The second and
|
---|
197 | third arguments are xmlNodePtr i.e. internal memory <a href="internals.html#libxml">representation of XML nodes</a>. They are
|
---|
198 | respectively <code>node</code> from the the input document being transformed
|
---|
199 | by the stylesheet and <code>inst</code> the extension element in the
|
---|
200 | stylesheet. The last argument is <code>comp</code> a pointer to a precompiled
|
---|
201 | representation of <code>inst</code> but usually for an extension function
|
---|
202 | this value is <code>NULL</code> by default (it could be added and associated
|
---|
203 | to the instruction in <code>inst->_private</code>).</p><p>The same functions are available from a function implementing an extension
|
---|
204 | element as in an extension function, including
|
---|
205 | <code>xsltGetExtData()</code>.</p><p>The goal of an extension element being usually to enrich the generated
|
---|
206 | output, it is expected that they will grow the currently generated output
|
---|
207 | tree. This can be done by grabbing ctxt->insert which is the current
|
---|
208 | libxml node being generated (Note this can also be the intermediate value
|
---|
209 | tree being built for example to initialize a variable, the processing should
|
---|
210 | be similar). The functions for libxml tree manipulation from <a href="http://xmlsoft.org/html/libxml-tree.html"><libxml/tree.h></a> can
|
---|
211 | be employed to extend or modify the tree, but it is required to preserve the
|
---|
212 | insertion node and its ancestors since there are existing pointers to those
|
---|
213 | elements still in use in the XSLT template execution stack.</p><h3><a name="Example" id="Example">Example for extension elements</a></h3><p>The module libxslt/transform.c contains the sources of the XSLT built-in
|
---|
214 | elements, including xsl:element, xsl:attribute, xsl:if, etc. There is a small
|
---|
215 | but full example in functions.c providing the implementation for the
|
---|
216 | libxslt:test element, it will output a comment in the result tree:</p><pre>/**
|
---|
217 | * xsltExtElementTest:
|
---|
218 | * @ctxt: an XSLT processing context
|
---|
219 | * @node: The current node
|
---|
220 | * @inst: the instruction in the stylesheet
|
---|
221 | * @comp: precomputed information
|
---|
222 | *
|
---|
223 | * Process a libxslt:test node
|
---|
224 | */
|
---|
225 | static void
|
---|
226 | xsltExtElementTest(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
---|
227 | xmlNodePtr inst,
|
---|
228 | xsltStylePreCompPtr comp)
|
---|
229 | {
|
---|
230 | xmlNodePtr comment;
|
---|
231 |
|
---|
232 | if (ctxt == NULL) {
|
---|
233 | xsltGenericError(xsltGenericErrorContext,
|
---|
234 | "xsltExtElementTest: no transformation context\n");
|
---|
235 | return;
|
---|
236 | }
|
---|
237 | if (node == NULL) {
|
---|
238 | xsltGenericError(xsltGenericErrorContext,
|
---|
239 | "xsltExtElementTest: no current node\n");
|
---|
240 | return;
|
---|
241 | }
|
---|
242 | if (inst == NULL) {
|
---|
243 | xsltGenericError(xsltGenericErrorContext,
|
---|
244 | "xsltExtElementTest: no instruction\n");
|
---|
245 | return;
|
---|
246 | }
|
---|
247 | if (ctxt->insert == NULL) {
|
---|
248 | xsltGenericError(xsltGenericErrorContext,
|
---|
249 | "xsltExtElementTest: no insertion point\n");
|
---|
250 | return;
|
---|
251 | }
|
---|
252 | comment =
|
---|
253 | xmlNewComment((const xmlChar *)
|
---|
254 | "libxslt:test element test worked");
|
---|
255 | xmlAddChild(ctxt->insert, comment);
|
---|
256 | }</pre><h3><a name="shutdown" id="shutdown">The shutdown of a module</a></h3><p>When the XSLT processor ends a transformation, the shutdown function (if
|
---|
257 | it exists) for each of the modules initialized is called. The
|
---|
258 | xsltExtShutdownFunction type defines the interface for a shutdown
|
---|
259 | function:</p><pre>/**
|
---|
260 | * xsltExtShutdownFunction:
|
---|
261 | * @ctxt: an XSLT transformation context
|
---|
262 | * @URI: the namespace URI for the extension
|
---|
263 | * @data: the data associated to this module
|
---|
264 | *
|
---|
265 | * A function called at shutdown time of an XSLT extension module
|
---|
266 | */
|
---|
267 | typedef void (*xsltExtShutdownFunction) (xsltTransformContextPtr ctxt,
|
---|
268 | const xmlChar *URI,
|
---|
269 | void *data);</pre><p>This is really similar to a module initialization function except a third
|
---|
270 | argument is passed, it's the value that was returned by the initialization
|
---|
271 | function. This allows the routine to deallocate resources from the module for
|
---|
272 | example close the connection to the database to keep the same example.</p><h3><a name="Future" id="Future">Future work</a></h3><p>Well, some of the pieces missing:</p><ul><li>a way to load shared libraries to instantiate new modules</li>
|
---|
273 | <li>a better detection of extension functions usage and their registration
|
---|
274 | without having to use the extension prefix which ought to be reserved to
|
---|
275 | element extensions.</li>
|
---|
276 | <li>more examples</li>
|
---|
277 | <li>implementations of the <a href="http://www.exslt.org/">EXSLT</a> common
|
---|
278 | extension libraries, Thomas Broyer nearly finished implementing them.</li>
|
---|
279 | </ul><p></p><p><a href="bugs.html">Daniel Veillard</a></p></td></tr></table></td></tr></table></td></tr></table></td></tr></table></td></tr></table></body></html>
|
---|