From 3c0af1e8d7c6249b202dea7d0f0cb2ba3c487ea4 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Tue, 6 Mar 2001 18:06:04 +0000 Subject: [PATCH] Step in improving performances: - libxslt/preproc.[ch] Makefile.am templates.[ch] transform.[ch] xsltInternals.h: started working on optimizing stylesheet element parsing. Just builds the extra informations so far. - xsltutils.h: added a missing XPath decl Daniel --- ChangeLog | 7 + libxslt/Makefile.am | 2 + libxslt/attributes.c | 89 ----- libxslt/numbersInternals.h | 5 - libxslt/preproc.c | 931 +++++++++++++++++++++++++++++++++++++++++++++ libxslt/preproc.h | 30 ++ libxslt/templates.c | 37 ++ libxslt/templates.h | 4 + libxslt/transform.c | 127 ++++++- libxslt/transform.h | 48 +++ libxslt/xsltInternals.h | 90 ++++- libxslt/xsltutils.h | 6 +- 12 files changed, 1271 insertions(+), 105 deletions(-) create mode 100644 libxslt/preproc.c create mode 100644 libxslt/preproc.h diff --git a/ChangeLog b/ChangeLog index d12b5bb..79e10e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Tue Mar 6 19:03:21 CET 2001 Daniel Veillard + + * libxslt/preproc.[ch] Makefile.am templates.[ch] transform.[ch] + xsltInternals.h: started working on optimizing stylesheet + element parsing. Just builds the extra informations so far. + * xsltutils.h: added a missing XPath decl + Tue Mar 6 09:52:13 CET 2001 Daniel Veillard * libxslt/variables.c: William M. Brack found a serious bug diff --git a/libxslt/Makefile.am b/libxslt/Makefile.am index 43f2539..750c8de 100644 --- a/libxslt/Makefile.am +++ b/libxslt/Makefile.am @@ -20,6 +20,7 @@ xsltinc_HEADERS = \ imports.h \ attributes.h \ documents.h \ + preproc.h \ transform.h \ xsltInternals.h @@ -38,6 +39,7 @@ libxslt_la_SOURCES = \ imports.c \ attributes.c \ documents.c \ + preproc.c \ transform.c diff --git a/libxslt/attributes.c b/libxslt/attributes.c index 5be2ca8..ac52ef2 100644 --- a/libxslt/attributes.c +++ b/libxslt/attributes.c @@ -369,95 +369,6 @@ error: } /** - * xsltAttribute: - * @ctxt: a XSLT process context - * @node: the node in the source tree. - * @inst: the xslt attribute node - * - * Process the xslt attribute node on the source node - */ -void -xsltAttribute(xsltTransformContextPtr ctxt, xmlNodePtr node, - xmlNodePtr inst) { - xmlChar *prop = NULL; - xmlChar *ncname = NULL; - xmlChar *prefix = NULL; - xmlChar *value = NULL; - xmlNsPtr ns = NULL; - xmlAttrPtr attr; - - - if (ctxt->insert == NULL) - return; - if (ctxt->insert->children != NULL) { - xsltGenericError(xsltGenericErrorContext, - "xslt:attribute : node has already children\n"); - return; - } - prop = xsltEvalAttrValueTemplate(ctxt, inst, (const xmlChar *)"name"); - if (prop == NULL) { - xsltGenericError(xsltGenericErrorContext, - "xslt:attribute : name is missing\n"); - goto error; - } - - ncname = xmlSplitQName2(prop, &prefix); - if (ncname == NULL) { - ncname = prop; - prop = NULL; - prefix = NULL; - } - - if ((prefix != NULL) && (xmlStrEqual(prefix, (const xmlChar *)"xmlns"))) { -#ifdef DEBUG_ATTRIBUTES - xsltGenericDebug(xsltGenericDebugContext, - "xslt:attribute : xmlns prefix forbidden\n"); -#endif - goto error; - } - prop = xsltEvalAttrValueTemplate(ctxt, inst, (const xmlChar *)"namespace"); - if (prop != NULL) { - ns = xsltGetSpecialNamespace(ctxt, inst, prop, prefix, ctxt->insert); - } else { - if (prefix != NULL) { - ns = xmlSearchNs(inst->doc, inst, prefix); - if (ns == NULL) { - xsltGenericError(xsltGenericErrorContext, - "no namespace bound to prefix %s\n", prefix); - } else { - ns = xsltGetNamespace(ctxt, inst, ns, ctxt->insert); - } - } - } - - - value = xsltEvalTemplateString(ctxt, node, inst); - if (value == NULL) { - if (ns) { - attr = xmlSetNsProp(ctxt->insert, ns, ncname, - (const xmlChar *)""); - } else - attr = xmlSetProp(ctxt->insert, ncname, (const xmlChar *)""); - } else { - if (ns) { - attr = xmlSetNsProp(ctxt->insert, ns, ncname, value); - } else - attr = xmlSetProp(ctxt->insert, ncname, value); - - } - -error: - if (prop != NULL) - xmlFree(prop); - if (ncname != NULL) - xmlFree(ncname); - if (prefix != NULL) - xmlFree(prefix); - if (value != NULL) - xmlFree(value); -} - -/** * xsltApplyAttributeSet: * @ctxt: the XSLT stylesheet * @node: the node in the source tree. diff --git a/libxslt/numbersInternals.h b/libxslt/numbersInternals.h index a20dec1..02794f4 100644 --- a/libxslt/numbersInternals.h +++ b/libxslt/numbersInternals.h @@ -11,7 +11,6 @@ #define __XML_XSLT_NUMBERSINTERNALS_H__ #include -#include "xsltInternals.h" #ifdef __cplusplus extern "C" { @@ -32,10 +31,6 @@ typedef struct _xsltNumberData { xmlNodePtr node; } xsltNumberData, *xsltNumberDataPtr; -xmlXPathError xsltFormatNumberConversion(xsltDecimalFormatPtr, xmlChar *, - double, xmlChar **); -void xsltNumberFormat(xsltTransformContextPtr, xsltNumberDataPtr, xmlNodePtr); - #ifdef __cplusplus } #endif diff --git a/libxslt/preproc.c b/libxslt/preproc.c new file mode 100644 index 0000000..c63906f --- /dev/null +++ b/libxslt/preproc.c @@ -0,0 +1,931 @@ +/* + * preproc.c: Preprocessing of style operations + * + * References: + * http://www.w3.org/TR/1999/REC-xslt-19991116 + * + * Michael Kay "XSLT Programmer's Reference" pp 637-643 + * Writing Multiple Output Files + * + * XSLT-1.1 Working Draft + * http://www.w3.org/TR/xslt11#multiple-output + * + * See Copyright for the status of this software. + * + * Daniel.Veillard@imag.fr + */ + +#include "xsltconfig.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include "xslt.h" +#include "xsltutils.h" +#include "xsltInternals.h" +#include "transform.h" +#include "templates.h" +#include "variables.h" +#include "numbersInternals.h" +#include "preproc.h" +#include "extra.h" +#include "imports.h" + +#define DEBUG_PREPROC + + +/************************************************************************ + * * + * handling of precomputed data * + * * + ************************************************************************/ + +/** + * xsltNewStylePreComp: + * @ctxt: an XSLT processing context + * @type: the construct type + * + * Create a new XSLT Style precomputed block + * + * Returns the newly allocated xsltStylePreCompPtr or NULL in case of error + */ +xsltStylePreCompPtr +xsltNewStylePreComp(xsltTransformContextPtr ctxt, xsltStyleType type) { + xsltStylePreCompPtr cur; + + cur = (xsltStylePreCompPtr) xmlMalloc(sizeof(xsltStylePreComp)); + if (cur == NULL) { + xsltGenericError(xsltGenericErrorContext, + "xsltNewStylePreComp : malloc failed\n"); + return(NULL); + } + memset(cur, 0, sizeof(xsltStylePreComp)); + + cur->type = type; + switch (cur->type) { + case XSLT_FUNC_COPY: + cur->func = xsltCopy;break; + case XSLT_FUNC_SORT: + cur->func = xsltSort;break; + case XSLT_FUNC_TEXT: + cur->func = xsltText;break; + case XSLT_FUNC_ELEMENT: + cur->func = xsltElement;break; + case XSLT_FUNC_ATTRIBUTE: + cur->func = xsltAttribute;break; + case XSLT_FUNC_COMMENT: + cur->func = xsltComment;break; + case XSLT_FUNC_PI: + cur->func = xsltProcessingInstruction;break; + case XSLT_FUNC_COPYOF: + cur->func = xsltCopyOf;break; + case XSLT_FUNC_VALUEOF: + cur->func = xsltValueOf;break; + case XSLT_FUNC_NUMBER: + cur->func = xsltNumber;break; + case XSLT_FUNC_APPLYIMPORTS: + cur->func = xsltApplyImports;break; + case XSLT_FUNC_CALLTEMPLATE: + cur->func = xsltCallTemplate;break; + case XSLT_FUNC_APPLYTEMPLATES: + cur->func = xsltApplyTemplates;break; + case XSLT_FUNC_CHOOSE: + cur->func = xsltChoose;break; + case XSLT_FUNC_IF: + cur->func = xsltIf;break; + case XSLT_FUNC_FOREACH: + cur->func = xsltForEach;break; + case XSLT_FUNC_DOCUMENT: + cur->func = xsltDocumentElem;break; + } + if (cur->func == NULL) { + xsltGenericError(xsltGenericErrorContext, + "xsltNewStylePreComp : no function for type %d\n", type); + } + cur->next = ctxt->preComps; + ctxt->preComps = cur; + + return(cur); +} + +/** + * xsltFreeStylePreComp: + * @comp: an XSLT Style precomputed block + * + * Free up the memory allocated by @comp + */ +void +xsltFreeStylePreComp(xsltStylePreCompPtr comp) { + if (comp == NULL) + return; + if (comp->stype != NULL) + xmlFree(comp->stype); + if (comp->order != NULL) + xmlFree(comp->order); + if (comp->use != NULL) + xmlFree(comp->use); + if (comp->name != NULL) + xmlFree(comp->name); + if (comp->ns != NULL) + xmlFree(comp->ns); + if (comp->mode != NULL) + xmlFree(comp->mode); + if (comp->modeURI != NULL) + xmlFree(comp->modeURI); + if (comp->test != NULL) + xmlFree(comp->test); + if (comp->select != NULL) + xmlFree(comp->select); + + if (comp->filename != NULL) + xmlFree(comp->filename); + + if (comp->numdata.level != NULL) + xmlFree(comp->numdata.level); + if (comp->numdata.count != NULL) + xmlFree(comp->numdata.count); + if (comp->numdata.from != NULL) + xmlFree(comp->numdata.from); + if (comp->numdata.value != NULL) + xmlFree(comp->numdata.value); + if (comp->numdata.format != NULL) + xmlFree(comp->numdata.format); + + memset(comp, -1, sizeof(xsltStylePreComp)); + + xmlFree(comp); +} + + +/************************************************************************ + * * + * XSLT-1.1 extensions * + * * + ************************************************************************/ + +/** + * xsltDocumentComp: + * @ctxt: an XSLT processing context + * @inst: the instruction in the stylesheet + * + * Pre process an XSLT-1.1 document element + */ +void +xsltDocumentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + xmlChar *filename = NULL; + xmlChar *base = NULL; + xmlChar *URL = NULL; + + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_DOCUMENT); + if (comp == NULL) + return; + inst->_private = comp; + comp->ver11 = 0; + + if (xmlStrEqual(inst->name, (const xmlChar *) "output")) { +#ifdef DEBUG_EXTRA + xsltGenericDebug(xsltGenericDebugContext, + "Found saxon:output extension\n"); +#endif + filename = xmlGetNsProp(inst, (const xmlChar *)"file", + XSLT_SAXON_NAMESPACE); + } else if (xmlStrEqual(inst->name, (const xmlChar *) "write")) { +#ifdef DEBUG_EXTRA + xsltGenericDebug(xsltGenericDebugContext, + "Found xalan:write extension\n"); +#endif + filename = xmlGetNsProp(inst, (const xmlChar *)"select", + XSLT_XALAN_NAMESPACE); + } else if (xmlStrEqual(inst->name, (const xmlChar *) "document")) { + filename = xmlGetNsProp(inst, (const xmlChar *)"href", + XSLT_XT_NAMESPACE); + if (filename == NULL) { +#ifdef DEBUG_EXTRA + xsltGenericDebug(xsltGenericDebugContext, + "Found xslt11:document construct\n"); +#endif + filename = xmlGetNsProp(inst, (const xmlChar *)"href", + XSLT_NAMESPACE); + comp->ver11 = 1; + } else { +#ifdef DEBUG_EXTRA + xsltGenericDebug(xsltGenericDebugContext, + "Found xt:document extension\n"); +#endif + comp->ver11 = 0; + } + } + if (filename == NULL) { + xsltGenericError(xsltGenericErrorContext, + "xsltDocumentComp: could not find the href\n"); + goto error; + } + + /* + * Compute output URL + */ + base = xmlNodeGetBase(inst->doc, inst); + URL = xmlBuildURI(base, filename); + if (URL == NULL) { + xsltGenericError(xsltGenericErrorContext, + "xsltDocumentElem: URL computation failed %s\n", filename); + comp->filename = xmlStrdup(filename); + } else { + comp->filename = URL; + } + +error: + if (base != NULL) + xmlFree(base); + if (filename != NULL) + xmlFree(filename); +} + +/************************************************************************ + * * + * Most of the XSLT-1.0 transformations * + * * + ************************************************************************/ + +/** + * xsltSortComp: + * @ctxt: a XSLT process context + * @inst: the xslt sort node + * + * Process the xslt sort node on the source node + */ +void +xsltSortComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + + + if ((ctxt == NULL) || (inst == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_SORT); + if (comp == NULL) + return; + inst->_private = comp; + + comp->stype = xsltEvalStaticAttrValueTemplate(ctxt, inst, + (const xmlChar *)"data-type", &comp->has_stype); + if (comp->stype != NULL) { + if (xmlStrEqual(comp->stype, (const xmlChar *) "text")) + comp->number = 0; + else if (xmlStrEqual(comp->stype, (const xmlChar *) "number")) + comp->number = 1; + else { + xsltGenericError(xsltGenericErrorContext, + "xsltSortComp: no support for data-type = %s\n", comp->stype); + comp->number = -1; + } + } + comp->order = xsltEvalStaticAttrValueTemplate(ctxt, inst, + (const xmlChar *)"order", &comp->has_order); + if (comp->order != NULL) { + if (xmlStrEqual(comp->order, (const xmlChar *) "ascending")) + comp->descending = 0; + else if (xmlStrEqual(comp->order, (const xmlChar *) "descending")) + comp->descending = 1; + else { + xsltGenericError(xsltGenericErrorContext, + "xsltSortComp: invalid value %s for order\n", comp->order); + comp->descending = -1; + } + } + /* TODO: xsl:sort lang attribute */ + /* TODO: xsl:sort case-order attribute */ + + comp->select = xmlGetNsProp(inst,(const xmlChar *)"select", XSLT_NAMESPACE); + if (comp->select == NULL) { + comp->select = xmlNodeGetContent(inst); + if (comp->select == NULL) { + xsltGenericError(xsltGenericErrorContext, + "xsltSortComp: select is not defined\n"); + } + } +} + +/** + * xsltCopyComp: + * @ctxt: a XSLT process context + * @inst: the xslt copy node + * + * Process the xslt copy node on the source node + */ +void +xsltCopyComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + + + if ((ctxt == NULL) || (inst == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_COPY); + if (comp == NULL) + return; + inst->_private = comp; + + + comp->use = xmlGetNsProp(inst, (const xmlChar *)"use-attribute-sets", + XSLT_NAMESPACE); + if (comp->use == NULL) + comp->has_use = 0; + else + comp->has_use = 1; +} + +/** + * xsltTextComp: + * @ctxt: a XSLT process context + * @inst: the xslt text node + * + * Process the xslt text node on the source node + */ +void +xsltTextComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + xmlChar *prop; + + if ((ctxt == NULL) || (inst == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_TEXT); + if (comp == NULL) + return; + inst->_private = comp; + comp->noescape = 0; + + prop = xmlGetNsProp(inst, + (const xmlChar *)"disable-output-escaping", + XSLT_NAMESPACE); + if (prop != NULL) { + if (xmlStrEqual(prop, (const xmlChar *)"yes")) { + comp->noescape = 1; + } else if (!xmlStrEqual(prop, + (const xmlChar *)"no")){ + xsltGenericError(xsltGenericErrorContext, +"xslt:text: disable-output-escaping allow only yes or no\n"); + } + xmlFree(prop); + } +} + +/** + * xsltElementComp: + * @ctxt: a XSLT process context + * @inst: the xslt element node + * + * Process the xslt element node on the source node + */ +void +xsltElementComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + + if ((ctxt == NULL) || (inst == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_ELEMENT); + if (comp == NULL) + return; + inst->_private = comp; + + /* + * TODO: more computation can be done there, especially namespace lookup + */ + comp->name = xsltEvalStaticAttrValueTemplate(ctxt, inst, + (const xmlChar *)"name", &comp->has_name); + comp->ns = xsltEvalStaticAttrValueTemplate(ctxt, inst, + (const xmlChar *)"namespace", &comp->has_ns); + + comp->use = xsltEvalStaticAttrValueTemplate(ctxt, inst, + (const xmlChar *)"use-attribute-sets", &comp->has_use); +} + +/** + * xsltAttributeComp: + * @ctxt: a XSLT process context + * @inst: the xslt attribute node + * + * Process the xslt attribute node on the source node + */ +void +xsltAttributeComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + + if ((ctxt == NULL) || (inst == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_ATTRIBUTE); + if (comp == NULL) + return; + inst->_private = comp; + + /* + * TODO: more computation can be done there, especially namespace lookup + */ + comp->name = xsltEvalStaticAttrValueTemplate(ctxt, inst, + (const xmlChar *)"name", &comp->has_name); + comp->ns = xsltEvalStaticAttrValueTemplate(ctxt, inst, + (const xmlChar *)"namespace", &comp->has_ns); + +} + +/** + * xsltCommentComp: + * @ctxt: a XSLT process context + * @inst: the xslt comment node + * + * Process the xslt comment node on the source node + */ +void +xsltCommentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + + if ((ctxt == NULL) || (inst == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_COMMENT); + if (comp == NULL) + return; + inst->_private = comp; +} + +/** + * xsltProcessingInstructionComp: + * @ctxt: a XSLT process context + * @inst: the xslt processing-instruction node + * + * Process the xslt processing-instruction node on the source node + */ +void +xsltProcessingInstructionComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + + if ((ctxt == NULL) || (inst == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_PI); + if (comp == NULL) + return; + inst->_private = comp; + + comp->name = xsltEvalStaticAttrValueTemplate(ctxt, inst, + (const xmlChar *)"name", &comp->has_name); +} + +/** + * xsltCopyOfComp: + * @ctxt: a XSLT process context + * @inst: the xslt copy-of node + * + * Process the xslt copy-of node on the source node + */ +void +xsltCopyOfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + + if ((ctxt == NULL) || (inst == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_COPYOF); + if (comp == NULL) + return; + inst->_private = comp; + + comp->select = xmlGetNsProp(inst, (const xmlChar *)"select", + XSLT_NAMESPACE); + if (comp->select == NULL) { + xsltGenericError(xsltGenericErrorContext, + "xslt:copy-of : select is missing\n"); + } +} + +/** + * xsltValueOfComp: + * @ctxt: a XSLT process context + * @inst: the xslt value-of node + * + * Process the xslt value-of node on the source node + */ +void +xsltValueOfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + xmlChar *prop; + + if ((ctxt == NULL) || (inst == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_VALUEOF); + if (comp == NULL) + return; + inst->_private = comp; + + prop = xmlGetNsProp(inst, + (const xmlChar *)"disable-output-escaping", + XSLT_NAMESPACE); + if (prop != NULL) { + if (xmlStrEqual(prop, (const xmlChar *)"yes")) { + comp->noescape = 1; + } else if (!xmlStrEqual(prop, + (const xmlChar *)"no")){ + xsltGenericError(xsltGenericErrorContext, +"value-of: disable-output-escaping allow only yes or no\n"); + } + xmlFree(prop); + } + comp->select = xmlGetNsProp(inst, (const xmlChar *)"select", + XSLT_NAMESPACE); + if (comp->select == NULL) { + xsltGenericError(xsltGenericErrorContext, + "xslt:value-of : select is missing\n"); + } +} + +/** + * xsltNumberComp: + * @ctxt: a XSLT process context + * @cur: the xslt number node + * + * Process the xslt number node on the source node + */ +void +xsltNumberComp(xsltTransformContextPtr ctxt, xmlNodePtr cur) { + xsltStylePreCompPtr comp; + xmlChar *prop; + + if ((ctxt == NULL) || (cur == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_NUMBER); + if (comp == NULL) + return; + cur->_private = comp; + + if ((ctxt == NULL) || (cur == NULL)) + return; + + comp->numdata.doc = cur->doc; + comp->numdata.node = cur; + comp->numdata.value = xmlGetNsProp(cur, (const xmlChar *)"value", + XSLT_NAMESPACE); + + prop = xmlGetNsProp(cur, (const xmlChar *)"format", XSLT_NAMESPACE); + if (prop != NULL) { + comp->numdata.format = prop; + } else { + comp->numdata.format = xmlStrdup(BAD_CAST("1")); + } + + comp->numdata.count = xmlGetNsProp(cur, (const xmlChar *)"count", + XSLT_NAMESPACE); + comp->numdata.from = xmlGetNsProp(cur, (const xmlChar *)"from", + XSLT_NAMESPACE); + + prop = xmlGetNsProp(cur, (const xmlChar *)"level", XSLT_NAMESPACE); + if (prop != NULL) { + if (xmlStrEqual(prop, BAD_CAST("single")) || + xmlStrEqual(prop, BAD_CAST("multiple")) || + xmlStrEqual(prop, BAD_CAST("any"))) { + comp->numdata.level = prop; + } else { + xsltGenericError(xsltGenericErrorContext, + "xsl:number : invalid value %s for level\n", prop); + xmlFree(prop); + } + } + + prop = xmlGetNsProp(cur, (const xmlChar *)"lang", XSLT_NAMESPACE); + if (prop != NULL) { + TODO; /* xsl:number lang attribute */ + xmlFree(prop); + } + + prop = xmlGetNsProp(cur, (const xmlChar *)"letter-value", XSLT_NAMESPACE); + if (prop != NULL) { + if (xmlStrEqual(prop, BAD_CAST("alphabetic"))) { + TODO; /* xsl:number letter-value attribute alphabetic */ + } else if (xmlStrEqual(prop, BAD_CAST("traditional"))) { + TODO; /* xsl:number letter-value attribute traditional */ + } else { + xsltGenericError(xsltGenericErrorContext, + "xsl:number : invalid value %s for letter-value\n", prop); + } + xmlFree(prop); + } + + prop = xmlGetNsProp(cur, (const xmlChar *)"grouping-separator", XSLT_NAMESPACE); + if (prop != NULL) { + comp->numdata.groupingCharacter = prop[0]; + xmlFree(prop); + } + + prop = xmlGetNsProp(cur, (const xmlChar *)"grouping-size", XSLT_NAMESPACE); + if (prop != NULL) { + sscanf((char *)prop, "%d", &comp->numdata.digitsPerGroup); + xmlFree(prop); + } else { + comp->numdata.groupingCharacter = 0; + } + + /* Set default values */ + if (comp->numdata.value == NULL) { + if (comp->numdata.level == NULL) { + comp->numdata.level = xmlStrdup(BAD_CAST("single")); + } + } + +} + +/** + * xsltApplyImportsComp: + * @ctxt: a XSLT process context + * @inst: the xslt apply-imports node + * + * Process the xslt apply-imports node on the source node + */ +void +xsltApplyImportsComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + + if ((ctxt == NULL) || (inst == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_APPLYIMPORTS); + if (comp == NULL) + return; + inst->_private = comp; +} + +/** + * xsltCallTemplateComp: + * @ctxt: a XSLT process context + * @inst: the xslt call-template node + * + * Process the xslt call-template node on the source node + */ +void +xsltCallTemplateComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + xmlChar *prop; + xmlChar *ncname = NULL; + xmlChar *prefix = NULL; + xmlNsPtr ns; + + if ((ctxt == NULL) || (inst == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_CALLTEMPLATE); + if (comp == NULL) + return; + inst->_private = comp; + + /* + * The full template resolution can be done statically + */ + prop = xmlGetNsProp(inst, (const xmlChar *)"name", XSLT_NAMESPACE); + if (prop == NULL) { + xsltGenericError(xsltGenericErrorContext, + "xslt:call-template : name is missing\n"); + goto error; + } else { + + ncname = xmlSplitQName2(prop, &prefix); + if (ncname == NULL) { + ncname = prop; + prop = NULL; + prefix = NULL; + } + if (prefix != NULL) { + ns = xmlSearchNs(ctxt->insert->doc, ctxt->insert, prefix); + if (ns == NULL) { + xsltGenericError(xsltGenericErrorContext, + "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); + } + } + + /* TODO: with-param could be optimized too */ + +error: + if (prop != NULL) + xmlFree(prop); + if (ncname != NULL) + xmlFree(ncname); + if (prefix != NULL) + xmlFree(prefix); +} + +/** + * xsltApplyTemplatesComp: + * @ctxt: a XSLT process context + * @inst: the apply-templates node + * + * Process the apply-templates node on the source node + */ +void +xsltApplyTemplatesComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + xmlChar *prop; + + if ((ctxt == NULL) || (inst == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_APPLYTEMPLATES); + if (comp == NULL) + return; + inst->_private = comp; + + /* + * Get mode if any + */ + prop = xmlGetNsProp(inst, (const xmlChar *)"mode", XSLT_NAMESPACE); + if (prop != NULL) { + xmlChar *prefix = NULL; + + comp->mode = xmlSplitQName2(prop, &prefix); + if (comp->mode != NULL) { + if (prefix != NULL) { + xmlNsPtr ns; + + ns = xmlSearchNs(inst->doc, inst, prefix); + if (ns == NULL) { + xsltGenericError(xsltGenericErrorContext, + "no namespace bound to prefix %s\n", prefix); + xmlFree(prefix); + xmlFree(comp->mode); + comp->mode = prop; + comp->modeURI = NULL; + } else { + comp->modeURI = xmlStrdup(ns->href); + xmlFree(prefix); + xmlFree(prop); + } + } else { + xmlFree(prop); + comp->modeURI = NULL; + } + } else { + comp->mode = prop; + comp->modeURI = NULL; + } + } + comp->select = xmlGetNsProp(inst, (const xmlChar *)"select", + XSLT_NAMESPACE); + + /* TODO: handle (or skip) the xsl:sort and xsl:with-param */ +} + +/** + * xsltChooseComp: + * @ctxt: a XSLT process context + * @inst: the xslt choose node + * + * Process the xslt choose node on the source node + */ +void +xsltChooseComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + + if ((ctxt == NULL) || (inst == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_CHOOSE); + if (comp == NULL) + return; + inst->_private = comp; +} + +/** + * xsltIfComp: + * @ctxt: a XSLT process context + * @inst: the xslt if node + * + * Process the xslt if node on the source node + */ +void +xsltIfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + + if ((ctxt == NULL) || (inst == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_IF); + if (comp == NULL) + return; + inst->_private = comp; + + comp->test = xmlGetNsProp(inst, (const xmlChar *)"test", XSLT_NAMESPACE); + if (comp->test == NULL) { + xsltGenericError(xsltGenericErrorContext, + "xsltIf: test is not defined\n"); + return; + } +} + +/** + * xsltForEachComp: + * @ctxt: a XSLT process context + * @inst: the xslt for-each node + * + * Process the xslt for-each node on the source node + */ +void +xsltForEachComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + xsltStylePreCompPtr comp; + + if ((ctxt == NULL) || (inst == NULL)) + return; + comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_FOREACH); + if (comp == NULL) + return; + inst->_private = comp; + + comp->select = xmlGetNsProp(inst, (const xmlChar *)"select", + XSLT_NAMESPACE); + + /* TODO: handle and skip the xsl:sort */ +} + + +/************************************************************************ + * * + * Generic interface * + * * + ************************************************************************/ + +/** + * xsltFreeStylePreComps: + * @ctxt: an XSLT transformation context + * + * Free up the memory allocated by all precomputed blocks + */ +void +xsltFreeStylePreComps(xsltTransformContextPtr ctxt) { + xsltStylePreCompPtr cur, next; + + if (ctxt == NULL) + return; + cur = ctxt->preComps; + while (cur != NULL) { + next = cur->next; + xsltFreeStylePreComp(cur); + cur = next; + } +} + +/** + * xsltDocumentCompute: + * @ctxt: an XSLT processing context + * @inst: the instruction in the stylesheet + * + * Precompute an XSLT stylesheet element + */ +void +xsltStylePreCompute(xsltTransformContextPtr ctxt, xmlNodePtr inst) { + if (IS_XSLT_ELEM(inst)) { + if (IS_XSLT_NAME(inst, "apply-templates")) { + xsltApplyTemplatesComp(ctxt, inst); + } else if (IS_XSLT_NAME(inst, "value-of")) { + xsltValueOfComp(ctxt, inst); + } else if (IS_XSLT_NAME(inst, "copy")) { + xsltCopyComp(ctxt, inst); + } else if (IS_XSLT_NAME(inst, "copy-of")) { + xsltCopyOfComp(ctxt, inst); + } else if (IS_XSLT_NAME(inst, "if")) { + xsltIfComp(ctxt, inst); + } else if (IS_XSLT_NAME(inst, "choose")) { + xsltChooseComp(ctxt, inst); + } else if (IS_XSLT_NAME(inst, "for-each")) { + xsltForEachComp(ctxt, inst); + } else if (IS_XSLT_NAME(inst, "apply-imports")) { + xsltApplyImportsComp(ctxt, inst); + } else if (IS_XSLT_NAME(inst, "attribute")) { + xsltAttributeComp(ctxt, inst); + } else if (IS_XSLT_NAME(inst, "element")) { + xsltElementComp(ctxt, inst); + } else if (IS_XSLT_NAME(inst, "text")) { + xsltTextComp(ctxt, inst); + } else if (IS_XSLT_NAME(inst, "comment")) { + xsltCommentComp(ctxt, inst); + } else if (IS_XSLT_NAME(inst, "number")) { + xsltNumberComp(ctxt, inst); + } else if (IS_XSLT_NAME(inst, "processing-instruction")) { + xsltProcessingInstructionComp(ctxt, inst); + } else if (IS_XSLT_NAME(inst, "call-template")) { + xsltCallTemplateComp(ctxt, inst); + } else if (IS_XSLT_NAME(inst, "variable")) { + /* TODO: is there any use optimizing variable too ? */ + return; + } else if (IS_XSLT_NAME(inst, "message")) { + /* no optimization needed */ + return; + } else if (IS_XSLT_NAME(inst, "document")) { + xsltDocumentComp(ctxt, inst); + } else { + xsltGenericError(xsltGenericDebugContext, + "xsltStylePreComp: unknown xslt:%s\n", inst->name); + } + } +} diff --git a/libxslt/preproc.h b/libxslt/preproc.h new file mode 100644 index 0000000..f07412e --- /dev/null +++ b/libxslt/preproc.h @@ -0,0 +1,30 @@ +/* + * preproc.h: precomputing data interfaces + * + * See Copyright for the status of this software. + * + * Daniel.Veillard@imag.fr + */ + +#ifndef __XML_XSLT_PRECOMP_H__ +#define __XML_XSLT_PRECOMP_H__ + +#include +#include "xsltInternals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Interfaces + */ +void xsltStylePreCompute (xsltTransformContextPtr ctxt, + xmlNodePtr inst); +void xsltFreeStylePreComps (xsltTransformContextPtr ctxt); +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_PRECOMP_H__ */ + diff --git a/libxslt/templates.c b/libxslt/templates.c index 694357f..1f2dd53 100644 --- a/libxslt/templates.c +++ b/libxslt/templates.c @@ -267,6 +267,43 @@ xsltEvalAttrValueTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, } /** + * xsltEvalStaticAttrValueTemplate: + * @ctxt: the XSLT transformation context + * @node: the stylesheet node + * @name: the attribute QName + * @found: indicator whether the attribute is present + * + * Check if an attribute value template has a static value, i.e. the + * attribute value does not contain expressions contained in curly braces ({}) + * + * Returns the static string value or NULL, must be deallocated by the + * caller. + */ +xmlChar * +xsltEvalStaticAttrValueTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, + const xmlChar *name, int *found) { + const xmlChar *ret; + xmlChar *expr; + + if ((ctxt == NULL) || (node == NULL) || (name == NULL)) + return(NULL); + + expr = xmlGetNsProp(node, name, XSLT_NAMESPACE); + if (expr == NULL) { + *found = 0; + return(NULL); + } + *found = 1; + + ret = xmlStrchr(expr, '{'); + if (ret != NULL) { + xmlFree(expr); + return(NULL); + } + return(expr); +} + +/** * xsltAttrTemplateProcess: * @ctxt: the XSLT transformation context * @target: the result node diff --git a/libxslt/templates.h b/libxslt/templates.h index 0fdb763..be2f6c0 100644 --- a/libxslt/templates.h +++ b/libxslt/templates.h @@ -25,6 +25,10 @@ xmlChar * xsltEvalTemplateString (xsltTransformContextPtr ctxt, xmlChar * xsltEvalAttrValueTemplate (xsltTransformContextPtr ctxt, xmlNodePtr node, const xmlChar *name); +xmlChar * xsltEvalStaticAttrValueTemplate (xsltTransformContextPtr ctxt, + xmlNodePtr node, + const xmlChar *name, + int *found); xmlChar * xsltEvalXPathString (xsltTransformContextPtr ctxt, const xmlChar *expr); xmlNodePtr * xsltTemplateProcess (xsltTransformContextPtr ctxt, diff --git a/libxslt/transform.c b/libxslt/transform.c index 196e722..38790dd 100644 --- a/libxslt/transform.c +++ b/libxslt/transform.c @@ -47,6 +47,7 @@ #include "documents.h" #include "extensions.h" #include "extra.h" +#include "preproc.h" #define DEBUG_PROCESS @@ -209,6 +210,7 @@ xsltFreeTransformContext(xsltTransformContextPtr ctxt) { xmlFree(ctxt->varsTab); xsltFreeDocuments(ctxt); xsltFreeCtxtExts(ctxt); + xsltFreeStylePreComps(ctxt); memset(ctxt, -1, sizeof(xsltTransformContext)); xmlFree(ctxt); } @@ -838,6 +840,96 @@ error: } /** + * xsltAttribute: + * @ctxt: a XSLT process context + * @node: the node in the source tree. + * @inst: the xslt attribute node + * + * Process the xslt attribute node on the source node + */ +void +xsltAttribute(xsltTransformContextPtr ctxt, xmlNodePtr node, + xmlNodePtr inst) { + xmlChar *prop = NULL; + xmlChar *ncname = NULL; + xmlChar *prefix = NULL; + xmlChar *value = NULL; + xmlNsPtr ns = NULL; + xmlAttrPtr attr; + + + if (ctxt->insert == NULL) + return; + if (ctxt->insert->children != NULL) { + xsltGenericError(xsltGenericErrorContext, + "xslt:attribute : node has already children\n"); + return; + } + prop = xsltEvalAttrValueTemplate(ctxt, inst, (const xmlChar *)"name"); + if (prop == NULL) { + xsltGenericError(xsltGenericErrorContext, + "xslt:attribute : name is missing\n"); + goto error; + } + + ncname = xmlSplitQName2(prop, &prefix); + if (ncname == NULL) { + ncname = prop; + prop = NULL; + prefix = NULL; + } + + if ((prefix != NULL) && (xmlStrEqual(prefix, (const xmlChar *)"xmlns"))) { +#ifdef DEBUG_ATTRIBUTES + xsltGenericDebug(xsltGenericDebugContext, + "xslt:attribute : xmlns prefix forbidden\n"); +#endif + goto error; + } + prop = xsltEvalAttrValueTemplate(ctxt, inst, (const xmlChar *)"namespace"); + if (prop != NULL) { + ns = xsltGetSpecialNamespace(ctxt, inst, prop, prefix, ctxt->insert); + } else { + if (prefix != NULL) { + ns = xmlSearchNs(inst->doc, inst, prefix); + if (ns == NULL) { + xsltGenericError(xsltGenericErrorContext, + "no namespace bound to prefix %s\n", prefix); + } else { + ns = xsltGetNamespace(ctxt, inst, ns, ctxt->insert); + } + } + } + + + value = xsltEvalTemplateString(ctxt, node, inst); + if (value == NULL) { + if (ns) { + attr = xmlSetNsProp(ctxt->insert, ns, ncname, + (const xmlChar *)""); + } else + attr = xmlSetProp(ctxt->insert, ncname, (const xmlChar *)""); + } else { + if (ns) { + attr = xmlSetNsProp(ctxt->insert, ns, ncname, value); + } else + attr = xmlSetProp(ctxt->insert, ncname, value); + + } + +error: + if (prop != NULL) + xmlFree(prop); + if (ncname != NULL) + xmlFree(ncname); + if (prefix != NULL) + xmlFree(prefix); + if (value != NULL) + xmlFree(value); +} + + +/** * xsltComment: * @ctxt: a XSLT process context * @node: the node in the source tree. @@ -1951,8 +2043,37 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, return; } - if (IS_XSLT_ELEM(cur)) { - if (IS_XSLT_NAME(cur, "apply-templates")) { + if (cur->_private != NULL) { + xsltStylePreCompPtr info = (xsltStylePreCompPtr) cur->_private; + if (info->func != NULL) { + ctxt->insert = insert; + info->func(ctxt, node, cur); + ctxt->insert = oldInsert; + } else { + xsltGenericError(xsltGenericDebugContext, + "xsltApplyOneTemplate: %s has _private without function\n", + cur->name); + } + goto skip_children; + } else if (IS_XSLT_ELEM(cur)) { + xsltStylePreCompute(ctxt, cur); + if (cur->_private != NULL) { + xsltStylePreCompPtr info = (xsltStylePreCompPtr) cur->_private; + if (info->func != NULL) { + ctxt->insert = insert; + info->func(ctxt, node, cur); + ctxt->insert = oldInsert; + } else { + xsltGenericError(xsltGenericDebugContext, + "xsltApplyOneTemplate: %s has _private without function\n", + cur->name); + } + goto skip_children; + } + + if (IS_XSLT_NAME(cur, "variable")) { + xsltParseStylesheetVariable(ctxt, cur); + } else if (IS_XSLT_NAME(cur, "apply-templates")) { ctxt->insert = insert; xsltApplyTemplates(ctxt, node, cur); ctxt->insert = oldInsert; @@ -2010,8 +2131,6 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, ctxt->insert = insert; xsltProcessingInstruction(ctxt, node, cur); ctxt->insert = oldInsert; - } else if (IS_XSLT_NAME(cur, "variable")) { - xsltParseStylesheetVariable(ctxt, cur); } else if (IS_XSLT_NAME(cur, "param")) { xsltParseStylesheetParam(ctxt, cur); } else if (IS_XSLT_NAME(cur, "call-template")) { diff --git a/libxslt/transform.h b/libxslt/transform.h index bfc9e05..0e0fa76 100644 --- a/libxslt/transform.h +++ b/libxslt/transform.h @@ -28,6 +28,54 @@ void xsltApplyOneTemplate (xsltTransformContextPtr ctxt, void xsltDocumentElem (xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst); +void xsltSort (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); +void xsltCopy (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); +void xsltText (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); +void xsltElement (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); +void xsltComment (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); +void xsltAttribute (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); +void xsltProcessingInstruction(xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); +void xsltCopyOf (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); +void xsltValueOf (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); +void xsltNumber (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr cur); +void xsltApplyImports (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); +void xsltCallTemplate (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); +void xsltApplyTemplates (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); +void xsltChoose (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); +void xsltIf (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); +void xsltForEach (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); #ifdef __cplusplus } #endif diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h index ae00895..fdd42be 100644 --- a/libxslt/xsltInternals.h +++ b/libxslt/xsltInternals.h @@ -14,6 +14,7 @@ #include #include #include +#include "numbersInternals.h" #ifdef __cplusplus extern "C" { @@ -181,6 +182,80 @@ struct _xsltStylesheet { /* + * The in-memory structure corresponding to XSLT stylesheet constructs + * precomputed data. + */ + +typedef struct _xsltTransformContext xsltTransformContext; +typedef xsltTransformContext *xsltTransformContextPtr; + +typedef void (*xsltStyleFunc) (xsltTransformContextPtr ctxt, + xmlNodePtr node, xmlNodePtr inst); + +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; + +typedef struct _xsltStylePreComp xsltStylePreComp; +typedef xsltStylePreComp *xsltStylePreCompPtr; +struct _xsltStylePreComp { + struct _xsltStylePreComp *next;/* chained list */ + xsltStyleType type; /* type of the element */ + xsltStyleFunc func; /* handling function */ + + /* + * 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 */ + + xsltNumberData numdata; /* number */ +}; + +/* * The in-memory structure corresponding to an XSLT Transformation */ typedef enum { @@ -195,8 +270,6 @@ typedef enum { XSLT_STATE_STOPPED } xsltTransformState; -typedef struct _xsltTransformContext xsltTransformContext; -typedef xsltTransformContext *xsltTransformContextPtr; struct _xsltTransformContext { xsltStylesheetPtr style; /* the stylesheet used */ xsltOutputType type; /* the type of output */ @@ -212,6 +285,11 @@ struct _xsltTransformContext { xsltStackElemPtr *varsTab; /* the variable list stack */ /* + * Precomputed blocks + */ + xsltStylePreCompPtr preComps; /* list of precomputed blocks */ + + /* * Extensions */ xmlHashTablePtr extFunctions; /* the extension functions */ @@ -259,6 +337,14 @@ xsltStylesheetPtr xsltParseStylesheetProcess(xsltStylesheetPtr ret, void xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur); xsltStylesheetPtr xsltParseStylesheetDoc (xmlDocPtr doc); +void xsltNumberFormat (xsltTransformContextPtr ctxt, + xsltNumberDataPtr data, + xmlNodePtr node); +xmlXPathError xsltFormatNumberConversion(xsltDecimalFormatPtr self, + xmlChar *format, + double number, + xmlChar **result); + #ifdef __cplusplus } #endif diff --git a/libxslt/xsltutils.h b/libxslt/xsltutils.h index bd13734..44238e5 100644 --- a/libxslt/xsltutils.h +++ b/libxslt/xsltutils.h @@ -20,13 +20,9 @@ extern "C" { /* * To cleanup */ +int xmlXPathIsNodeType(const xmlChar *name); xmlChar *xmlSplitQName2(const xmlChar *name, xmlChar **prefix); void xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs); -xmlAttrPtr xmlSetNsProp (xmlNodePtr node, xmlNsPtr ns, const xmlChar *name, - const xmlChar *value); -xmlNodePtr xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur); -xmlNodePtr xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur); -xmlNodePtr xmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur); /********* void xmlXPathRegisterVariableLookup(xmlXPathContextPtr ctxt, xmlXPathVariableLookupFunc f, void *data) -- 2.7.4