Re: [xslt] extension modules
- From: Thomas Broyer <tbroyer ltgt net>
- To: xslt gnome org
- Subject: Re: [xslt] extension modules
- Date: Mon, 23 Jul 2001 19:39:47 +0200
Le 22/07/01 18:16:28, Thomas Broyer a écrit :
> Le 22/07/01 16:54:36, Daniel Veillard a écrit :
> > > Here's a list of some of the changes:
> > > · added function lookup framework to libxml/XPath and used it in
> > > libxslt and modified the extension element lookup in the same way
> > > (look for the element in the context, then in the global
> registry)
> >
> > Not sure I understand this one. can you give me the names of the
> > functions ?
>
> /*
> * Function Lookup forwarding
> */
> typedef xmlXPathFunction
> (*xmlXPathFuncLookupFunc) (void *ctxt,
> const xmlChar *name,
> const xmlChar *ns_uri);
>
> void xmlXPathRegisterFuncLookup (xmlXPathContextPtr ctxt,
> xmlXPathFuncLookupFunc f,
> void *funcCtxt);
>
> libxslt registers its own lookup function to also look for extension
> module
> functions in the global hash table.
>
> > Everything else sounds fine.
>
> Great ;o)
>
> > > What's still needed:
> > > · correct handling of extension-element-prefixes and
> > > exclude-result-prefixes. extension-element-prefixes may need
> > > binding data to the _private field of *every* element node (even
> > > literal result elements)
> >
> > Hum, that part is complex. Tell exactly what you need and I will
> > check.
> > I took great care of not destroying performances to handle those and
> this
> > requires a lot of attention to get right.
> > In general if you start adding data or processing for each node at
> > run time then thwin twice and ask first :-)
>
> Well, I'm not sure what's really needed...
> Maybe extension-element-prefixes can be handled the same way
> exclude-result-prefixes are handled, since we'll precompute extension
> elements.
> I'll look at it in details...
According to http://lists.w3.org/Archives/Public/xsl-editors/1999JulSep/0091.html,
extension-element-prefixes isn't needed by element-available, and this was
the only place where precomputation wouldn't have been possible.
Extension element prefixes can be handled _totally_ at preprocessing, in a
way similar to how exclude-result-prefixes are handled.
This leads me to wonder where the data needed during precomputation of
these attributes (and maybe other things) should be stored.
Currently, exclude-result-prefixes precomputation uses xsltStylesheet, but
the data is only needed for precomputation and (seems) no longer used
afterwards.
Using a "precomp context" would be a solution but requires some more memory
allocation/freeing...
> Actually, I was thinking of making a stripped down version of
> xsltStylePreComp and adding 2 types: extension element and literal result
> element. Extension elements could then extend this struct with their own
> precomputed data, and -- most important -- associate a callback function
> to process the node.
> There are 3 things that can justify that:
> · if extension-element-prefixes, and maybe exclude-result-prefixes,
> handling needs some data bindings at node level
> · extension elements have a way of adding precomputed data:
> the stylesheet is a bit more homogeneous, and -- most important --
> the struct can carry a free() function. This way, the _private
> field can be used without memory leak or hackish "registration" of
> computed data to be freed by the module's shutdown function (something
> similar to the preComps field of xsltStylesheet, that any module
> implementor would have to mimic) If I'm not clear enough, I can
> provide a better, longer explaination ;o)
> · the callback function for extension elements can be attached to the
> node instead of being looked up for each transformation
>
> If the first point isn't needed, literal result elements do not need
> precomputed data.
>
> Processing of an element would then consist only in calling
> _private->func (or check whether its a literal result element --
> _private is NULL -- and then copy the node or call _private->func ; if
> the first point above is not needed)
>
> This may improve performances of transformations (more things are
> computed during preprocessing)
>
> Also, extension elements now consist only in a precomp function, and its
> up to this function to set the {precomp}->func => no need to look up the
> transform function in a hash table any more => better performances (maybe
> its peanut, I don't know...)
>
> Just an idea...
The "first point" is not needed, so what should I do? Are we going for the
"extension element precomputed data framework"?
Here's an API proposal:
xsltPreComputeFunction returns an xsltStylePreCompPtr. If it returns NULL,
the processor puts xsltExtMarker in node->_private, otherwise it puts the
returned value.
/* stripped down version, the "complete" one would be renamed */
typedef xsltStylePreComp *xsltStylePreCompPtr;
...
typedef void (*xsltStylePreCompFreeFunction) (xsltStylePreCompPtr comp);
/* allocate and initialize */
void xsltNewStylePreComp (xsltStylesheetPtr style, xsltStyleType type,
xmlNodePtr inst,
xsltTransformFunction function);
/* initialize only, for "extended data struct" */
void xsltInitStylePreComp (xsltStylePreCompPtr comp, ...same args...,
xsltStylePreCompFreeFunction freeFunc);
As an example, the func:result element would do something like this:
typedef struct {
xsltStylePreComp comp; /* cast to StylePreComp possible */
xmlXPathCompExprPtr select;
} exsltFuncResultPreComp, *exsltFuncResultPreCompPtr;
/* commes a free function */
xsltStylePreCompPtr
exsltFuncResultElemComp (... style, ... inst) {
exsltFuncResultPreCompPtr ret;
xmlChar *select;
...
ret = /* malloc & memset + error handling */
xsltInitStylePreComp (ret, style, XSLT_EXTENSION_ELEM, inst,
exsltFuncResultElem, exsltFreeFuncResultPreComp);
...
/* parse the select attribute */
select = xmlGetPropNs (inst, (const xmlChar *) "select", NULL);
ret->select = xmlXPathCompile (select);
...
return ((xsltStylePreCompPtr) ret);
}
void
exsltFuncResultElem (...ctxt, ...node, ...inst, ...comp) {
...
if ((comp == NULL) || (comp == xsltExtMarker)) {
/* ERROR: not initialized */
return;
}
...
/* retrieve the compiled expression */
select = ((exsltFuncResultPreCompPtr) comp)->select;
...
}
Tom.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]