summaryrefslogtreecommitdiff
path: root/doc/extensions.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/extensions.html')
-rw-r--r--doc/extensions.html265
1 files changed, 133 insertions, 132 deletions
diff --git a/doc/extensions.html b/doc/extensions.html
index aab2f428..ac06e7ff 100644
--- a/doc/extensions.html
+++ b/doc/extensions.html
@@ -13,54 +13,53 @@ A:link, A:visited, A:active { text-decoration: underline }
<li><a href="extensions.html#Keep">Extension modules</a></li>
<li><a href="extensions.html#Registerin">Registering a module</a></li>
<li><a href="extensions.html#module">Loading a module</a></li>
- <li><a href="extensions.html#Registerin1">Registering an extension
- function</a></li>
- <li><a href="extensions.html#Implementi">Implementing an extension
- function</a></li>
- <li><a href="extensions.html#Examples">Examples for extension
- functions</a></li>
- <li><a href="extensions.html#Registerin2">Registering an extension
- element</a></li>
- <li><a href="extensions.html#Implementi1">Implementing an extension
- element</a></li>
- <li><a href="extensions.html#Example">Example for extension
- elements</a></li>
+ <li><a href="extensions.html#Registerin1">Registering an
+ extensionfunction</a></li>
+ <li><a href="extensions.html#Implementi">Implementing an
+ extensionfunction</a></li>
+ <li><a href="extensions.html#Examples">Examples for
+ extensionfunctions</a></li>
+ <li><a href="extensions.html#Registerin2">Registering an
+ extensionelement</a></li>
+ <li><a href="extensions.html#Implementi1">Implementing an
+ extensionelement</a></li>
+ <li><a href="extensions.html#Example">Example for extensionelements</a></li>
<li><a href="extensions.html#shutdown">The shutdown of a module</a></li>
<li><a href="extensions.html#Future">Future work</a></li>
-</ul><h3><a name="Introducti1" id="Introducti1">Introduction</a></h3><p>This document describes the work needed to write extensions to the
-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
-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
-spelling, grammar, so patches and suggestions are <a href="mailto:veillard@redhat.com">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
-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
- functions</a> which can be called from XPath expressions</li>
- <li>providing <a href="http://www.w3.org/TR/xslt">new extension
- elements</a> which can be inserted in stylesheets</li>
-</ul><p>In both cases the extensions need to be associated to a new namespace,
-i.e. an URI used as the name for the extension's namespace (there is no need
-to have a resource there for this to work).</p><p>libxslt provides a few extensions itself, either in the libxslt namespace
-"http://xmlsoft.org/XSLT/namespace" or in namespaces for other well known
-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
-coming from a given source are using the same namespace name defining in
-practice a group of extensions providing elements, functions or both. From
-the libxslt point of view those are considered as an "extension module", and
-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
-the module. This is currently done by declaring the namespace as an extension
-by using the attribute <code>extension-element-prefixes</code> on the
-<code><a href="http://www.w3.org/TR/xslt">xsl:stylesheet</a></code>
-element.</p><p>An extension module is defined by 3 objects:</p><ul><li>the namespace name associated</li>
+</ul><h3><a name="Introducti1" id="Introducti1">Introduction</a></h3><p>This document describes the work needed to write extensions to thestandard
+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
+getfamiliar with <a href="internals.html">the libxslt internals</a>.</p><p>Note: this documentation is by definition incomplete and I am not good
+atspelling, grammar, so patches and suggestions are <a href="mailto:veillard@redhat.com">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>providestwo
+<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
+ extensionfunctions</a>which can be called from XPath expressions</li>
+ <li>providing <a href="http://www.w3.org/TR/xslt">new
+ extensionelements</a>which can be inserted in stylesheets</li>
+</ul><p>In both cases the extensions need to be associated to a new namespace,i.e.
+an URI used as the name for the extension's namespace (there is no needto
+have a resource there for this to work).</p><p>libxslt provides a few extensions itself, either in the libxslt
+namespace"http://xmlsoft.org/XSLT/namespace" or in namespaces for other well
+knownextensions 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
+extensionscoming from a given source are using the same namespace name
+defining inpractice a group of extensions providing elements, functions or
+both. Fromthe libxslt point of view those are considered as an "extension
+module", andmost of the APIs work at a module point of view.</p><p>Registration of new functions or elements are bound to the activation
+ofthe module. This is currently done by declaring the namespace as an
+extensionby using the attribute <code>extension-element-prefixes</code>on
+the<code><a href="http://www.w3.org/TR/xslt">xsl:stylesheet</a></code>element.</p><p>An extension module is defined by 3 objects:</p><ul><li>the namespace name associated</li>
<li>an initialization function</li>
<li>a shutdown function</li>
-</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
-libxslt. There is no code to load dynamically shared libraries associated to
-a namespace (this may be added but is likely to become a portability
-nightmare).</p><p>The current way to register a module is to link the code implementing it
-with the application and to call a registration function:</p><pre>int xsltRegisterExtModule(const xmlChar *URI,
+</ul><h3><a name="Registerin" id="Registerin">Registering a module</a></h3><p>Currently a libxslt module has to be compiled within the application
+usinglibxslt. There is no code to load dynamically shared libraries
+associated toa namespace (this may be added but is likely to become a
+portabilitynightmare).</p><p>The current way to register a module is to link the code implementing
+itwith the application and to call a registration function:</p><pre>int xsltRegisterExtModule(const xmlChar *URI,
xsltExtInitFunction initFunc,
- xsltExtShutdownFunction shutdownFunc);</pre><p>The associated header is read by:</p><pre>#include&lt;libxslt/extensions.h&gt;</pre><p>which also defines the type for the initialization and shutdown
-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
-that a given stylesheet needs the functionalities of an extended module, this
-one is initialized.</p><p>The xsltExtInitFunction type defines the interface for an initialization
-function:</p><pre>/**
+ xsltExtShutdownFunction shutdownFunc);</pre><p>The associated header is read by:</p><pre>#include&lt;libxslt/extensions.h&gt;</pre><p>which also defines the type for the initialization and
+shutdownfunctions</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
+detectsthat a given stylesheet needs the functionalities of an extended
+module, thisone is initialized.</p><p>The xsltExtInitFunction type defines the interface for an
+initializationfunction:</p><pre>/**
* xsltExtInitFunction:
* @ctxt: an XSLT transformation context
* @URI: the namespace URI for the extension
@@ -72,30 +71,30 @@ function:</p><pre>/**
* transformation
*/
typedef void *(*xsltExtInitFunction)(xsltTransformContextPtr ctxt,
- 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
- allows a single function to provide the initialization for multiple
- logical modules.</li>
- <li>It also gets passed a transformation context. The initialization is
- done at run time before any processing occurs on the stylesheet but it
- will be invoked separately each time for each transformation.</li>
- <li>It returns a pointer. This can be used to store module specific
- information which can be retrieved later when a function or an element
- from the extension is used. An obvious example is a connection to a
- database which should be kept and reused along with the transformation.
- NULL is a perfectly valid return; there is no way to indicate a failure
- at this level</li>
-</ul><p>What this function is expected to do is:</p><ul><li>prepare the context for this module (like opening the database
- connection)</li>
+ 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.
+ Thisallows a single function to provide the initialization for
+ multiplelogical modules.</li>
+ <li>It also gets passed a transformation context. The initialization isdone
+ at run time before any processing occurs on the stylesheet but itwill be
+ invoked separately each time for each transformation.</li>
+ <li>It returns a pointer. This can be used to store module
+ specificinformation which can be retrieved later when a function or an
+ elementfrom the extension is used. An obvious example is a connection to
+ adatabase which should be kept and reused along with the
+ transformation.NULL is a perfectly valid return; there is no way to
+ indicate a failureat this level</li>
+</ul><p>What this function is expected to do is:</p><ul><li>prepare the context for this module (like opening the
+ databaseconnection)</li>
<li>register the extensions specific to this module</li>
</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,
const xmlChar *name,
const xmlChar *URI,
- xmlXPathEvalFunc function);</pre><p>The registration is bound to a single transformation instance referred by
-ctxt, name is the UTF8 encoded name for the NCName of the function, and URI
-is the namespace name for the extension (no checking is done, a module could
-register functions or elements from a different namespace, but it is not
-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
-XPath function:</p><pre>/**
+ xmlXPathEvalFunc function);</pre><p>The registration is bound to a single transformation instance referred
+byctxt, name is the UTF8 encoded name for the NCName of the function, and
+URIis the namespace name for the extension (no checking is done, a module
+couldregister functions or elements from a different namespace, but it is
+notrecommended).</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
+libxmlXPath function:</p><pre>/**
* xmlXPathEvalFunc:
* @ctxt: an XPath parser context
* @nargs: the number of arguments passed to the function
@@ -105,43 +104,43 @@ XPath function:</p><pre>/**
*/
typedef void (*xmlXPathEvalFunc)(xmlXPathParserContextPtr ctxt,
- 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
-find one from the other:</p><ul><li>The function xsltXPathGetTransformContext provides this lookup facility:
+ 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 tofind
+one from the other:</p><ul><li>The function xsltXPathGetTransformContext provides this lookup facility:
<pre>xsltTransformContextPtr
xsltXPathGetTransformContext
(xmlXPathParserContextPtr ctxt);</pre>
</li>
- <li>The <code>xmlXPathContextPtr</code> associated to an
- <code>xsltTransformContext</code> is stored in the <code>xpathCtxt</code>
- field.</li>
-</ul><p>The first thing an extension function may want to do is to check the
-arguments passed on the stack, the <code>nargs</code> parameter will tell how
-many of them were provided on the XPath expression. The macro valuePop will
-extract them from the XPath stack:</p><pre>#include &lt;libxml/xpath.h&gt;
+ <li>The <code>xmlXPathContextPtr</code>associated to
+ an<code>xsltTransformContext</code>is stored in the
+ <code>xpathCtxt</code>field.</li>
+</ul><p>The first thing an extension function may want to do is to check
+thearguments passed on the stack, the <code>nargs</code>parameter will tell
+howmany of them were provided on the XPath expression. The macro valuePop
+willextract them from the XPath stack:</p><pre>#include &lt;libxml/xpath.h&gt;
#include &lt;libxml/xpathInternals.h&gt;
-xmlXPathObjectPtr obj = valuePop(ctxt); </pre><p>Note that <code>ctxt</code> is the XPath context not the XSLT one. It is
-then possible to examine the content of the value. Check <a href="internals.html#Descriptio">the description of XPath objects</a> if
-necessary. The following is a common sequence checking whether the argument
-passed is a string and converting it using the built-in XPath
-<code>string()</code> function if this is not the case:</p><pre>if (obj-&gt;type != XPATH_STRING) {
+xmlXPathObjectPtr obj = valuePop(ctxt); </pre><p>Note that <code>ctxt</code>is the XPath context not the XSLT one. It
+isthen possible to examine the content of the value. Check <a href="internals.html#Descriptio">the description of XPath
+objects</a>ifnecessary. The following is a common sequence checking whether
+the argumentpassed is a string and converting it using the built-in
+XPath<code>string()</code>function if this is not the case:</p><pre>if (obj-&gt;type != XPATH_STRING) {
valuePush(ctxt, obj);
xmlXPathStringFunction(ctxt, 1);
obj = valuePop(ctxt);
-}</pre><p>Most common XPath functions are available directly at the C level and are
-exported either in <code>&lt;libxml/xpath.h&gt;</code> or in
-<code>&lt;libxml/xpathInternals.h&gt;</code>.</p><p>The extension function may also need to retrieve the data associated to
-this module instance (the database connection in the previous example) this
-can be done using the xsltGetExtData:</p><pre>void * xsltGetExtData(xsltTransformContextPtr ctxt,
- const xmlChar *URI);</pre><p>Again the URI to be provided is the one which was used when registering
-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,
- obj)</code></li>
- <li>deallocate the parameters passed to the function using
- <code>xmlXPathFreeObject(obj)</code></li>
-</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
-functions, including document(), key(), generate-id(), etc. as well as a full
-example module at the end. Here is the test function implementation for the
-libxslt:test function:</p><pre>/**
+}</pre><p>Most common XPath functions are available directly at the C level and
+areexported either in <code>&lt;libxml/xpath.h&gt;</code>or
+in<code>&lt;libxml/xpathInternals.h&gt;</code>.</p><p>The extension function may also need to retrieve the data associated
+tothis module instance (the database connection in the previous example)
+thiscan be done using the xsltGetExtData:</p><pre>void * xsltGetExtData(xsltTransformContextPtr ctxt,
+ const xmlChar *URI);</pre><p>Again the URI to be provided is the one which was used when registeringthe
+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,obj)</code></li>
+ <li>deallocate the parameters passed to the function
+ using<code>xmlXPathFreeObject(obj)</code></li>
+</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-infunctions, including document(), key(), generate-id(), etc. as well
+as a fullexample module at the end. Here is the test function implementation
+for thelibxslt:test function:</p><pre>/**
* xsltExtFunctionTest:
* @ctxt: the XPath Parser context
* @nargs: the number of arguments
@@ -173,13 +172,14 @@ xsltExtFunctionTest(xmlXPathParserContextPtr ctxt, int nargs)
}</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,
const xmlChar *name,
const xmlChar *URI,
- xsltTransformFunction function);</pre><p>It is similar to the mechanism used to register an extension function,
-except that the signature of an extension element implementation is
-different.</p><p>The registration is bound to a single transformation instance referred to
-by ctxt, name is the UTF8 encoded name for the NCName of the element, and URI
-is the namespace name for the extension (no checking is done, a module could
-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
-transformation function:</p><pre>/**
+ xsltTransformFunction function);</pre><p>It is similar to the mechanism used to register an extension
+function,except that the signature of an extension element implementation
+isdifferent.</p><p>The registration is bound to a single transformation instance referred
+toby ctxt, name is the UTF8 encoded name for the NCName of the element, and
+URIis the namespace name for the extension (no checking is done, a module
+couldregister 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
+XSLTtransformation function:</p><pre>/**
* xsltTransformFunction:
* @ctxt: the XSLT transformation context
* @node: the input node
@@ -193,27 +193,27 @@ typedef void (*xsltTransformFunction)
(xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
- xsltStylePreCompPtr comp);</pre><p>The first argument is the XSLT transformation context. The second and
-third arguments are xmlNodePtr i.e. internal memory <a href="internals.html#libxml">representation of XML nodes</a>. They are
-respectively <code>node</code> from the the input document being transformed
-by the stylesheet and <code>inst</code> the extension element in the
-stylesheet. The last argument is <code>comp</code> a pointer to a precompiled
-representation of <code>inst</code> but usually for an extension function
-this value is <code>NULL</code> by default (it could be added and associated
-to the instruction in <code>inst-&gt;_private</code>).</p><p>The same functions are available from a function implementing an extension
-element as in an extension function, including
-<code>xsltGetExtData()</code>.</p><p>The goal of an extension element being usually to enrich the generated
-output, it is expected that they will grow the currently generated output
-tree. This can be done by grabbing ctxt-&gt;insert which is the current
-libxml node being generated (Note this can also be the intermediate value
-tree being built for example to initialize a variable, the processing should
-be similar). The functions for libxml tree manipulation from <a href="http://xmlsoft.org/html/libxml-tree.html">&lt;libxml/tree.h&gt;</a> can
-be employed to extend or modify the tree, but it is required to preserve the
-insertion node and its ancestors since there are existing pointers to those
-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
-elements, including xsl:element, xsl:attribute, xsl:if, etc. There is a small
-but full example in functions.c providing the implementation for the
-libxslt:test element, it will output a comment in the result tree:</p><pre>/**
+ xsltStylePreCompPtr comp);</pre><p>The first argument is the XSLT transformation context. The second andthird
+arguments are xmlNodePtr i.e. internal memory <a href="internals.html#libxml">representation of XML nodes</a>. They
+arerespectively <code>node</code>from the the input document being
+transformedby the stylesheet and <code>inst</code>the extension element in
+thestylesheet. The last argument is <code>comp</code>a pointer to a
+precompiledrepresentation of <code>inst</code>but usually for an extension
+functionthis value is <code>NULL</code>by default (it could be added and
+associatedto the instruction in <code>inst-&gt;_private</code>).</p><p>The same functions are available from a function implementing an
+extensionelement as in an extension function,
+including<code>xsltGetExtData()</code>.</p><p>The goal of an extension element being usually to enrich the
+generatedoutput, it is expected that they will grow the currently generated
+outputtree. This can be done by grabbing ctxt-&gt;insert which is the
+currentlibxml node being generated (Note this can also be the intermediate
+valuetree being built for example to initialize a variable, the processing
+shouldbe similar). The functions for libxml tree manipulation from <a href="http://xmlsoft.org/html/libxml-tree.html">&lt;libxml/tree.h&gt;</a>canbe
+employed to extend or modify the tree, but it is required to preserve
+theinsertion node and its ancestors since there are existing pointers to
+thoseelements 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-inelements, including xsl:element, xsl:attribute, xsl:if, etc. There is
+a smallbut full example in functions.c providing the implementation for
+thelibxslt:test element, it will output a comment in the result tree:</p><pre>/**
* xsltExtElementTest:
* @ctxt: an XSLT processing context
* @node: The current node
@@ -253,10 +253,10 @@ xsltExtElementTest(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNewComment((const xmlChar *)
"libxslt:test element test worked");
xmlAddChild(ctxt-&gt;insert, comment);
-}</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
-it exists) for each of the modules initialized is called. The
-xsltExtShutdownFunction type defines the interface for a shutdown
-function:</p><pre>/**
+}</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 (ifit
+exists) for each of the modules initialized is called.
+ThexsltExtShutdownFunction type defines the interface for a
+shutdownfunction:</p><pre>/**
* xsltExtShutdownFunction:
* @ctxt: an XSLT transformation context
* @URI: the namespace URI for the extension
@@ -266,14 +266,15 @@ function:</p><pre>/**
*/
typedef void (*xsltExtShutdownFunction) (xsltTransformContextPtr ctxt,
const xmlChar *URI,
- void *data);</pre><p>This is really similar to a module initialization function except a third
-argument is passed, it's the value that was returned by the initialization
-function. This allows the routine to deallocate resources from the module for
-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>
- <li>a better detection of extension functions usage and their registration
- without having to use the extension prefix which ought to be reserved to
- element extensions.</li>
+ void *data);</pre><p>This is really similar to a module initialization function except a
+thirdargument is passed, it's the value that was returned by the
+initializationfunction. This allows the routine to deallocate resources from
+the module forexample 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>
+ <li>a better detection of extension functions usage and their
+ registrationwithout having to use the extension prefix which ought to be
+ reserved toelement extensions.</li>
<li>more examples</li>
- <li>implementations of the <a href="http://www.exslt.org/">EXSLT</a> common
- extension libraries, Thomas Broyer nearly finished implementing them.</li>
+ <li>implementations of the <a href="http://www.exslt.org/">EXSLT</a>commonextension libraries, Thomas
+ Broyer nearly finished implementing them.</li>
</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>