1
0
mirror of https://gitlab.gnome.org/GNOME/libxslt synced 2026-01-07 21:58:22 +03:00

Big changes (but planned for a long time) small mem leak in docbook

still to fix:
- preproc.[ch] templates.[ch] variables.[ch] xslt.c xsltInternals.h
  attributes.c extensions.[ch]: moved all stylesheet precomputation
  at stylesheet loading time (stylesheet transform should be thread
  safe now), improved params and variables evaluations (but optim
  is not complete yet).
- TODO: updated
Daniel
This commit is contained in:
Daniel Veillard
2001-04-29 09:52:50 +00:00
parent 765abf021e
commit eef9a85837
15 changed files with 709 additions and 548 deletions

View File

@@ -1,3 +1,12 @@
Sun Apr 29 11:47:58 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* preproc.[ch] templates.[ch] variables.[ch] xslt.c xsltInternals.h
attributes.c extensions.[ch]: moved all stylesheet precomputation
at stylesheet loading time (stylesheet transform should be thread
safe now), improved params and variables evaluations (but optim
is not complete yet).
* TODO: updated
Sat Apr 28 16:28:45 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* libxslt/xsltproc.c : changed the way --repeat works when

17
TODO
View File

@@ -8,15 +8,9 @@ Doc:
- manpage and doc for xsltproc
Design:
- should transforms for a given stylesheet be thread clean,
or can a stylesheet be enriched with document specific
informations and cleaned up later ?
- seems that saving back XSLT stylesheet from a compiled form might
be a bit ugly ...
Embedding Stylesheets:
- example in 2.7 would force to validate, we do it by default now
Import:
@@ -51,6 +45,17 @@ Sorting:
* *
********
Design:
- should transforms for a given stylesheet be thread clean,
-> the precompilation now occur only at stylesheet processing
time (except the binding for named templates and extension
functions which need to be computed once at run-time).
Multiple threads should be able to reuse the same stylesheet
now.
Embedding Stylesheets:
- example in 2.7 would force to validate, we do it by default now
ID and Key support:
-> Done

View File

@@ -49,7 +49,7 @@ if test "${LOGNAME}" = "veillard" -a "`pwd`" = "/u/veillard/XSLT" ; then
fi
AC_ARG_WITH(debug, [ --with-debug Add the debugging code (on)])
if test "$with_mem_debug" = "no" ; then
if test "$with_debug" = "no" ; then
echo Disabling debug support
WITH_XSLT_DEBUG=0
else

View File

