[xslt] XSLT extension API


Just as I made suggestions in the libxml list about the XPath extension
API, here is my view (just suggestions) of the XSLT extension API. This is
nearly (maybe exactly, I didn't check) what I proposed last fall when we
were talking about libxslt's design.

An "extension module" (refered as "module" below) consists of extension
elements and functions (for use in XPath expressions) belonging to a
specific namespace.

Each module has a registration function registering the namespace and
further information (see below) in an application wide, global hash table.

A module also has two registration functions passed a context as argument,
registering the module's functions or elements.
The "RegisterFunctions" function is called if the namespace is declared in
the stylesheet. This is done at evaluation time.
The "RegisterElements" function is called as soon as the namespace is
declared an extension-element namespace (using the
(xsl:)extension-element-prefixes attribute(s)). This is done at stylesheet
compiling time.

A module may use data shared by all its elements and functions (for
example, a database connection). A module must then provide functions to
allocate and free the data structure. These data structures are kept in an
hash table (the key is the namespace URI) in the evaluation context. The
functions aren't called directly by extension implementors (for cleanly
"unregister" the data from the hash table).

An element may need (I don't know if it is really necessary) to do some
computation at parsing (stylesheet compiling) time (as the XSLT
decimal-format and key do for instance). The data structure is kept in an
hash table in the stylesheet directly. It should be allocated in the
"RegisterElements" function or a "NewData" function provided by the module,
and the module must provide a "FreeData" function called when the
stylesheet is freed to free the data. Each element may then have an
associated function passed its element node and its content subtree.
Such elements are likely to be only top-level elements. An element must
then be registered as a (possibly) top-level element. The "Precompute"
function is called only for top-level elements, and elements not registered
as top-level elements but found at the top level raise an error.
These elements are processed in two phases: stylesheet compilation and
stylesheet evaluation (data may need to be computed depending on the
context, as for XSLT variables and params).
Maybe every element (not only top-level elements) should have this
"two-phases" processing scheme to allow them to precompute even context
dependant data (as it should be done for attribute valu templates:
precomputation so that only the "dynamic" part has to be evaluated, the AVT
doesn't need to be parsed each time the node is processed ; as for XPath
expressions and XSLT matching patterns)

The global information is composed of:
  the two registration functions (for elements and functions)
  the "FreeData" function, eventually a "NewData" function
  functions to allocate/free the context-dependant data structure

  global registration of the namespace
  functions and elements registered separately
  for each element:
    whether it may appear at top-level
    the "Precompute" function
    the "Evaluate" function
  functions to access the module's data:
     /* used when compiling the stylesheet */
     void * xsltPreCompGetModuleData (stylesheet, namespaceURI);

     /* used when transforming, processing extension elements */
     void * xsltNewData (ctxt, namespaceURI)
     void * xsltGetData (ctxt, namespaceURI)
     void   xsltFreeData (ctxt, namespaceURI);

     void * xsltGetModuleData(ctxt, namespaceURI);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]