[xslt] The nature of xsltApplyOneTemplate() needs to be modified
- From: "Buchcik, Kasimier" <k buchcik 4commerce de>
- To: <xslt gnome org>
- Subject: [xslt] The nature of xsltApplyOneTemplate() needs to be modified
- Date: Wed, 28 Jun 2006 18:40:48 +0200
Hi,
I noticed a problem with the semantics of xsltApplyOneTemplate() and
it's actual usage in Libxslt/Libexslt. This function is currently
used to handle 3 alternative scenarios, but fails to do so, since
it it is designed for only 1 scenario.
I'll try to explain the issue and will present a potential solution.
xsltApplyOneTemplate(xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr list,
xsltTemplatePtr templ,
xsltStackElemPtr params);
1) The usage in exsltFuncFunctionFunction() (libexslt/function.c):
Here the number of xsl:param instructions, which are set by the
invoking function call are processed with
xsltParseStylesheetCallerParam() and handed over to
xsltApplyOneTemplate() via @params; remaining xsl:param(s) in
@list are expected to be processed by xsltApplyOneTemplate().
Example: the following function is called with "my:func('zoo')".
<func:function name="my:func">
<xsl:param name="foo"/>
<xsl:param name="bar"/>
</func:function>
<xsl:param name="foo"/> is processed by exsltFuncFunctionFunction(),
and the remaining <xsl:param name="bar"/> is expected to be processed
by xsltApplyOneTemplate().
@templ is not given, since there's no xsl:template.
Side note: Using xsltParseStylesheetCallerParam(), which is intended
for xsl:with-param, to process xsl:param is actually a hack,
since there's no appropriate function to process xsl:param(s) in
Libxslt
for this scenario.
2) The usage in Libxslt:
a) It is called to process a template (or sequence constructor in
XSLT 2.0). This means *no* xsl:param instructions are expected in
@list, and @params and @templ are both NULL.
b) It is called to process an xsl:template. This means xsl:param(s)
*are*
expected in @list, and caller-params (xsl:with-param) are handed
over
via @params; @templ is the compiled xsl:template struct.
The clashes are easier to spot in the following table:
@params @list @templ
1) reflects xsl:param(s) can contain more xsl:param(s) always NULL
2a) refl. xsl:with-param(s) can contain xsl:param(s) refl.
xsl:template
2b) always NULL must not contain xsl:param(s) always NULL
Proposed solution:
1) Change xsltApplyOneTemplate():
- *reject* xsl:param(s) in @list (raise an error if one is found)
- @params are any xsl:param(s) already processed by the caller
- @templ is *not* used (ATTRIBUTE_UNUSED)
- do *not* initiate a new variable scope (it did so previously
when @templ was given)
So, if @params is NULL, xsltApplyOneTemplate() will actually become
a function for processing of a normal template (in constrast to
xsl:template); e.g. for the content of an xsl:for-each instruction.
If @params is given, then those are pushed on the variable stack;
This, for example, reflects the content model of an exslt:function,
which is (xsl:param*, template) - *without* the possibility
to override xsl:param(s) with xsl:with-param.
Note that due to this change 4 calling functions (see below)
need to be adjusted in Libxslt; all other calls are already OK for
the modified nature of xsltApplyOneTemplate().
2) Add xsltApplyXSLTTemplate() for processing of xsl:template.
This function will expect:
- @templ
- optional @withParams, reflecting xsl:with-param instructions;
those will override xsl:param(s) in @list
- xsl:param(s) in @list still to be processed
This function will then be used if a xsl:template needs to be
processed - namely in:
- xsltApplyImports()
- xsltCallTemplate()
- xsltDefaultProcessOneNode()
- xsltProcessOneNode()
3) Change exsltFuncFunctionFunction() in Libexslt to
process *all* xsl:param(s) and to hand over *all* processed
xsl:param(s) to xsltApplyOneTemplate().
This is a fix, since the current way of calling
xsltApplyOneTemplate() was simply incorrect.
I think this is the most trouble-free solution for users, as the
changes will only have impact on scenarios where an xsl:template
needs to be processed; normally xsl:template should only be
processed internally by Libxslt - not in user-code.
Immediate comments are appreciated. I already refactored
the code in the proposed way on my side and would like to commit
as soon as possible if accepted.
Regards,
Kasimier
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]