@@ -418,7 +418,10 @@ xsltApplyAttributeSet(xsltTransformContextPtr ctxt, xmlNodePtr node,
while (style != NULL) {
values = xmlHashLookup2(style->attributeSets, ncname, prefix);
while (values != NULL) {
xsltAttribute(ctxt, node, values->attr, NULL);
if (values->attr != NULL) {
xsltAttribute(ctxt, node, values->attr,
values->attr->_private);
}
values = values->next;
}
style = xsltNextImport(style);

View File

@@ -35,8 +35,6 @@ struct _xsltExtDef {
xmlChar *URI;
};
const xmlChar *xsltExtMarker = (const xmlChar *)"extension";
/************************************************************************
* *
* Type functions *

View File

@@ -32,7 +32,6 @@ int xsltRegisterExtElement (xsltTransformContextPtr ctxt,
void xsltFreeCtxtExts (xsltTransformContextPtr ctxt);
void xsltFreeExts (xsltStylesheetPtr style);
extern const xmlChar *xsltExtMarker;
#ifdef __cplusplus
}
#endif

View File

@@ -41,6 +41,7 @@
#define WITH_XSLT_DEBUG_PREPROC
#endif
const xmlChar *xsltExtMarker = (const xmlChar *) "Extension Element";
/************************************************************************
* *
@@ -50,7 +51,7 @@
/**
* xsltNewStylePreComp:
* @ctxt: an XSLT processing context
* @style: the XSLT stylesheet
* @type: the construct type
*
* Create a new XSLT Style precomputed block
@@ -58,7 +59,7 @@
* Returns the newly allocated xsltStylePreCompPtr or NULL in case of error
*/
static xsltStylePreCompPtr
xsltNewStylePreComp(xsltTransformContextPtr ctxt, xsltStyleType type) {
xsltNewStylePreComp(xsltStylesheetPtr style, xsltStyleType type) {
xsltStylePreCompPtr cur;
cur = (xsltStylePreCompPtr) xmlMalloc(sizeof(xsltStylePreComp));
@@ -105,13 +106,22 @@ xsltNewStylePreComp(xsltTransformContextPtr ctxt, xsltStyleType type) {
cur->func = xsltForEach;break;
case XSLT_FUNC_DOCUMENT:
cur->func = xsltDocumentElem;break;
case XSLT_FUNC_WITHPARAM:
cur->func = NULL;break;
case XSLT_FUNC_PARAM:
cur->func = NULL;break;
case XSLT_FUNC_VARIABLE:
cur->func = NULL;break;
case XSLT_FUNC_WHEN:
cur->func = NULL;break;
default:
if (cur->func == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltNewStylePreComp : no function for type %d\n", type);
}
}
if (cur->func == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltNewStylePreComp : no function for type %d\n", type);
}
cur->next = ctxt->preComps;
ctxt->preComps = cur;
cur->next = style->preComps;
style->preComps = cur;
return(cur);
}
@@ -165,8 +175,6 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
if (comp->nsList != NULL)
xmlFree(comp->nsList);
memset(comp, -1, sizeof(xsltStylePreComp));
xmlFree(comp);
}
@@ -179,19 +187,19 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
/**
* xsltDocumentComp:
* @ctxt: an XSLT processing context
* @style: the XSLT stylesheet
* @inst: the instruction in the stylesheet
*
* Pre process an XSLT-1.1 document element
*/
static void
xsltDocumentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltDocumentComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
xmlChar *filename = NULL;
xmlChar *base = NULL;
xmlChar *URL = NULL;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_DOCUMENT);
comp = xsltNewStylePreComp(style, XSLT_FUNC_DOCUMENT);
if (comp == NULL)
return;
inst->_private = comp;
@@ -203,7 +211,7 @@ xsltDocumentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltGenericDebug(xsltGenericDebugContext,
"Found saxon:output extension\n");
#endif
filename = xsltEvalStaticAttrValueTemplate(ctxt, inst,
filename = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"file",
XSLT_SAXON_NAMESPACE, &comp->has_filename);
} else if (xmlStrEqual(inst->name, (const xmlChar *) "write")) {
@@ -211,11 +219,11 @@ xsltDocumentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltGenericDebug(xsltGenericDebugContext,
"Found xalan:write extension\n");
#endif
filename = xsltEvalStaticAttrValueTemplate(ctxt, inst,
filename = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"select",
XSLT_XALAN_NAMESPACE, &comp->has_filename);
} else if (xmlStrEqual(inst->name, (const xmlChar *) "document")) {
filename = xsltEvalStaticAttrValueTemplate(ctxt, inst,
filename = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"href",
XSLT_XT_NAMESPACE, &comp->has_filename);
if (filename == NULL) {
@@ -223,7 +231,7 @@ xsltDocumentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltGenericDebug(xsltGenericDebugContext,
"Found xslt11:document construct\n");
#endif
filename = xsltEvalStaticAttrValueTemplate(ctxt, inst,
filename = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"href",
XSLT_NAMESPACE, &comp->has_filename);
comp->ver11 = 1;
@@ -273,25 +281,25 @@ error:
/**
* xsltSortComp:
* @ctxt: a XSLT process context
* @style: the XSLT stylesheet
* @inst: the xslt sort node
*
* Process the xslt sort node on the source node
*/
static void
xsltSortComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
if ((ctxt == NULL) || (inst == NULL))
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_SORT);
comp = xsltNewStylePreComp(style, XSLT_FUNC_SORT);
if (comp == NULL)
return;
inst->_private = comp;
comp->inst = inst;
comp->stype = xsltEvalStaticAttrValueTemplate(ctxt, inst,
comp->stype = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"data-type",
XSLT_NAMESPACE, &comp->has_stype);
if (comp->stype != NULL) {
@@ -305,7 +313,7 @@ xsltSortComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
comp->number = -1;
}
}
comp->order = xsltEvalStaticAttrValueTemplate(ctxt, inst,
comp->order = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"order",
XSLT_NAMESPACE, &comp->has_order);
if (comp->order != NULL) {
@@ -335,19 +343,19 @@ xsltSortComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltCopyComp:
* @ctxt: a XSLT process context
* @style: the XSLT stylesheet
* @inst: the xslt copy node
*
* Process the xslt copy node on the source node
*/
static void
xsltCopyComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltCopyComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
if ((ctxt == NULL) || (inst == NULL))
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_COPY);
comp = xsltNewStylePreComp(style, XSLT_FUNC_COPY);
if (comp == NULL)
return;
inst->_private = comp;
@@ -364,19 +372,19 @@ xsltCopyComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltTextComp:
* @ctxt: a XSLT process context
* @style: a XSLT process context
* @inst: the xslt text node
*
* Process the xslt text node on the source node
*/
static void
xsltTextComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltTextComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
xmlChar *prop;
if ((ctxt == NULL) || (inst == NULL))
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_TEXT);
comp = xsltNewStylePreComp(style, XSLT_FUNC_TEXT);
if (comp == NULL)
return;
inst->_private = comp;
@@ -400,18 +408,18 @@ xsltTextComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltElementComp:
* @ctxt: a XSLT process context
* @style: a XSLT process context
* @inst: the xslt element node
*
* Process the xslt element node on the source node
*/
static void
xsltElementComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
if ((ctxt == NULL) || (inst == NULL))
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_ELEMENT);
comp = xsltNewStylePreComp(style, XSLT_FUNC_ELEMENT);
if (comp == NULL)
return;
inst->_private = comp;
@@ -420,32 +428,32 @@ xsltElementComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/*
* TODO: more computation can be done there, especially namespace lookup
*/
comp->name = xsltEvalStaticAttrValueTemplate(ctxt, inst,
comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"name",
XSLT_NAMESPACE, &comp->has_name);
comp->ns = xsltEvalStaticAttrValueTemplate(ctxt, inst,
comp->ns = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"namespace",
XSLT_NAMESPACE, &comp->has_ns);
comp->use = xsltEvalStaticAttrValueTemplate(ctxt, inst,
comp->use = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"use-attribute-sets",
XSLT_NAMESPACE, &comp->has_use);
}
/**
* xsltAttributeComp:
* @ctxt: a XSLT process context
* @style: a XSLT process context
* @inst: the xslt attribute node
*
* Process the xslt attribute node on the source node
*/
static void
xsltAttributeComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltAttributeComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
if ((ctxt == NULL) || (inst == NULL))
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_ATTRIBUTE);
comp = xsltNewStylePreComp(style, XSLT_FUNC_ATTRIBUTE);
if (comp == NULL)
return;
inst->_private = comp;
@@ -454,10 +462,10 @@ xsltAttributeComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/*
* TODO: more computation can be done there, especially namespace lookup
*/
comp->name = xsltEvalStaticAttrValueTemplate(ctxt, inst,
comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"name",
XSLT_NAMESPACE, &comp->has_name);
comp->ns = xsltEvalStaticAttrValueTemplate(ctxt, inst,
comp->ns = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"namespace",
XSLT_NAMESPACE, &comp->has_ns);
@@ -465,18 +473,18 @@ xsltAttributeComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltCommentComp:
* @ctxt: a XSLT process context
* @style: a XSLT process context
* @inst: the xslt comment node
*
* Process the xslt comment node on the source node
*/
static void
xsltCommentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltCommentComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
if ((ctxt == NULL) || (inst == NULL))
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_COMMENT);
comp = xsltNewStylePreComp(style, XSLT_FUNC_COMMENT);
if (comp == NULL)
return;
inst->_private = comp;
@@ -485,42 +493,42 @@ xsltCommentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltProcessingInstructionComp:
* @ctxt: a XSLT process context
* @style: a XSLT process context
* @inst: the xslt processing-instruction node
*
* Process the xslt processing-instruction node on the source node
*/
static void
xsltProcessingInstructionComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltProcessingInstructionComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
if ((ctxt == NULL) || (inst == NULL))
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_PI);
comp = xsltNewStylePreComp(style, XSLT_FUNC_PI);
if (comp == NULL)
return;
inst->_private = comp;
comp->inst = inst;
comp->name = xsltEvalStaticAttrValueTemplate(ctxt, inst,
comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"name",
XSLT_NAMESPACE, &comp->has_name);
}
/**
* xsltCopyOfComp:
* @ctxt: a XSLT process context
* @style: a XSLT process context
* @inst: the xslt copy-of node
*
* Process the xslt copy-of node on the source node
*/
static void
xsltCopyOfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltCopyOfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
if ((ctxt == NULL) || (inst == NULL))
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_COPYOF);
comp = xsltNewStylePreComp(style, XSLT_FUNC_COPYOF);
if (comp == NULL)
return;
inst->_private = comp;
@@ -536,19 +544,19 @@ xsltCopyOfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltValueOfComp:
* @ctxt: a XSLT process context
* @style: a XSLT process context
* @inst: the xslt value-of node
*
* Process the xslt value-of node on the source node
*/
static void
xsltValueOfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltValueOfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
xmlChar *prop;
if ((ctxt == NULL) || (inst == NULL))
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_VALUEOF);
comp = xsltNewStylePreComp(style, XSLT_FUNC_VALUEOF);
if (comp == NULL)
return;
inst->_private = comp;
@@ -575,26 +583,97 @@ xsltValueOfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
}
}
/**
* xsltWithParamComp:
* @style: a XSLT process context
* @inst: the xslt with-param node
*
* Process the xslt with-param node on the source node
*/
static void
xsltWithParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
xmlChar *prop;
xmlChar *ncname = NULL;
xmlChar *prefix = NULL;
xmlNsPtr ns = NULL;
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(style, XSLT_FUNC_WITHPARAM);
if (comp == NULL)
return;
inst->_private = comp;
comp->inst = inst;
/*
* The full namespace resolution can be done statically
*/
prop = xmlGetNsProp(inst, (const xmlChar *)"name", XSLT_NAMESPACE);
if (prop == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xslt:with-param : name is missing\n");
} else {
ncname = xmlSplitQName2(prop, &prefix);
if (ncname == NULL) {
ncname = prop;
prop = NULL;
prefix = NULL;
}
if (prefix != NULL) {
ns = xmlSearchNs(inst->doc, inst, prefix);
if (ns == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xslt:with-param : no namespace bound to prefix %s\n", prefix);
}
}
comp->name = xmlStrdup(ncname);
comp->has_name = 1;
if (ns != NULL) {
comp->has_ns = 1;
comp->ns = xmlStrdup(ns->href);
} else
comp->has_ns = 0;
}
comp->select = xmlGetNsProp(inst, (const xmlChar *)"select",
XSLT_NAMESPACE);
if (comp->select != NULL) {
if (inst->children != NULL)
xsltGenericError(xsltGenericErrorContext,
"xsl:param : content should be empty since select is present \n");
}
comp->comp = NULL;
if (prop != NULL)
xmlFree(prop);
if (ncname != NULL)
xmlFree(ncname);
if (prefix != NULL)
xmlFree(prefix);
}
/**
* xsltNumberComp:
* @ctxt: a XSLT process context
* @style: a XSLT process context
* @cur: the xslt number node
*
* Process the xslt number node on the source node
*/
static void
xsltNumberComp(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
xsltNumberComp(xsltStylesheetPtr style, xmlNodePtr cur) {
xsltStylePreCompPtr comp;
xmlChar *prop;
if ((ctxt == NULL) || (cur == NULL))
if ((style == NULL) || (cur == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_NUMBER);
comp = xsltNewStylePreComp(style, XSLT_FUNC_NUMBER);
if (comp == NULL)
return;
cur->_private = comp;
if ((ctxt == NULL) || (cur == NULL))
if ((style == NULL) || (cur == NULL))
return;
comp->numdata.doc = cur->doc;
@@ -671,18 +750,18 @@ xsltNumberComp(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
/**
* xsltApplyImportsComp:
* @ctxt: a XSLT process context
* @style: a XSLT process context
* @inst: the xslt apply-imports node
*
* Process the xslt apply-imports node on the source node
*/
static void
xsltApplyImportsComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltApplyImportsComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
if ((ctxt == NULL) || (inst == NULL))
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_APPLYIMPORTS);
comp = xsltNewStylePreComp(style, XSLT_FUNC_APPLYIMPORTS);
if (comp == NULL)
return;
inst->_private = comp;
@@ -691,22 +770,22 @@ xsltApplyImportsComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltCallTemplateComp:
* @ctxt: a XSLT process context
* @style: a XSLT process context
* @inst: the xslt call-template node
*
* Process the xslt call-template node on the source node
*/
static void
xsltCallTemplateComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltCallTemplateComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
xmlChar *prop;
xmlChar *ncname = NULL;
xmlChar *prefix = NULL;
xmlNsPtr ns = NULL;
if ((ctxt == NULL) || (inst == NULL))
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_CALLTEMPLATE);
comp = xsltNewStylePreComp(style, XSLT_FUNC_CALLTEMPLATE);
if (comp == NULL)
return;
inst->_private = comp;
@@ -728,25 +807,22 @@ xsltCallTemplateComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
prefix = NULL;
}
if (prefix != NULL) {
ns = xmlSearchNs(ctxt->insert->doc, ctxt->insert, prefix);
ns = xmlSearchNs(inst->doc, inst, prefix);
if (ns == NULL) {
xsltGenericError(xsltGenericErrorContext,
"no namespace bound to prefix %s\n", prefix);
"xslt:call-template : no namespace bound to prefix %s\n", prefix);
}
}
if (ns != NULL)
comp->templ = xsltFindTemplate(ctxt, ncname, ns->href);
else
comp->templ = xsltFindTemplate(ctxt, ncname, NULL);
if (comp->templ == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xslt:call-template : template %s not found\n", ncname);
}
comp->name = xmlStrdup(ncname);
comp->has_name = 1;
if (ns != NULL) {
comp->ns = xmlStrdup(ns->href);
comp->has_ns = 1;
} else
comp->has_ns = 0;
comp->templ = NULL;
}
/* TODO: with-param could be optimized too */
if (prop != NULL)
xmlFree(prop);
if (ncname != NULL)
@@ -757,19 +833,19 @@ xsltCallTemplateComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltApplyTemplatesComp:
* @ctxt: a XSLT process context
* @style: a XSLT process context
* @inst: the apply-templates node
*
* Process the apply-templates node on the source node
*/
static void
xsltApplyTemplatesComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltApplyTemplatesComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
xmlChar *prop;
if ((ctxt == NULL) || (inst == NULL))
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_APPLYTEMPLATES);
comp = xsltNewStylePreComp(style, XSLT_FUNC_APPLYTEMPLATES);
if (comp == NULL)
return;
inst->_private = comp;
@@ -817,18 +893,18 @@ xsltApplyTemplatesComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltChooseComp:
* @ctxt: a XSLT process context
* @style: a XSLT process context
* @inst: the xslt choose node
*
* Process the xslt choose node on the source node
*/
static void
xsltChooseComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltChooseComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
if ((ctxt == NULL) || (inst == NULL))
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_CHOOSE);
comp = xsltNewStylePreComp(style, XSLT_FUNC_CHOOSE);
if (comp == NULL)
return;
inst->_private = comp;
@@ -837,18 +913,18 @@ xsltChooseComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltIfComp:
* @ctxt: a XSLT process context
* @style: a XSLT process context
* @inst: the xslt if node
*
* Process the xslt if node on the source node
*/
static void
xsltIfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltIfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
if ((ctxt == NULL) || (inst == NULL))
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_IF);
comp = xsltNewStylePreComp(style, XSLT_FUNC_IF);
if (comp == NULL)
return;
inst->_private = comp;
@@ -857,25 +933,52 @@ xsltIfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
comp->test = xmlGetNsProp(inst, (const xmlChar *)"test", XSLT_NAMESPACE);
if (comp->test == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltIf: test is not defined\n");
"xslt:if : test is not defined\n");
return;
}
}
/**
* xsltWhenComp:
* @style: a XSLT process context
* @inst: the xslt if node
*
* Process the xslt if node on the source node
*/
static void
xsltWhenComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(style, XSLT_FUNC_WHEN);
if (comp == NULL)
return;
inst->_private = comp;
comp->inst = inst;
comp->test = xmlGetNsProp(inst, (const xmlChar *)"test", XSLT_NAMESPACE);
if (comp->test == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:when : test is not defined\n");
return;
}
}
/**
* xsltForEachComp:
* @ctxt: a XSLT process context
* @style: a XSLT process context
* @inst: the xslt for-each node
*
* Process the xslt for-each node on the source node
*/
static void
xsltForEachComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltForEachComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
if ((ctxt == NULL) || (inst == NULL))
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_FOREACH);
comp = xsltNewStylePreComp(style, XSLT_FUNC_FOREACH);
if (comp == NULL)
return;
inst->_private = comp;
@@ -887,6 +990,144 @@ xsltForEachComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/* TODO: handle and skip the xsl:sort */
}
/**
* xsltVariableComp:
* @style: a XSLT process context
* @inst: the xslt variable node
*
* Process the xslt variable node on the source node
*/
static void
xsltVariableComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
xmlChar *prop;
xmlChar *ncname = NULL;
xmlChar *prefix = NULL;
xmlNsPtr ns = NULL;
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(style, XSLT_FUNC_VARIABLE);
if (comp == NULL)
return;
inst->_private = comp;
comp->inst = inst;
/*
* The full template resolution can be done statically
*/
prop = xmlGetNsProp(inst, (const xmlChar *)"name", XSLT_NAMESPACE);
if (prop == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xslt:variable : name is missing\n");
} else {
ncname = xmlSplitQName2(prop, &prefix);
if (ncname == NULL) {
ncname = prop;
prop = NULL;
prefix = NULL;
}
if (prefix != NULL) {
ns = xmlSearchNs(inst->doc, inst, prefix);
if (ns == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:variable no namespace bound to prefix %s\n", prefix);
}
}
comp->name = xmlStrdup(ncname);
comp->has_name = 1;
if (ns != NULL) {
comp->ns = xmlStrdup(ns->href);
comp->has_ns = 1;
} else
comp->has_ns = 0;
}
comp->select = xmlGetNsProp(inst, (const xmlChar *)"select",
XSLT_NAMESPACE);
if (comp->select != NULL) {
if (inst->children != NULL)
xsltGenericError(xsltGenericErrorContext,
"xsl:variable : content should be empty since select is present \n");
}
if (prop != NULL)
xmlFree(prop);
if (ncname != NULL)
xmlFree(ncname);
if (prefix != NULL)
xmlFree(prefix);
}
/**
* xsltParamComp:
* @style: a XSLT process context
* @inst: the xslt param node
*
* Process the xslt param node on the source node
*/
static void
xsltParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
xmlChar *prop;
xmlChar *ncname = NULL;
xmlChar *prefix = NULL;
xmlNsPtr ns = NULL;
if ((style == NULL) || (inst == NULL))
return;
comp = xsltNewStylePreComp(style, XSLT_FUNC_PARAM);
if (comp == NULL)
return;
inst->_private = comp;
comp->inst = inst;
/*
* The full template resolution can be done statically
*/
prop = xmlGetNsProp(inst, (const xmlChar *)"name", XSLT_NAMESPACE);
if (prop == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xslt:param : name is missing\n");
} else {
ncname = xmlSplitQName2(prop, &prefix);
if (ncname == NULL) {
ncname = prop;
prop = NULL;
prefix = NULL;
}
if (prefix != NULL) {
ns = xmlSearchNs(inst->doc, inst, prefix);
if (ns == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:param no namespace bound to prefix %s\n", prefix);
}
}
comp->name = xmlStrdup(ncname);
comp->has_name = 1;
if (ns != NULL) {
comp->ns = xmlStrdup(ns->href);
comp->has_ns = 1;
} else
comp->has_ns = 0;
}
comp->select = xmlGetNsProp(inst, (const xmlChar *)"select",
XSLT_NAMESPACE);
if (comp->select != NULL) {
if (inst->children != NULL)
xsltGenericError(xsltGenericErrorContext,
"xsl:variable : content should be empty since select is present \n");
}
if (prop != NULL)
xmlFree(prop);
if (ncname != NULL)
xmlFree(ncname);
if (prefix != NULL)
xmlFree(prefix);
}
/************************************************************************
* *
@@ -896,17 +1137,17 @@ xsltForEachComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltFreeStylePreComps:
* @ctxt: an XSLT transformation context
* @style: an XSLT transformation context
*
* Free up the memory allocated by all precomputed blocks
*/
void
xsltFreeStylePreComps(xsltTransformContextPtr ctxt) {
xsltFreeStylePreComps(xsltStylesheetPtr style) {
xsltStylePreCompPtr cur, next;
if (ctxt == NULL)
if (style == NULL)
return;
cur = ctxt->preComps;
cur = style->preComps;
while (cur != NULL) {
next = cur->next;
xsltFreeStylePreComp(cur);
@@ -916,61 +1157,99 @@ xsltFreeStylePreComps(xsltTransformContextPtr ctxt) {
/**
* xsltDocumentCompute:
* @ctxt: an XSLT processing context
* @style: the XSLT stylesheet
* @inst: the instruction in the stylesheet
*
* Precompute an XSLT stylesheet element
*/
void
xsltStylePreCompute(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr inst) {
if (inst->_private != NULL)
return;
if (IS_XSLT_ELEM(inst)) {
xsltStylePreCompPtr cur;
if (IS_XSLT_NAME(inst, "apply-templates")) {
xsltApplyTemplatesComp(ctxt, inst);
xsltApplyTemplatesComp(style, inst);
} else if (IS_XSLT_NAME(inst, "with-param")) {
xsltWithParamComp(style, inst);
} else if (IS_XSLT_NAME(inst, "value-of")) {
xsltValueOfComp(ctxt, inst);
xsltValueOfComp(style, inst);
} else if (IS_XSLT_NAME(inst, "copy")) {
xsltCopyComp(ctxt, inst);
xsltCopyComp(style, inst);
} else if (IS_XSLT_NAME(inst, "copy-of")) {
xsltCopyOfComp(ctxt, inst);
xsltCopyOfComp(style, inst);
} else if (IS_XSLT_NAME(inst, "if")) {
xsltIfComp(ctxt, inst);
xsltIfComp(style, inst);
} else if (IS_XSLT_NAME(inst, "when")) {
xsltWhenComp(style, inst);
} else if (IS_XSLT_NAME(inst, "choose")) {
xsltChooseComp(ctxt, inst);
xsltChooseComp(style, inst);
} else if (IS_XSLT_NAME(inst, "for-each")) {
xsltForEachComp(ctxt, inst);
xsltForEachComp(style, inst);
} else if (IS_XSLT_NAME(inst, "apply-imports")) {
xsltApplyImportsComp(ctxt, inst);
xsltApplyImportsComp(style, inst);
} else if (IS_XSLT_NAME(inst, "attribute")) {
xsltAttributeComp(ctxt, inst);
xsltAttributeComp(style, inst);
} else if (IS_XSLT_NAME(inst, "element")) {
xsltElementComp(ctxt, inst);
xsltElementComp(style, inst);
} else if (IS_XSLT_NAME(inst, "text")) {
xsltTextComp(ctxt, inst);
xsltTextComp(style, inst);
} else if (IS_XSLT_NAME(inst, "sort")) {
xsltSortComp(ctxt, inst);
xsltSortComp(style, inst);
} else if (IS_XSLT_NAME(inst, "comment")) {
xsltCommentComp(ctxt, inst);
xsltCommentComp(style, inst);
} else if (IS_XSLT_NAME(inst, "number")) {
xsltNumberComp(ctxt, inst);
xsltNumberComp(style, inst);
} else if (IS_XSLT_NAME(inst, "processing-instruction")) {
xsltProcessingInstructionComp(ctxt, inst);
xsltProcessingInstructionComp(style, inst);
} else if (IS_XSLT_NAME(inst, "call-template")) {
xsltCallTemplateComp(ctxt, inst);
xsltCallTemplateComp(style, inst);
} else if (IS_XSLT_NAME(inst, "param")) {
/* TODO: is there any use optimizing param too ? */
return;
xsltParamComp(style, inst);
} else if (IS_XSLT_NAME(inst, "variable")) {
/* TODO: is there any use optimizing variable too ? */
xsltVariableComp(style, inst);
} else if (IS_XSLT_NAME(inst, "otherwise")) {
/* no computation needed */
return;
} else if (IS_XSLT_NAME(inst, "template")) {
/* no computation needed */
return;
} else if (IS_XSLT_NAME(inst, "output")) {
/* no computation needed */
return;
} else if (IS_XSLT_NAME(inst, "preserve-space")) {
/* no computation needed */
return;
} else if (IS_XSLT_NAME(inst, "strip-space")) {
/* no computation needed */
return;
} else if (IS_XSLT_NAME(inst, "stylesheet")) {
/* no computation needed */
return;
} else if (IS_XSLT_NAME(inst, "key")) {
/* no computation needed */
return;
} else if (IS_XSLT_NAME(inst, "message")) {
/* no optimization needed */
/* no computation needed */
return;
} else if (IS_XSLT_NAME(inst, "attribute-set")) {
/* no computation needed */
return;
} else if (IS_XSLT_NAME(inst, "namespace-alias")) {
/* no computation needed */
return;
} else if (IS_XSLT_NAME(inst, "include")) {
/* no computation needed */
return;
} else if (IS_XSLT_NAME(inst, "import")) {
/* no computation needed */
return;
} else if (IS_XSLT_NAME(inst, "decimal-format")) {
/* no computation needed */
return;
} else if (IS_XSLT_NAME(inst, "document")) {
xsltDocumentComp(ctxt, inst);
xsltDocumentComp(style, inst);
} else {
xsltGenericError(xsltGenericDebugContext,
"xsltStylePreCompute: unknown xslt:%s\n", inst->name);
@@ -992,7 +1271,13 @@ xsltStylePreCompute(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
}
} else {
if (IS_XSLT_NAME(inst, "document")) {
xsltDocumentComp(ctxt, inst);
xsltDocumentComp(style, inst);
} else {
/*
* Mark the element for later recognition.
*/
if (inst->_private == NULL)
inst->_private = (void *) xsltExtMarker;
}
}
}

View File

@@ -19,9 +19,9 @@ extern "C" {
/*
* Interfaces
*/
void xsltStylePreCompute (xsltTransformContextPtr ctxt,
void xsltStylePreCompute (xsltStylesheetPtr style,
xmlNodePtr inst);
void xsltFreeStylePreComps (xsltTransformContextPtr ctxt);
void xsltFreeStylePreComps (xsltStylesheetPtr style);
#ifdef __cplusplus
}
#endif

View File

@@ -262,7 +262,7 @@ xsltEvalAttrValueTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
/**
* xsltEvalStaticAttrValueTemplate:
* @ctxt: the XSLT transformation context
* @style: the XSLT stylesheet
* @node: the stylesheet node
* @name: the attribute Name
* @name: the attribute namespace URI
@@ -275,12 +275,12 @@ xsltEvalAttrValueTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
* caller.
*/
xmlChar *
xsltEvalStaticAttrValueTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
xsltEvalStaticAttrValueTemplate(xsltStylesheetPtr style, xmlNodePtr node,
const xmlChar *name, const xmlChar *ns, int *found) {
const xmlChar *ret;
xmlChar *expr;
if ((ctxt == NULL) || (node == NULL) || (name == NULL))
if ((style == NULL) || (node == NULL) || (name == NULL))
return(NULL);
expr = xmlGetNsProp(node, name, ns);

View File

@@ -26,7 +26,7 @@ xmlChar * xsltEvalAttrValueTemplate (xsltTransformContextPtr ctxt,
xmlNodePtr node,
const xmlChar *name,
const xmlChar *ns);
xmlChar * xsltEvalStaticAttrValueTemplate (xsltTransformContextPtr ctxt,
xmlChar * xsltEvalStaticAttrValueTemplate (xsltStylesheetPtr style,
xmlNodePtr node,
const xmlChar *name,
const xmlChar *ns,

View File

@@ -214,7 +214,6 @@ xsltFreeTransformContext(xsltTransformContextPtr ctxt) {
xmlFree(ctxt->varsTab);
xsltFreeDocuments(ctxt);
xsltFreeCtxtExts(ctxt);
xsltFreeStylePreComps(ctxt);
memset(ctxt, -1, sizeof(xsltTransformContext));
xmlFree(ctxt);
}
@@ -876,20 +875,18 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
}
if (IS_XSLT_ELEM(cur)) {
if (cur->_private == NULL)
xsltStylePreCompute(ctxt, cur);
xsltStylePreCompPtr info = (xsltStylePreCompPtr) cur->_private;
if (info == NULL) {
xsltGenericError(xsltGenericDebugContext,
"xsltApplyOneTemplate: %s was not compiled\n",
cur->name);
goto skip_children;
}
if (cur->_private != NULL) {
xsltStylePreCompPtr info = (xsltStylePreCompPtr) cur->_private;
if (info->func != NULL) {
ctxt->insert = insert;
info->func(ctxt, node, cur, info);
ctxt->insert = oldInsert;
} else {
xsltGenericError(xsltGenericDebugContext,
"xsltApplyOneTemplate: %s has _private without function\n",
cur->name);
}
if (info->func != NULL) {
ctxt->insert = insert;
info->func(ctxt, node, cur, info);
ctxt->insert = oldInsert;
goto skip_children;
}
@@ -953,10 +950,6 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
"xsltApplyOneTemplate: extension construct %s\n", cur->name);
#endif
if (cur->_private == (void *) xsltExtMarker) {
cur->_private = NULL;
xsltStylePreCompute(ctxt, cur);
}
ctxt->insert = insert;
function(ctxt, node, cur, cur->_private);
ctxt->insert = oldInsert;
@@ -1195,8 +1188,9 @@ xsltSort(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr oldNode;
if (comp == NULL) {
xsltStylePreCompute(ctxt, inst);
comp = inst->_private;
xsltGenericError(xsltGenericErrorContext,
"xslt:sort : compilation had failed\n");
return;
}
if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
@@ -1560,8 +1554,9 @@ xsltAttribute(xsltTransformContextPtr ctxt, xmlNodePtr node,
if (ctxt->insert == NULL)
return;
if (comp == NULL) {
xsltStylePreCompute(ctxt, inst);
comp = inst->_private;
xsltGenericError(xsltGenericErrorContext,
"xslt:attribute : compilation had failed\n");
return;
}
if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
@@ -1916,8 +1911,9 @@ xsltNumber(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst, xsltStylePreCompPtr comp)
{
if (comp == NULL) {
xsltStylePreCompute(ctxt, inst);
comp = inst->_private;
xsltGenericError(xsltGenericErrorContext,
"xslt:number : compilation had failed\n");
return;
}
if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
@@ -1974,18 +1970,24 @@ xsltCallTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
xsltStackElemPtr params = NULL, param;
if (comp == NULL) {
xsltStylePreCompute(ctxt, inst);
comp = inst->_private;
}
if (ctxt->insert == NULL)
return;
if (comp == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xslt:call-template : compilation had failed\n");
return;
}
/*
* The template must have been precomputed
*/
if (comp->templ == NULL)
return;
if (comp->templ == NULL) {
comp->templ = xsltFindTemplate(ctxt, comp->name, comp->ns);
if (comp->templ == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xslt:call-template : template %s not found\n", comp->name);
}
}
/*
* Create a new frame but block access to variables
@@ -2039,8 +2041,9 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
if (comp == NULL) {
xsltStylePreCompute(ctxt, inst);
comp = inst->_private;
xsltGenericError(xsltGenericErrorContext,
"xslt:apply-templates : compilation had failed\n");
return;
}
if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
return;
@@ -2363,8 +2366,9 @@ xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr node,
int oldContextSize, oldProximityPosition;
if (comp == NULL) {
xsltStylePreCompute(ctxt, inst);
comp = inst->_private;
xsltGenericError(xsltGenericErrorContext,
"xslt:if : compilation had failed\n");
return;
}
if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
return;
@@ -2439,8 +2443,9 @@ xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr oldNode = ctxt->node;
if (comp == NULL) {
xsltStylePreCompute(ctxt, inst);
comp = inst->_private;
xsltGenericError(xsltGenericErrorContext,
"xslt:for-each : compilation had failed\n");
return;
}
if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
return;

View File

@@ -28,6 +28,7 @@
#include "variables.h"
#include "transform.h"
#include "imports.h"
#include "preproc.h"
#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_VARIABLE
@@ -245,8 +246,9 @@ xsltStackLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
* Returns 0 in case of success, -1 in case of error
*/
static int
xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr elem) {
int oldProximityPosition, oldContextSize;
xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr elem,
xsltStylePreCompPtr precomp) {
int oldProximityPosition, oldContextSize;
if ((ctxt == NULL) || (elem == NULL))
return(-1);
@@ -255,10 +257,18 @@ int oldProximityPosition, oldContextSize;
"Evaluating variable %s\n", elem->name);
#endif
if (elem->select != NULL) {
xmlXPathCompExprPtr comp;
xmlXPathCompExprPtr comp = NULL;
xmlXPathObjectPtr result;
comp = xmlXPathCompile(elem->select);
if (precomp != NULL) {
comp = precomp->comp;
if (comp == NULL) {
comp = xmlXPathCompile(elem->select);
precomp->comp = comp;
}
} else {
comp = xmlXPathCompile(elem->select);
}
if (comp == NULL)
return(-1);
oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
@@ -270,7 +280,8 @@ int oldProximityPosition, oldContextSize;
result = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
ctxt->xpathCtxt->contextSize = oldContextSize;
ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
xmlXPathFreeCompExpr(comp);
if (precomp == NULL)
xmlXPathFreeCompExpr(comp);
if (result == NULL) {
xsltGenericError(xsltGenericErrorContext,
"Evaluating variable %s failed\n", elem->name);
@@ -358,7 +369,7 @@ xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) {
while (elem != NULL) {
if (elem->computed == 0)
xsltEvalVariable(ctxt, elem);
xsltEvalVariable(ctxt, elem, NULL);
elem = elem->next;
}
@@ -498,21 +509,16 @@ xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) {
* Returns the xsltStackElemPtr or NULL in case of error
*/
static xsltStackElemPtr
xsltBuildVariable(xsltTransformContextPtr ctxt, const xmlChar *name,
const xmlChar *ns_uri, const xmlChar *select,
xmlNodePtr tree, int param) {
xsltBuildVariable(xsltTransformContextPtr ctxt, xsltStylePreCompPtr comp,
xmlNodePtr tree, int param) {
xsltStackElemPtr elem;
if (ctxt == NULL)
return(NULL);
if (name == NULL)
return(NULL);
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
"Building variable %s", name);
if (select != NULL)
"Building variable %s", comp->name);
if (comp->select != NULL)
xsltGenericDebug(xsltGenericDebugContext,
" select %s", select);
" select %s", comp->select);
xsltGenericDebug(xsltGenericDebugContext, "\n");
#endif
elem = xsltNewStackElem();
@@ -522,15 +528,15 @@ xsltBuildVariable(xsltTransformContextPtr ctxt, const xmlChar *name,
elem->type = XSLT_ELEM_PARAM;
else
elem->type = XSLT_ELEM_VARIABLE;
elem->name = xmlStrdup(name);
if (select != NULL)
elem->select = xmlStrdup(select);
elem->name = xmlStrdup(comp->name);
if (comp->select != NULL)
elem->select = xmlStrdup(comp->select);
else
elem->select = NULL;
if (ns_uri)
elem->nameURI = xmlStrdup(ns_uri);
if (comp->ns)
elem->nameURI = xmlStrdup(comp->ns);
elem->tree = tree;
xsltEvalVariable(ctxt, elem);
xsltEvalVariable(ctxt, elem, comp);
return(elem);
}
@@ -547,29 +553,24 @@ xsltBuildVariable(xsltTransformContextPtr ctxt, const xmlChar *name,
*
* Returns 0 in case of success, -1 in case of error
*/
int
xsltRegisterVariable(xsltTransformContextPtr ctxt, const xmlChar *name,
const xmlChar *ns_uri, const xmlChar *select,
static int
xsltRegisterVariable(xsltTransformContextPtr ctxt, xsltStylePreCompPtr comp,
xmlNodePtr tree, int param) {
xsltStackElemPtr elem;
if (ctxt == NULL)
return(-1);
if (name == NULL)
return(-1);
if (xsltCheckStackElem(ctxt, name, ns_uri) != 0) {
if (xsltCheckStackElem(ctxt, comp->name, comp->ns) != 0) {
if (!param) {
xsltGenericError(xsltGenericErrorContext,
"xsl:variable : redefining %s\n", name);
"xsl:variable : redefining %s\n", comp->name);
}
#ifdef WITH_XSLT_DEBUG_VARIABLE
else
xsltGenericDebug(xsltGenericDebugContext,
"param %s defined by caller", name);
"param %s defined by caller", comp->name);
#endif
return(0);
}
elem = xsltBuildVariable(ctxt, name, ns_uri, select, tree, param);
elem = xsltBuildVariable(ctxt, comp, tree, param);
xsltAddStackElem(ctxt, elem);
return(0);
}
@@ -621,7 +622,7 @@ xsltGlobalVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
xsltGenericDebug(xsltGenericDebugContext,
"uncomputed global variable %s\n", name);
#endif
xsltEvalVariable(ctxt, elem);
xsltEvalVariable(ctxt, elem, NULL);
}
if (elem->value != NULL)
return(xmlXPathObjectCopy(elem->value));
@@ -660,7 +661,7 @@ xsltVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
xsltGenericDebug(xsltGenericDebugContext,
"uncomputed variable %s\n", name);
#endif
xsltEvalVariable(ctxt, elem);
xsltEvalVariable(ctxt, elem, NULL);
}
if (elem->value != NULL)
return(xmlXPathObjectCopy(elem->value));
@@ -684,139 +685,45 @@ xsltVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
xsltStackElemPtr
xsltParseStylesheetCallerParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
xmlChar *name, *ncname, *prefix;
xmlChar *select;
xmlNodePtr tree = NULL;
xsltStackElemPtr elem = NULL;
xsltStylePreCompPtr comp;
if ((cur == NULL) || (ctxt == NULL))
return(NULL);
comp = (xsltStylePreCompPtr) cur->_private;
if (comp == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:param : compilation error\n");
return(NULL);
}
name = xmlGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE);
if (name == NULL) {
if (comp->name == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:param : missing name attribute\n");
return(NULL);
}
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
"Parsing param %s\n", name);
"Handling param %s\n", comp->name);
#endif
select = xmlGetNsProp(cur, (const xmlChar *)"select", XSLT_NAMESPACE);
if (select == NULL) {
if (comp->select == NULL) {
tree = cur->children;
} else {
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
" select %s\n", select);
" select %s\n", comp->select);
#endif
if (cur->children != NULL)
xsltGenericError(xsltGenericErrorContext,
"xsl:param : content shuld be empty since select is present \n");
tree = cur;
}
ncname = xmlSplitQName2(name, &prefix);
elem = xsltBuildVariable(ctxt, comp, tree, 1);
if (ncname != NULL) {
if (prefix != NULL) {
xmlNsPtr ns;
ns = xmlSearchNs(cur->doc, cur, prefix);
if (ns == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:param : no namespace bound to prefix %s\n", prefix);
} else {
elem = xsltBuildVariable(ctxt, ncname, ns->href, select,
tree, 1);
}
xmlFree(prefix);
} else {
elem = xsltBuildVariable(ctxt, ncname, NULL, select, tree, 1);
}
xmlFree(ncname);
} else {
elem = xsltBuildVariable(ctxt, name, NULL, select, tree, 1);
}
xmlFree(name);
if (select != NULL)
xmlFree(select);
return(elem);
}
/**
* xsltParseStylesheetParam:
* @ctxt: the XSLT transformation context
* @cur: the "param" element
*
* parse an XSLT transformation param declaration and record
* its value.
*/
void
xsltParseStylesheetParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
xmlChar *name, *ncname, *prefix;
xmlChar *select;
xmlNodePtr tree = NULL;
if ((cur == NULL) || (ctxt == NULL))
return;
name = xmlGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE);
if (name == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:param : missing name attribute\n");
return;
}
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
"Parsing param %s\n", name);
#endif
select = xmlGetNsProp(cur, (const xmlChar *)"select", XSLT_NAMESPACE);
if (select == NULL) {
tree = cur->children;
} else {
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
" select %s\n", select);
#endif
if (cur->children != NULL)
xsltGenericError(xsltGenericErrorContext,
"xsl:param : content shuld be empty since select is present \n");
}
ncname = xmlSplitQName2(name, &prefix);
if (ncname != NULL) {
if (prefix != NULL) {
xmlNsPtr ns;
ns = xmlSearchNs(cur->doc, cur, prefix);
if (ns == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:param : no namespace bound to prefix %s\n", prefix);
} else {
xsltRegisterVariable(ctxt, ncname, ns->href, select, tree, 1);
}
xmlFree(prefix);
} else {
xsltRegisterVariable(ctxt, ncname, NULL, select, tree, 1);
}
xmlFree(ncname);
} else {
xsltRegisterVariable(ctxt, name, NULL, select, tree, 1);
}
xmlFree(name);
if (select != NULL)
xmlFree(select);
}
/**
* xsltParseGlobalVariable:
* @style: the XSLT stylesheet
@@ -828,15 +735,20 @@ xsltParseStylesheetParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
void
xsltParseGlobalVariable(xsltStylesheetPtr style, xmlNodePtr cur) {
xmlChar *name, *ncname, *prefix;
xmlChar *select;
xmlNodePtr tree = NULL;
xsltStylePreCompPtr comp;
if ((cur == NULL) || (style == NULL))
return;
name = xmlGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE);
if (name == NULL) {
xsltStylePreCompute(style, cur);
comp = (xsltStylePreCompPtr) cur->_private;
if (comp == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:variable : compilation had failed\n");
return;
}
if (comp->name == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:variable : missing name attribute\n");
return;
@@ -844,46 +756,11 @@ xsltParseGlobalVariable(xsltStylesheetPtr style, xmlNodePtr cur) {
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
"Parsing global variable %s\n", name);
"Registering global variable %s\n", comp->name);
#endif
select = xmlGetNsProp(cur, (const xmlChar *)"select", XSLT_NAMESPACE);
if (select == NULL) {
tree = cur->children;
} else {
if (cur->children != NULL)
xsltGenericError(xsltGenericErrorContext,
"xsl:variable : content shuld be empty since select is present \n");
}
ncname = xmlSplitQName2(name, &prefix);
if (ncname != NULL) {
if (prefix != NULL) {
xmlNsPtr ns;
ns = xmlSearchNs(cur->doc, cur, prefix);
if (ns == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:variable : no namespace bound to prefix %s\n", prefix);
} else {
xsltRegisterGlobalVariable(style, ncname, ns->href, select,
tree, 0, NULL);
}
xmlFree(prefix);
} else {
xsltRegisterGlobalVariable(style, ncname, NULL, select, tree,
0, NULL);
}
xmlFree(ncname);
} else {
xsltRegisterGlobalVariable(style, name, NULL, select, tree, 0, NULL);
}
xmlFree(name);
if (select != NULL)
xmlFree(select);
xsltRegisterGlobalVariable(style, comp->name, comp->ns, comp->select,
cur->children, 0, NULL);
}
/**
@@ -897,15 +774,20 @@ xsltParseGlobalVariable(xsltStylesheetPtr style, xmlNodePtr cur) {
void
xsltParseGlobalParam(xsltStylesheetPtr style, xmlNodePtr cur) {
xmlChar *name, *ncname, *prefix;
xmlChar *select;
xmlNodePtr tree = NULL;
xsltStylePreCompPtr comp;
if ((cur == NULL) || (style == NULL))
return;
name = xmlGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE);
if (name == NULL) {
xsltStylePreCompute(style, cur);
comp = (xsltStylePreCompPtr) cur->_private;
if (comp == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:param : compilation had failed\n");
return;
}
if (comp->name == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:param : missing name attribute\n");
return;
@@ -913,45 +795,11 @@ xsltParseGlobalParam(xsltStylesheetPtr style, xmlNodePtr cur) {
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
"Parsing global param %s\n", name);
"Registering global param %s\n", comp->name);
#endif
select = xmlGetNsProp(cur, (const xmlChar *)"select", XSLT_NAMESPACE);
if (select == NULL) {
tree = cur->children;
} else {
if (cur->children != NULL)
xsltGenericError(xsltGenericErrorContext,
"xsl:param : content shuld be empty since select is present \n");
}
ncname = xmlSplitQName2(name, &prefix);
if (ncname != NULL) {
if (prefix != NULL) {
xmlNsPtr ns;
ns = xmlSearchNs(cur->doc, cur, prefix);
if (ns == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:param : no namespace bound to prefix %s\n", prefix);
} else {
xsltRegisterGlobalVariable(style, ncname, ns->href, select,
tree, 1, NULL);
}
xmlFree(prefix);
} else {
xsltRegisterGlobalVariable(style, ncname, NULL, select, tree,
1, NULL);
}
xmlFree(ncname);
} else {
xsltRegisterGlobalVariable(style, name, NULL, select, tree, 1, NULL);
}
xmlFree(name);
if (select != NULL)
xmlFree(select);
xsltRegisterGlobalVariable(style, comp->name, comp->ns, comp->select,
cur->children, 1, NULL);
}
/**
@@ -965,15 +813,19 @@ xsltParseGlobalParam(xsltStylesheetPtr style, xmlNodePtr cur) {
void
xsltParseStylesheetVariable(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
xmlChar *name, *ncname, *prefix;
xmlChar *select;
xmlNodePtr tree = NULL;
xsltStylePreCompPtr comp;
if ((cur == NULL) || (ctxt == NULL))
return;
name = xmlGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE);
if (name == NULL) {
comp = (xsltStylePreCompPtr) cur->_private;
if (comp == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:variable : compilation had failed\n");
return;
}
if (comp->name == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:variable : missing name attribute\n");
return;
@@ -981,44 +833,47 @@ xsltParseStylesheetVariable(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
"Parsing variable %s\n", name);
"Registering variable %s\n", comp->name);
#endif
select = xmlGetNsProp(cur, (const xmlChar *)"select", XSLT_NAMESPACE);
if (select == NULL) {
tree = cur->children;
} else {
if (cur->children != NULL)
xsltGenericError(xsltGenericErrorContext,
"xsl:variable : content should be empty since select is present \n");
xsltRegisterVariable(ctxt, comp, cur->children, 0);
}
/**
* xsltParseStylesheetParam:
* @ctxt: the XSLT transformation context
* @cur: the "param" element
*
* parse an XSLT transformation param declaration and record
* its value.
*/
void
xsltParseStylesheetParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
xsltStylePreCompPtr comp;
if ((cur == NULL) || (ctxt == NULL))
return;
comp = (xsltStylePreCompPtr) cur->_private;
if (comp == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:param : compilation had failed\n");
return;
}
ncname = xmlSplitQName2(name, &prefix);
if (ncname != NULL) {
if (prefix != NULL) {
xmlNsPtr ns;
ns = xmlSearchNs(cur->doc, cur, prefix);
if (ns == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:variable : no namespace bound to prefix %s\n", prefix);
} else {
xsltRegisterVariable(ctxt, ncname, ns->href, select, tree, 0);
}
xmlFree(prefix);
} else {
xsltRegisterVariable(ctxt, ncname, NULL, select, tree, 0);
}
xmlFree(ncname);
} else {
xsltRegisterVariable(ctxt, name, NULL, select, tree, 0);
if (comp->name == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:param : missing name attribute\n");
return;
}
xmlFree(name);
if (select != NULL)
xmlFree(select);
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
"Registering param %s\n", comp->name);
#endif
xsltRegisterVariable(ctxt, comp, cur->children, 1);
}
/**

View File

@@ -54,12 +54,6 @@ void xsltFreeVariableHashes (xsltTransformContextPtr ctxt);
xmlXPathObjectPtr xsltVariableLookup (xsltTransformContextPtr ctxt,
const xmlChar *name,
const xmlChar *ns_uri);
int xsltRegisterVariable (xsltTransformContextPtr ctxt,
const xmlChar *name,
const xmlChar *ns_uri,
const xmlChar *select,
xmlNodePtr tree,
int param);
xmlXPathObjectPtr xsltXPathVariableLookup (void *ctxt,
const xmlChar *name,
const xmlChar *ns_uri);

View File

@@ -32,6 +32,7 @@
#include "keys.h"
#include "documents.h"
#include "extensions.h"
#include "preproc.h"
#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_PARSING
@@ -293,6 +294,7 @@ xsltFreeStylesheet(xsltStylesheetPtr sheet) {
xsltFreeAttributeSetsHashes(sheet);
xsltFreeNamespaceAliasHashes(sheet);
xsltFreeStyleDocuments(sheet);
xsltFreeStylePreComps(sheet);
if (sheet->doc != NULL)
xmlFreeDoc(sheet->doc);
if (sheet->variables != NULL)
@@ -751,14 +753,16 @@ xsltParseStylesheetStripSpace(xsltStylesheetPtr style, xmlNodePtr cur) {
}
/**
* xsltParseRemoveBlanks:
* xsltPrecomputeStylesheet:
* @style: the XSLT stylesheet
*
* Clean-up the stylesheet content from unwanted ignorable blank nodes
* and run the preprocessing of all XSLT constructs.
*
* and process xslt:text
*/
static void
xsltParseRemoveBlanks(xsltStylesheetPtr style) {
xsltPrecomputeStylesheet(xsltStylesheetPtr style) {
xmlNodePtr cur, delete;
/*
@@ -775,13 +779,14 @@ xsltParseRemoveBlanks(xsltStylesheetPtr style) {
if (delete != NULL) {
#ifdef WITH_XSLT_DEBUG_BLANKS
xsltGenericDebug(xsltGenericDebugContext,
"xsltParseRemoveBlanks: removing ignorable blank node\n");
"xsltPrecomputeStylesheet: removing ignorable blank node\n");
#endif
xmlUnlinkNode(delete);
xmlFreeNode(delete);
delete = NULL;
}
if ((cur->type == XML_ELEMENT_NODE) && (IS_XSLT_ELEM(cur))) {
xsltStylePreCompute(style, cur);
if (IS_XSLT_NAME(cur, "text")) {
goto skip_children;
}
@@ -830,7 +835,7 @@ skip_children:
if (delete != NULL) {
#ifdef WITH_XSLT_DEBUG_PARSING
xsltGenericDebug(xsltGenericDebugContext,
"xsltParseRemoveBlanks: removing ignorable blank node\n");
"xsltPrecomputeStylesheet: removing ignorable blank node\n");
#endif
xmlUnlinkNode(delete);
xmlFreeNode(delete);
@@ -991,9 +996,9 @@ xsltParseTemplateContent(xsltStylesheetPtr style, xsltTemplatePtr ret,
} else if ((cur->ns != NULL) && (style->nsDefs != NULL)) {
if (xsltCheckExtPrefix(style, cur->ns->prefix)) {
/*
* Mark the element as being 'special'
* okay this is an extension element compile it too
*/
cur->_private = (void *) xsltExtMarker;
xsltStylePreCompute(style, cur);
}
}
@@ -1431,7 +1436,7 @@ xsltParseStylesheetProcess(xsltStylesheetPtr ret, xmlDocPtr doc) {
return(NULL);
}
xsltParseRemoveBlanks(ret);
xsltPrecomputeStylesheet(ret);
if ((IS_XSLT_ELEM(cur)) &&
((IS_XSLT_NAME(cur, "stylesheet")) ||
(IS_XSLT_NAME(cur, "transform")))) {

View File

@@ -39,7 +39,7 @@ struct _xsltStackElem {
xmlChar *name; /* the local part of the name QName */
xmlChar *nameURI; /* the URI part of the name QName */
xmlChar *select; /* the eval string */
xmlNodePtr tree; /* the tree if no eval string */
xmlNodePtr tree; /* the tree if no eval string or the location */
xmlXPathObjectPtr value; /* The value if computed */
};
@@ -97,6 +97,92 @@ struct _xsltDocument {
void *keys; /* key tables storage */
};
/*
* The in-memory structure corresponding to XSLT stylesheet constructs
* precomputed data.
*/
typedef struct _xsltTransformContext xsltTransformContext;
typedef xsltTransformContext *xsltTransformContextPtr;
typedef struct _xsltStylePreComp xsltStylePreComp;
typedef xsltStylePreComp *xsltStylePreCompPtr;
typedef void (*xsltTransformFunction) (xsltTransformContextPtr ctxt,
xmlNodePtr node, xmlNodePtr inst,
xsltStylePreCompPtr comp);
typedef enum {
XSLT_FUNC_COPY=1,
XSLT_FUNC_SORT,
XSLT_FUNC_TEXT,
XSLT_FUNC_ELEMENT,
XSLT_FUNC_ATTRIBUTE,
XSLT_FUNC_COMMENT,
XSLT_FUNC_PI,
XSLT_FUNC_COPYOF,
XSLT_FUNC_VALUEOF,
XSLT_FUNC_NUMBER,
XSLT_FUNC_APPLYIMPORTS,
XSLT_FUNC_CALLTEMPLATE,
XSLT_FUNC_APPLYTEMPLATES,
XSLT_FUNC_CHOOSE,
XSLT_FUNC_IF,
XSLT_FUNC_FOREACH,
XSLT_FUNC_DOCUMENT,
XSLT_FUNC_WITHPARAM,
XSLT_FUNC_PARAM,
XSLT_FUNC_VARIABLE,
XSLT_FUNC_WHEN
} xsltStyleType;
struct _xsltStylePreComp {
struct _xsltStylePreComp *next;/* chained list */
xsltStyleType type; /* type of the element */
xsltTransformFunction func; /* handling function */
xmlNodePtr inst; /* the instruction */
/*
* Pre computed values
*/
xmlChar *stype; /* sort */
int has_stype; /* sort */
int number; /* sort */
xmlChar *order; /* sort */
int has_order; /* sort */
int descending; /* sort */
xmlChar *use; /* copy, element */
int has_use; /* copy, element */
int noescape; /* text */
xmlChar *name; /* element, attribute, pi */
int has_name; /* element, attribute, pi */
xmlChar *ns; /* element */
int has_ns; /* element */
xmlChar *mode; /* apply-templates */
xmlChar *modeURI; /* apply-templates */
xmlChar *test; /* if */
xsltTemplatePtr templ; /* call-template */
xmlChar *select; /* sort, copy-of, value-of, apply-templates */
int ver11; /* document */
xmlChar *filename; /* document URL */
int has_filename; /* document */
xsltNumberData numdata; /* number */
xmlXPathCompExprPtr comp; /* a precompiled XPath expression */
xmlNsPtr *nsList; /* the namespaces in scope */
int nsNr; /* the number of namespaces in scope */
};
/*
* The in-memory structure corresponding to an XSLT Stylesheet
* NOTE: most of the content is simply linked from the doc tree
@@ -179,89 +265,11 @@ struct _xsltStylesheet {
xmlChar *doctypeSystem; /* doctype-system string */
int indent; /* should output being indented */
xmlChar *mediaType; /* media-type string */
};
/*
* The in-memory structure corresponding to XSLT stylesheet constructs
* precomputed data.
*/
typedef struct _xsltTransformContext xsltTransformContext;
typedef xsltTransformContext *xsltTransformContextPtr;
typedef struct _xsltStylePreComp xsltStylePreComp;
typedef xsltStylePreComp *xsltStylePreCompPtr;
typedef void (*xsltTransformFunction) (xsltTransformContextPtr ctxt,
xmlNodePtr node, xmlNodePtr inst,
xsltStylePreCompPtr comp);
typedef enum {
XSLT_FUNC_COPY=1,
XSLT_FUNC_SORT,
XSLT_FUNC_TEXT,
XSLT_FUNC_ELEMENT,
XSLT_FUNC_ATTRIBUTE,
XSLT_FUNC_COMMENT,
XSLT_FUNC_PI,
XSLT_FUNC_COPYOF,
XSLT_FUNC_VALUEOF,
XSLT_FUNC_NUMBER,
XSLT_FUNC_APPLYIMPORTS,
XSLT_FUNC_CALLTEMPLATE,
XSLT_FUNC_APPLYTEMPLATES,
XSLT_FUNC_CHOOSE,
XSLT_FUNC_IF,
XSLT_FUNC_FOREACH,
XSLT_FUNC_DOCUMENT
} xsltStyleType;
struct _xsltStylePreComp {
struct _xsltStylePreComp *next;/* chained list */
xsltStyleType type; /* type of the element */
xsltTransformFunction func; /* handling function */
xmlNodePtr inst; /* the instruction */
/*
* Pre computed values
* Precomputed blocks
*/
xmlChar *stype; /* sort */
int has_stype; /* sort */
int number; /* sort */
xmlChar *order; /* sort */
int has_order; /* sort */
int descending; /* sort */
xmlChar *use; /* copy, element */
int has_use; /* copy, element */
int noescape; /* text */
xmlChar *name; /* element, attribute, pi */
int has_name; /* element, attribute, pi */
xmlChar *ns; /* element */
int has_ns; /* element */
xmlChar *mode; /* apply-templates */
xmlChar *modeURI; /* apply-templates */
xmlChar *test; /* if */
xsltTemplatePtr templ; /* call-template */
xmlChar *select; /* sort, copy-of, value-of, apply-templates */
int ver11; /* document */
xmlChar *filename; /* document URL */
int has_filename; /* document */
xsltNumberData numdata; /* number */
xmlXPathCompExprPtr comp; /* a precompiled XPath expression */
xmlNsPtr *nsList; /* the namespaces in scope */
int nsNr; /* the number of namespaces in scope */
xsltStylePreCompPtr preComps; /* list of precomputed blocks */
};
/*
@@ -293,11 +301,6 @@ struct _xsltTransformContext {
int varsMax; /* Size of the variable list stack */
xsltStackElemPtr *varsTab; /* the variable list stack */
/*
* Precomputed blocks
*/
xsltStylePreCompPtr preComps; /* list of precomputed blocks */
/*
* Extensions
*/