summaryrefslogtreecommitdiff
path: root/doc/extensions.html
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@src.gnome.org>2006-06-09 13:40:33 +0000
committerDaniel Veillard <veillard@src.gnome.org>2006-06-09 13:40:33 +0000
commit54f9859bf2bf1ded0454bfbaf6070d0b9aab43ee (patch)
treebe14caa750d95698179362f7800a49b16cc6b385 /doc/extensions.html
parentd9d50ec1505a65ccc62f692df28efe6112990d8a (diff)
downloadlibxslt-54f9859bf2bf1ded0454bfbaf6070d0b9aab43ee.tar.gz
libxslt-54f9859bf2bf1ded0454bfbaf6070d0b9aab43ee.tar.bz2
libxslt-54f9859bf2bf1ded0454bfbaf6070d0b9aab43ee.zip
Fixing the screwups introduced by amaya, Daniel
Diffstat (limited to 'doc/extensions.html')
-rw-r--r--doc/extensions.html265
1 files changed, 132 insertions, 133 deletions
diff --git a/doc/extensions.html b/doc/extensions.html
index ac06e7ff..aab2f428 100644
--- a/doc/extensions.html
+++ b/doc/extensions.html
@@ -13,53 +13,54 @@ 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
- 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#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#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 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>
+</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>
<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
-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,
+</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,
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
-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>/**
+ 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>/**
* xsltExtInitFunction:
* @ctxt: an XSLT transformation context
* @URI: the namespace URI for the extension
@@ -71,30 +72,30 @@ initializationfunction:</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.
- 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>
+ 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>
<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
-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 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:
* @ctxt: an XPath parser context
* @nargs: the number of arguments passed to the function
@@ -104,43 +105,43 @@ libxmlXPath 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 tofind
-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 to
+find 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
-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;
+ <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;
#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
-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) {
+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) {
valuePush(ctxt, obj);
xmlXPathStringFunction(ctxt, 1);
obj = valuePop(ctxt);
-}</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>/**
+}</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>/**
* xsltExtFunctionTest:
* @ctxt: the XPath Parser context
* @nargs: the number of arguments
@@ -172,14 +173,13 @@ 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
-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 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:
* @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 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>/**
+ 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>/**
* 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 (ifit
-exists) for each of the modules initialized is called.
-ThexsltExtShutdownFunction type defines the interface for a
-shutdownfunction:</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 (if
+it exists) for each of the modules initialized is called. The
+xsltExtShutdownFunction type defines the interface for a shutdown
+function:</p><pre>/**
* xsltExtShutdownFunction:
* @ctxt: an XSLT transformation context
* @URI: the namespace URI for the extension
@@ -266,15 +266,14 @@ shutdownfunction:</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
-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>
+ 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>
<li>more examples</li>
- <li>implementations of the <a href="http://www.exslt.org/">EXSLT</a>commonextension libraries, Thomas
- Broyer nearly finished implementing them.</li>
+ <li>implementations of the <a href="http://www.exslt.org/">EXSLT</a> common
+ extension 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>