Re: [xslt] extension modules
- From: Thomas Broyer <tbroyer ltgt net>
- To: xslt gnome org
- Subject: Re: [xslt] extension modules
- Date: Thu, 26 Jul 2001 14:45:22 +0200
Le 22/07/01 06:34:40, Thomas Broyer a écrit :
> Here's a list of some of the changes:
> · added an extInfos field to xsltStylesheet for stylesheet module data
> · added the couple of stylesheet data init/shutdown functions to
> xsltExtModule (this is a private struct)
> and a function xsltRegisterExtModuleFull that receives these 4
> functions
> · added xslt{Register,Unregister}ExtModule{Function,ElementTopLevel}
> and xsltExtModule{Function,Element,ElementPreCompute,TopLevel}Lookup
> · added function lookup framework to libxml/XPath and used it in
> libxslt
> and modified the extension element lookup in the same way (look for
> the element in the context, then in the global registry)
> · modified xsltGetExtData to initialize the module when needed and
> added xsltStyleGetExtData for the stylesheet data
> · modified xsltInitCtxtExts to do the automatic initialization of
> modules with stylesheet data (and do not care about
> extension-element-prefixes)
> · modified xsltParseTemplateContent to be independant of xsltTemplate
> and made it public: extension elements may need it (func:function do)
> to precompute their contents.
> · modified xsltPrecomputeStylesheetTop to precompute top-level elements
>
> What's still needed:
> · correct handling of extension-element-prefixes and
> exclude-result-prefixes. extension-element-prefixes may need binding
> data to the _private field of *every* element node (even literal
> result elements)
> · actually do extension element precomputation
> · test, test and test again...
Here's the patch, if someone wants to help. Please note that the API won't
be freezed until we stated on my message on 23/07/01 19:39:47 in this
thread about an "extension element precomputed data framework".
Also:
· code isn't as clean as it could be => the patch can't be commited as-is
· extension element precomputation is almost done. There's some "bug"
for elements with a local-name equal to "document".
· I moved the test module from functions.c to extensions.c. Other
"extras" should also be moved to the new extension framework IMO.
Tom.
Index: libexslt/common.c
===================================================================
RCS file: /cvs/gnome/libxslt/libexslt/common.c,v
retrieving revision 1.4
diff -u -r1.4 common.c
--- libexslt/common.c 2001/07/16 04:56:47 1.4
+++ libexslt/common.c 2001/07/25 14:54:35
@@ -52,19 +52,6 @@
}
-static void *
-exsltCommonInit (xsltTransformContextPtr ctxt, const xmlChar *URI) {
- xsltRegisterExtFunction (ctxt, (const xmlChar *) "node-set",
- URI, xsltFunctionNodeSet);
- xsltRegisterExtFunction (ctxt, (const xmlChar *) "object-type",
- URI, exsltObjectTypeFunction);
-
- xsltRegisterExtElement (ctxt, (const xmlChar *) "document",
- URI, xsltDocumentElem);
-
- return(NULL);
-}
-
/**
* exsltCommonRegister:
*
@@ -73,6 +60,13 @@
void
exsltCommonRegister (void) {
- xsltRegisterExtModule (EXSLT_COMMON_NAMESPACE,
- exsltCommonInit, NULL);
+ xsltRegisterExtModuleFunction((const xmlChar *) "node-set",
+ EXSLT_COMMON_NAMESPACE,
+ xsltFunctionNodeSet);
+ xsltRegisterExtModuleFunction((const xmlChar *) "object-type",
+ EXSLT_COMMON_NAMESPACE,
+ exsltObjectTypeFunction);
+ xsltRegisterExtModuleElement((const xmlChar *) "document",
+ EXSLT_COMMON_NAMESPACE,
+ NULL, xsltDocumentElem);
}
Index: libexslt/functions.c
===================================================================
RCS file: /cvs/gnome/libxslt/libexslt/functions.c,v
retrieving revision 1.4
diff -u -r1.4 functions.c
--- libexslt/functions.c 2001/07/16 04:56:47 1.4
+++ libexslt/functions.c 2001/07/25 14:54:35
@@ -23,13 +23,33 @@
int error;
};
-static void exsltFuncFunctionElem (xsltTransformContextPtr ctxt,
- xmlNodePtr node, xmlNodePtr inst,
- xsltStylePreCompPtr comp);
-static void exsltFuncResultElem (xsltTransformContextPtr ctxt,
- xmlNodePtr node, xmlNodePtr inst,
- xsltStylePreCompPtr comp);
+static void exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt,
+ int nargs);
+
+/**
+ * exsltFuncRegisterFunc:
+ * @func: the #exsltFuncFunctionData for the function
+ * @ctxt: an XSLT transformation context
+ * @URI: the function namespace URI
+ * @name: the function name
+ *
+ * Registers a function declared by a func:function element
+ */
+static void
+exsltFuncRegisterFunc (exsltFuncFunctionData *data,
+ xsltTransformContextPtr ctxt,
+ const xmlChar *URI, const xmlChar *name) {
+ if ((data == NULL) || (ctxt == NULL) || (URI == NULL) || (name == NULL))
+ return;
+
+ xsltGenericDebug(xsltGenericDebugContext,
+ "exsltFuncRegisterFunc: register {%s}%s\n",
+ URI, name);
+ xsltRegisterExtFunction(ctxt, name, URI,
+ exsltFuncFunctionFunction);
+}
+
/**
* exsltFuncInit:
* @ctxt: an XSLT transformation context
@@ -41,6 +61,7 @@
*/
static exsltFuncData *
exsltFuncInit (xsltTransformContextPtr ctxt, const xmlChar *URI) {
+ xmlHashTablePtr hash;
exsltFuncData *ret;
ret = (exsltFuncData *) xmlMalloc (sizeof(exsltFuncData));
@@ -51,15 +72,13 @@
}
memset(ret, 0, sizeof(exsltFuncData));
- ret->funcs = xmlHashCreate(1);
ret->result = NULL;
ret->error = 0;
- xsltRegisterExtElement (ctxt, (const xmlChar *) "function",
- URI, exsltFuncFunctionElem);
- xsltRegisterExtElement (ctxt, (const xmlChar *) "result",
- URI, exsltFuncResultElem);
+ hash = (xmlHashTablePtr) xsltStyleGetExtData(ctxt->style, URI);
+ xmlHashScanFull(hash, (xmlHashScannerFull) exsltFuncRegisterFunc, ctxt);
+ ret->funcs = hash;
return(ret);
}
@@ -67,7 +86,7 @@
/**
* exsltFuncShutdown:
* @ctxt: an XSLT transformation context
- * @URI: the namespace URI fir the extension
+ * @URI: the namespace URI for the extension
* @data: the module data to free up
*
* Shutdown the EXSLT - Functions module
@@ -76,23 +95,39 @@
exsltFuncShutdown (xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
const xmlChar *URI ATTRIBUTE_UNUSED,
exsltFuncData *data) {
- if (data->funcs != NULL)
- xmlHashFree(data->funcs, (xmlHashDeallocator) xmlFree);
if (data->result != NULL)
xmlXPathFreeObject(data->result);
xmlFree(data);
}
/**
- * exsltFuncRegister:
+ * exsltFuncStyleInit:
+ * @style: an XSLT stylesheet
+ * @URI: the namespace URI for the extension
*
- * Registers the EXSLT - Functions module
+ * Allocates the styleshet data for EXSLT - Function
+ *
+ * Returns the allocated data
*/
-void
-exsltFuncRegister (void) {
- xsltRegisterExtModule (EXSLT_FUNCTIONS_NAMESPACE,
- (xsltExtInitFunction) exsltFuncInit,
- (xsltExtShutdownFunction) exsltFuncShutdown);
+static xmlHashTablePtr
+exsltFuncStyleInit (xsltStylesheetPtr style ATTRIBUTE_UNUSED,
+ const xmlChar *URI ATTRIBUTE_UNUSED) {
+ return xmlHashCreate(1);
+}
+
+/**
+ * exsltFuncStyleShutdown:
+ * @style: an XSLT stylesheet
+ * @URI: the namespace URI for the extension
+ * @data: the stylesheet data to free up
+ *
+ * Shutdown the EXSLT - Function module
+ */
+static void
+exsltFuncStyleShutdown (xsltStylesheetPtr style ATTRIBUTE_UNUSED,
+ const xmlChar *URI ATTRIBUTE_UNUSED,
+ xmlHashTablePtr data) {
+ xmlHashFree(data, NULL);
}
/**
@@ -112,6 +147,7 @@
"exsltFuncNewFunctionData: not enough memory\n");
return (NULL);
}
+ memset(ret, 0, sizeof(exsltFuncFunctionData));
ret->nargs = 0;
ret->content = NULL;
@@ -124,11 +160,12 @@
* @ctxt: an XPath parser context
* @nargs: the number of arguments
*
- * Evaluates the func:function element defining the called function.
+ * Evaluates the func:function element that defines the called function.
*/
static void
exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
xmlXPathObjectPtr obj, oldResult, ret;
+ xmlHashTablePtr funcs;
exsltFuncData *data;
exsltFuncFunctionData *func;
xmlNodePtr paramNode, oldInsert, fake;
@@ -215,6 +252,7 @@
* the generation of result nodes.
*/
if (fake->children != NULL) {
+ xmlDebugDumpNode (stderr, fake, 1);
xsltGenericError(xsltGenericErrorContext,
"{%s}%s: cannot write to result tree while "
"executing a function\n",
@@ -224,16 +262,18 @@
valuePush(ctxt, ret);
}
+
+void xsltParseTemplateContent(xsltStylesheetPtr style,
+ xmlNodePtr template);
+
static void
-exsltFuncFunctionElem (xsltTransformContextPtr ctxt, xmlNodePtr node,
- xmlNodePtr inst, xsltStylePreCompPtr comp) {
+exsltFuncFunctionComp (xsltStylesheetPtr style, xmlNodePtr inst) {
xmlChar *name, *prefix;
xmlNsPtr ns;
- exsltFuncData *data;
+ xmlHashTablePtr data;
exsltFuncFunctionData *func;
- xsltStylePreCompPtr param_comp;
- if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
{
@@ -267,27 +307,36 @@
*/
func = exsltFuncNewFunctionData();
func->content = inst->children;
- param_comp = (xsltStylePreCompPtr) func->content->_private;
- while ((param_comp != NULL) && (param_comp->type == XSLT_FUNC_PARAM)) {
+ while (IS_XSLT_ELEM(func->content) &&
+ IS_XSLT_NAME(func->content, "param")) {
func->content = func->content->next;
func->nargs++;
- param_comp = (xsltStylePreCompPtr) func->content->_private;
}
+ xsltParseTemplateContent(style, inst);
+
/*
* Register the function data such that it can be retrieved
* by exslFuncFunctionFunction
- */
- data = (exsltFuncData *) xsltGetExtData (ctxt, EXSLT_FUNCTIONS_NAMESPACE);
- xmlHashAddEntry2 (data->funcs, ns->href, name, func);
-
- /*
- * Register the function such that it is available for use in XPath
- * expressions.
*/
- xsltRegisterExtFunction (ctxt, name, ns->href,
- exsltFuncFunctionFunction);
+ data = (xmlHashTablePtr) xsltStyleGetExtData (style,
+ EXSLT_FUNCTIONS_NAMESPACE);
+ if (data == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "exsltFuncFunctionComp: no stylesheet data\n");
+ xmlFree(name);
+ return;
+ }
+ if (xmlHashAddEntry2 (data, ns->href, name, func) < 0) {
+ xsltGenericError(xsltGenericErrorContext,
+ "Failed to register function {%s}%s\n",
+ ns->href, name);
+ } else {
+ xsltGenericDebug(xsltGenericDebugContext,
+ "exsltFuncFunctionComp: register {%s}%s\n",
+ ns->href, name);
+ }
xmlFree(name);
}
@@ -415,4 +464,26 @@
ret = xmlXPathNewCString("");
}
data->result = ret;
+}
+
+/**
+ * exsltFuncRegister:
+ *
+ * Registers the EXSLT - Functions module
+ */
+void
+exsltFuncRegister (void) {
+ xsltRegisterExtModuleFull (EXSLT_FUNCTIONS_NAMESPACE,
+ (xsltExtInitFunction) exsltFuncInit,
+ (xsltExtShutdownFunction) exsltFuncShutdown,
+ (xsltStyleExtInitFunction) exsltFuncStyleInit,
+ (xsltStyleExtShutdownFunction) exsltFuncStyleShutdown);
+
+ xsltRegisterExtModuleTopLevel ((const xmlChar *) "function",
+ EXSLT_FUNCTIONS_NAMESPACE,
+ exsltFuncFunctionComp);
+ xsltRegisterExtModuleElement ((const xmlChar *) "result",
+ EXSLT_FUNCTIONS_NAMESPACE,
+ NULL,
+ exsltFuncResultElem);
}
Index: libexslt/math.c
===================================================================
RCS file: /cvs/gnome/libxslt/libexslt/math.c,v
retrieving revision 1.5
diff -u -r1.5 math.c
--- libexslt/math.c 2001/07/23 00:55:42 1.5
+++ libexslt/math.c 2001/07/25 14:54:35
@@ -271,19 +271,6 @@
xmlXPathReturnNodeSet(ctxt, ret);
}
-static void *
-exsltMathInit (xsltTransformContextPtr ctxt, const xmlChar *URI) {
- xsltRegisterExtFunction (ctxt, (const xmlChar *) "min",
- URI, exsltMathMinFunction);
- xsltRegisterExtFunction (ctxt, (const xmlChar *) "max",
- URI, exsltMathMaxFunction);
- xsltRegisterExtFunction (ctxt, (const xmlChar *) "highest",
- URI, exsltMathHighestFunction);
- xsltRegisterExtFunction (ctxt, (const xmlChar *) "lowest",
- URI, exsltMathLowestFunction);
- return(NULL);
-}
-
/**
* exsltMathRegister:
*
@@ -292,5 +279,16 @@
void
exsltMathRegister (void) {
- xsltRegisterExtModule (EXSLT_MATH_NAMESPACE, exsltMathInit, NULL);
+ xsltRegisterExtModuleFunction ((const xmlChar *) "min",
+ EXSLT_MATH_NAMESPACE,
+ exsltMathMinFunction);
+ xsltRegisterExtModuleFunction ((const xmlChar *) "max",
+ EXSLT_MATH_NAMESPACE,
+ exsltMathMaxFunction);
+ xsltRegisterExtModuleFunction ((const xmlChar *) "highest",
+ EXSLT_MATH_NAMESPACE,
+ exsltMathHighestFunction);
+ xsltRegisterExtModuleFunction ((const xmlChar *) "lowest",
+ EXSLT_MATH_NAMESPACE,
+ exsltMathLowestFunction);
}
Index: libexslt/sets.c
===================================================================
RCS file: /cvs/gnome/libxslt/libexslt/sets.c,v
retrieving revision 1.4
diff -u -r1.4 sets.c
--- libexslt/sets.c 2001/07/16 04:56:47 1.4
+++ libexslt/sets.c 2001/07/25 14:54:35
@@ -221,24 +221,6 @@
xmlXPathReturnNodeSet(ctxt, ret);
}
-static void *
-exsltSetsInit (xsltTransformContextPtr ctxt, const xmlChar *URI) {
- xsltRegisterExtFunction (ctxt, (const xmlChar *) "difference",
- URI, exsltSetsDifferenceFunction);
- xsltRegisterExtFunction (ctxt, (const xmlChar *) "intersection",
- URI, exsltSetsIntersectionFunction);
- xsltRegisterExtFunction (ctxt, (const xmlChar *) "distinct",
- URI, exsltSetsDistinctFunction);
- xsltRegisterExtFunction (ctxt, (const xmlChar *) "has-same-nodes",
- URI, exsltSetsHasSameNodesFunction);
- xsltRegisterExtFunction (ctxt, (const xmlChar *) "leading",
- URI, exsltSetsLeadingFunction);
- xsltRegisterExtFunction (ctxt, (const xmlChar *) "trailing",
- URI, exsltSetsTrailingFunction);
-
- return(NULL);
-}
-
/**
* exsltCommonRegister:
*
@@ -247,5 +229,22 @@
void
exsltSetsRegister (void) {
- xsltRegisterExtModule (EXSLT_SETS_NAMESPACE, exsltSetsInit, NULL);
+ xsltRegisterExtModuleFunction ((const xmlChar *) "difference",
+ EXSLT_SETS_NAMESPACE,
+ exsltSetsDifferenceFunction);
+ xsltRegisterExtModuleFunction ((const xmlChar *) "intersection",
+ EXSLT_SETS_NAMESPACE,
+ exsltSetsIntersectionFunction);
+ xsltRegisterExtModuleFunction ((const xmlChar *) "distinct",
+ EXSLT_SETS_NAMESPACE,
+ exsltSetsDistinctFunction);
+ xsltRegisterExtModuleFunction ((const xmlChar *) "has-same-nodes",
+ EXSLT_SETS_NAMESPACE,
+ exsltSetsHasSameNodesFunction);
+ xsltRegisterExtModuleFunction ((const xmlChar *) "leading",
+ EXSLT_SETS_NAMESPACE,
+ exsltSetsLeadingFunction);
+ xsltRegisterExtModuleFunction ((const xmlChar *) "trailing",
+ EXSLT_SETS_NAMESPACE,
+ exsltSetsTrailingFunction);
}
Index: libxslt/extensions.c
===================================================================
RCS file: /cvs/gnome/libxslt/libxslt/extensions.c,v
retrieving revision 1.13
diff -u -r1.13 extensions.c
--- libxslt/extensions.c 2001/07/12 01:32:04 1.13
+++ libxslt/extensions.c 2001/07/25 14:54:35
@@ -49,6 +49,8 @@
struct _xsltExtModule {
xsltExtInitFunction initFunc;
xsltExtShutdownFunction shutdownFunc;
+ xsltStyleExtInitFunction styleInitFunc;
+ xsltStyleExtShutdownFunction styleShutdownFunc;
};
typedef struct _xsltExtData xsltExtData;
@@ -58,7 +60,17 @@
void *extData;
};
+typedef struct _xsltExtElement xsltExtElement;
+typedef xsltExtElement *xsltExtElementPtr;
+struct _xsltExtElement {
+ xsltPreComputeFunction precomp;
+ xsltTransformFunction transform;
+};
+
static xmlHashTablePtr xsltExtensionsHash = NULL;
+static xmlHashTablePtr xsltFunctionsHash = NULL;
+static xmlHashTablePtr xsltElementsHash = NULL;
+static xmlHashTablePtr xsltTopLevelsHash = NULL;
/************************************************************************
* *
@@ -133,6 +145,8 @@
* xsltNewExtModule:
* @initFunc: the module initialization function
* @shutdownFunc: the module shutdown function
+ * @styleInitFunc: the stylesheet module data allocator function
+ * @styleShutdownFunc: the stylesheet module data free function
*
* Create a new XSLT extension module
*
@@ -140,7 +154,9 @@
*/
static xsltExtModulePtr
xsltNewExtModule(xsltExtInitFunction initFunc,
- xsltExtShutdownFunction shutdownFunc)
+ xsltExtShutdownFunction shutdownFunc,
+ xsltStyleExtInitFunction styleInitFunc,
+ xsltStyleExtShutdownFunction styleShutdownFunc)
{
xsltExtModulePtr cur;
@@ -153,6 +169,8 @@
}
cur->initFunc = initFunc;
cur->shutdownFunc = shutdownFunc;
+ cur->styleInitFunc = styleInitFunc;
+ cur->styleShutdownFunc = styleShutdownFunc;
return (cur);
}
@@ -210,6 +228,49 @@
xmlFree(ext);
}
+/**
+ * xsltNewExtElement:
+ * @precomp: the pre-computation function
+ * @transform: the transformation function
+ *
+ * Create a new XSLT extension element
+ *
+ * Returns the newly allocated xsltExtElementPtr or NULL in case of
+ * error
+ */
+static xsltExtElementPtr
+xsltNewExtElement (xsltPreComputeFunction precomp,
+ xsltTransformFunction transform) {
+ xsltExtElementPtr cur;
+
+ if (transform == NULL)
+ return(NULL);
+
+ cur = (xsltExtElementPtr) xmlMalloc(sizeof(xsltExtElement));
+ if (cur == NULL) {
+ xsltPrintErrorContext(NULL, NULL, NULL);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltNewExtElement : malloc failed\n");
+ return (NULL);
+ }
+ cur->precomp = precomp;
+ cur->transform = transform;
+ return(cur);
+}
+
+/**
+ * xsltFreeExtElement:
+ * @ext: an XSLT extension element
+ *
+ * Frees up the memory allocated by @ext
+ */
+static void
+xsltFreeExtElement (xsltExtElementPtr ext) {
+ if (ext == NULL)
+ return;
+ xmlFree(ext);
+}
+
/************************************************************************
* *
@@ -290,6 +351,8 @@
}
if (ctxt->extFunctions == NULL)
ctxt->extFunctions = xmlHashCreate(10);
+ if (ctxt->extFunctions == NULL)
+ return(-1);
return(xmlHashAddEntry2(ctxt->extFunctions, name, URI, (void *) function));
}
@@ -312,6 +375,8 @@
return(-1);
if (ctxt->extElements == NULL)
ctxt->extElements = xmlHashCreate(10);
+ if (ctxt->extElements == NULL)
+ return(-1);
return(xmlHashAddEntry2(ctxt->extElements, name, URI, (void *) function));
}
@@ -330,6 +395,71 @@
}
/**
+ * xsltStyleGetExtData:
+ * @style: an XSLT stylesheet
+ * @URI: the URI associated to the exension module
+ *
+ * Retrieve the data associated to the extension module in this given
+ * stylesheet.
+ *
+ * Returns the pointer or NULL if not present
+ */
+void *
+xsltStyleGetExtData(xsltStylesheetPtr style, const xmlChar * URI) {
+ xsltExtDataPtr data;
+
+ if ((style == NULL) || (URI == NULL))
+ return (NULL);
+ if (style->extInfos == NULL) {
+ style->extInfos = xmlHashCreate(10);
+ if (style->extInfos == NULL)
+ return(NULL);
+ data = NULL;
+ } else {
+ data = (xsltExtDataPtr) xmlHashLookup(style->extInfos, URI);
+ }
+ if (data == NULL) {
+ void *extData;
+ xsltExtModulePtr module;
+
+ module = xmlHashLookup(xsltExtensionsHash, URI);
+ if (module == NULL) {
+#ifdef WITH_XSLT_DEBUG_EXTENSIONS
+ xsltGenericDebug(xsltGenericDebugContext,
+ "Not registered extension module: %s\n", URI);
+#endif
+ return(NULL);
+ } else {
+ if (module->styleInitFunc == NULL)
+ return(NULL);
+
+#ifdef WITH_XSLT_DEBUG_EXTENSIONS
+ xsltGenericDebug(xsltGenericDebugContext,
+ "Initializing module: %s\n", URI);
+#endif
+
+ extData = module->styleInitFunc(style, URI);
+ if (extData == NULL)
+ return(NULL);
+
+ data = xsltNewExtData(module, extData);
+ if (data == NULL)
+ return (NULL);
+ if (xmlHashAddEntry(style->extInfos, URI,
+ (void *) data) < 0) {
+ xsltGenericError(xsltGenericErrorContext,
+ "Failed to register module data: %s\n", URI);
+ if (module->styleShutdownFunc)
+ module->styleShutdownFunc(style, URI, extData);
+ xsltFreeExtData(data);
+ return(NULL);
+ }
+ }
+ }
+ return (data->extData);
+}
+
+/**
* xsltGetExtData:
* @ctxt: an XSLT transformation context
* @URI: the URI associated to the exension module
@@ -340,35 +470,149 @@
* Returns the pointer or NULL if not present
*/
void *
-xsltGetExtData(xsltTransformContextPtr ctxt, const xmlChar * URI)
-{
+xsltGetExtData(xsltTransformContextPtr ctxt, const xmlChar * URI) {
xsltExtDataPtr data;
- if ((ctxt == NULL) || (ctxt->extInfos == NULL) || (URI == NULL))
- return (NULL);
- data = (xsltExtDataPtr) xmlHashLookup(ctxt->extInfos, URI);
- if (data == NULL)
+ if ((ctxt == NULL) || (URI == NULL))
return (NULL);
+ if (ctxt->extInfos == NULL) {
+ ctxt->extInfos = xmlHashCreate(10);
+ if (ctxt->extInfos == NULL)
+ return(NULL);
+ data = NULL;
+ } else {
+ data = (xsltExtDataPtr) xmlHashLookup(ctxt->extInfos, URI);
+ }
+ if (data == NULL) {
+ void *extData;
+ xsltExtModulePtr module;
+
+ module = xmlHashLookup(xsltExtensionsHash, URI);
+ if (module == NULL) {
+#ifdef WITH_XSLT_DEBUG_EXTENSIONS
+ xsltGenericDebug(xsltGenericDebugContext,
+ "Not registered extension module: %s\n", URI);
+#endif
+ return(NULL);
+ } else {
+ if (module->initFunc == NULL)
+ return(NULL);
+
+#ifdef WITH_XSLT_DEBUG_EXTENSIONS
+ xsltGenericDebug(xsltGenericDebugContext,
+ "Initializing module: %s\n", URI);
+#endif
+
+ extData = module->initFunc(ctxt, URI);
+ if (extData == NULL)
+ return(NULL);
+
+ data = xsltNewExtData(module, extData);
+ if (data == NULL)
+ return (NULL);
+ if (xmlHashAddEntry(ctxt->extInfos, URI,
+ (void *) data) < 0) {
+ xsltPrintErrorContext(ctxt, NULL, NULL);
+ xsltGenericError(xsltGenericErrorContext,
+ "Failed to register module data: %s\n", URI);
+ if (module->shutdownFunc)
+ module->shutdownFunc(ctxt, URI, extData);
+ xsltFreeExtData(data);
+ return(NULL);
+ }
+ }
+ }
return (data->extData);
}
+typedef struct _xsltInitExtCtxt xsltInitExtCtxt;
+struct _xsltInitExtCtxt {
+ xsltTransformContextPtr ctxt;
+ int ret;
+};
+
+/**
+ * xsltInitCtxtExt:
+ * @styleData: the registered stylesheet data for the module
+ * @ctxt: the XSLT transformation context + the return value
+ * @URI: the extension URI
+ *
+ * Initializes an extension module
+ */
+static void
+xsltInitCtxtExt (xsltExtDataPtr styleData, xsltInitExtCtxt *ctxt,
+ const xmlChar *URI) {
+ xsltExtModulePtr module;
+ xsltExtDataPtr ctxtData;
+ void *extData;
+
+ if ((styleData == NULL) || (ctxt == NULL) || (URI == NULL) ||
+ (ctxt->ret == -1)) {
+#ifdef WITH_XSLT_DEBUG_EXTENSIONS
+ xsltGenericDebug(xsltGenericDebugContext,
+ "xsltInitCtxtExt: NULL param or error\n");
+#endif
+ return;
+ }
+ module = styleData->extModule;
+ if ((module == NULL) || (module->initFunc == NULL)) {
+#ifdef WITH_XSLT_DEBUG_EXTENSIONS
+ xsltGenericDebug(xsltGenericDebugContext,
+ "xsltInitCtxtExt: no module or no initFunc\n");
+#endif
+ return;
+ }
+
+ extData = module->initFunc(ctxt->ctxt, URI);
+ if (extData == NULL) {
+#ifdef WITH_XSLT_DEBUG_EXTENSIONS
+ xsltGenericDebug(xsltGenericDebugContext,
+ "xsltInitCtxtExt: no extData\n");
+#endif
+ return;
+ }
+ ctxtData = xsltNewExtData(module, extData);
+ if (ctxtData == NULL) {
+ ctxt->ret = -1;
+ return;
+ }
+
+ if (ctxt->ctxt->extInfos == NULL)
+ ctxt->ctxt->extInfos = xmlHashCreate(10);
+ if (ctxt->ctxt->extInfos == NULL) {
+ ctxt->ret = -1;
+ return;
+ }
+
+ if (xmlHashAddEntry(ctxt->ctxt->extInfos, URI, ctxtData) < 0) {
+ xsltGenericError(xsltGenericErrorContext,
+ "Failed to register module data: %s\n", URI);
+ if (module->shutdownFunc)
+ module->shutdownFunc(ctxt->ctxt, URI, extData);
+ xsltFreeExtData(ctxtData);
+ ctxt->ret = -1;
+ return;
+ }
+#ifdef WITH_XSLT_DEBUG_EXTENSIONS
+ xsltGenericDebug(xsltGenericDebugContext, "Registered module %s\n",
+ URI);
+#endif
+ ctxt->ret++;
+}
+
/**
* xsltInitCtxtExts:
* @ctxt: an XSLT transformation context
*
- * Initialize the set of modules associated to the extension prefixes
+ * Initialize the set of modules with registered stylesheet data
*
* Returns the number of modules initialized or -1 in case of error
*/
int
xsltInitCtxtExts(xsltTransformContextPtr ctxt)
{
- int ret = 0;
xsltStylesheetPtr style;
- xsltExtDefPtr def;
- xsltExtModulePtr module;
- xsltExtDataPtr data;
- void *extData;
+ xsltInitExtCtxt ctx;
if (ctxt == NULL)
return (-1);
@@ -376,71 +620,24 @@
style = ctxt->style;
if (style == NULL)
return (-1);
+
+ ctx.ctxt = ctxt;
+ ctx.ret = 0;
+
while (style != NULL) {
- def = (xsltExtDefPtr) style->nsDefs;
- while (def != NULL) {
- if (def->URI != NULL) {
- if (ctxt->extInfos == NULL) {
- ctxt->extInfos = xmlHashCreate(10);
- if (ctxt->extInfos == NULL)
- return (-1);
- data = NULL;
- } else {
- data =
- (xsltExtDataPtr) xmlHashLookup(ctxt->extInfos,
- def->URI);
- }
- if (data == NULL) {
- /*
- * Register this module
- */
- module = xmlHashLookup(xsltExtensionsHash, def->URI);
- if (module == NULL) {
-#ifdef WITH_XSLT_DEBUG_EXTENSIONS
- xsltGenericDebug(xsltGenericDebugContext,
- "Not registered extension module : %s\n",
- def->URI);
-#endif
- } else {
- if (module->initFunc != NULL) {
-#ifdef WITH_XSLT_DEBUG_EXTENSIONS
- xsltGenericDebug(xsltGenericDebugContext,
- "Initializing module : %s\n",
- def->URI);
-#endif
- extData = module->initFunc(ctxt, def->URI);
- } else {
- extData = NULL;
- }
- data = xsltNewExtData(module, extData);
- if (data == NULL)
- return (-1);
- if (xmlHashAddEntry(ctxt->extInfos, def->URI,
- (void *) data) < 0) {
- xsltPrintErrorContext(ctxt, NULL, NULL);
- xsltGenericError(xsltGenericErrorContext,
- "Failed to register module : %s\n",
- def->URI);
- } else {
- ret++;
-#ifdef WITH_XSLT_DEBUG_EXTENSIONS
- xsltGenericDebug(xsltGenericDebugContext,
- "Registered module : %s\n",
- def->URI);
-#endif
- }
-
- }
- }
- }
- def = def->next;
- }
+ if (style->extInfos != NULL) {
+ xmlHashScan(style->extInfos,
+ (xmlHashScanner) xsltInitCtxtExt, &ctx);
+ if (ctx.ret == -1)
+ return(-1);
+ }
style = xsltNextImport(style);
}
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
- xsltGenericDebug(xsltGenericDebugContext, "Registered %d modules\n", ret);
+ xsltGenericDebug(xsltGenericDebugContext, "Registered %d modules\n",
+ ctx.ret);
#endif
- return (ret);
+ return (ctx.ret);
}
/**
@@ -491,6 +688,53 @@
}
/**
+ * xsltShutdownExt:
+ * @data: the registered data for the module
+ * @ctxt: the XSLT stylesheet
+ * @URI: the extension URI
+ *
+ * Shutdown an extension module loaded
+ */
+static void
+xsltShutdownExt(xsltExtDataPtr data, xsltStylesheetPtr style,
+ const xmlChar * URI)
+{
+ xsltExtModulePtr module;
+
+ if ((data == NULL) || (style == NULL) || (URI == NULL))
+ return;
+ module = data->extModule;
+ if ((module == NULL) || (module->styleShutdownFunc == NULL))
+ return;
+
+#ifdef WITH_XSLT_DEBUG_EXTENSIONS
+ xsltGenericDebug(xsltGenericDebugContext,
+ "Shutting down module : %s\n", URI);
+#endif
+ module->styleShutdownFunc(style, URI, data->extData);
+ xmlHashRemoveEntry(style->extInfos, URI,
+ (xmlHashDeallocator) xsltFreeExtData);
+}
+
+/**
+ * xsltShutdownExts:
+ * @style: an XSLT stylesheet
+ *
+ * Shutdown the set of modules loaded
+ */
+void
+xsltShutdownExts(xsltStylesheetPtr style)
+{
+ if (style == NULL)
+ return;
+ if (style->extInfos == NULL)
+ return;
+ xmlHashScan(style->extInfos, (xmlHashScanner) xsltShutdownExt, style);
+ xmlHashFree(style->extInfos, (xmlHashDeallocator) xsltFreeExtData);
+ style->extInfos = NULL;
+}
+
+/**
* xsltCheckExtPrefix:
* @style: the stylesheet
* @prefix: the namespace prefix (possibly NULL)
@@ -516,19 +760,23 @@
}
/**
- * xsltRegisterExtModule:
+ * xsltRegisterExtModuleFull:
* @URI: URI associated to this module
* @initFunc: the module initialization function
* @shutdownFunc: the module shutdown function
+ * @styleInitFunc: the module initialization function
+ * @styleShutdownFunc: the module shutdown function
*
* Register an XSLT extension module to the library.
*
* Returns 0 if sucessful, -1 in case of error
*/
int
-xsltRegisterExtModule(const xmlChar * URI,
- xsltExtInitFunction initFunc,
- xsltExtShutdownFunction shutdownFunc)
+xsltRegisterExtModuleFull(const xmlChar * URI,
+ xsltExtInitFunction initFunc,
+ xsltExtShutdownFunction shutdownFunc,
+ xsltStyleExtInitFunction styleInitFunc,
+ xsltStyleExtShutdownFunction styleShutdownFunc)
{
int ret;
xsltExtModulePtr module;
@@ -548,7 +796,8 @@
return (0);
return (-1);
}
- module = xsltNewExtModule(initFunc, shutdownFunc);
+ module = xsltNewExtModule(initFunc, shutdownFunc,
+ styleInitFunc, styleShutdownFunc);
if (module == NULL)
return (-1);
ret = xmlHashAddEntry(xsltExtensionsHash, URI, (void *) module);
@@ -556,6 +805,24 @@
}
/**
+ * xsltRegisterExtModule:
+ * @URI: URI associated to this module
+ * @initFunc: the module initialization function
+ * @shutdownFunc: the module shutdown function
+ *
+ * Register an XSLT extension module to the library.
+ *
+ * Returns 0 if sucessful, -1 in case of error
+ */
+int
+xsltRegisterExtModule(const xmlChar * URI,
+ xsltExtInitFunction initFunc,
+ xsltExtShutdownFunction shutdownFunc) {
+ return xsltRegisterExtModuleFull(URI, initFunc, shutdownFunc,
+ NULL, NULL);
+}
+
+/**
* xsltUnregisterExtModule:
* @URI: URI associated to this module
*
@@ -614,4 +881,552 @@
return(ctxt->context->extra);
}
+/**
+ * xsltRegisterExtModuleFunction:
+ * @name: the function name
+ * @URI: the function namespace URI
+ * @function: the function callback
+ *
+ * Registers an extension module function.
+ *
+ * Returns 0 if successful, -1 in case of error.
+ */
+int
+xsltRegisterExtModuleFunction (const xmlChar *name, const xmlChar *URI,
+ xmlXPathFunction function) {
+ if ((name == NULL) || (URI == NULL) || (function == NULL))
+ return(-1);
+
+ if (xsltFunctionsHash == NULL)
+ xsltFunctionsHash = xmlHashCreate(10);
+ if (xsltFunctionsHash == NULL)
+ return(-1);
+
+ xmlHashUpdateEntry2(xsltFunctionsHash, name, URI,
+ (void *) function, NULL);
+
+ return(0);
+}
+
+/**
+ * xsltExtModuleFunctionLookup:
+ * @name: the function name
+ * @URI: the function namespace URI
+ *
+ * Looks up an extension module function
+ *
+ * Returns the function if found, NULL otherwise.
+ */
+xmlXPathFunction
+xsltExtModuleFunctionLookup (const xmlChar *name, const xmlChar *URI) {
+ if ((xsltFunctionsHash == NULL) || (name == NULL) || (URI == NULL))
+ return(NULL);
+
+ return (xmlXPathFunction) xmlHashLookup2(xsltFunctionsHash, name, URI);
+}
+
+/**
+ * xsltUnregisterExtModuleFunction:
+ * @name: the function name
+ * @URI: the function namespace URI
+ *
+ * Unregisters an extension module function
+ *
+ * Returns 0 if successful, -1 in case of error.
+ */
+int
+xsltUnregisterExtModuleFunction (const xmlChar *name,
+ const xmlChar *URI) {
+ if ((xsltFunctionsHash == NULL) || (name == NULL) || (URI == NULL))
+ return(-1);
+
+ return xmlHashRemoveEntry2 (xsltFunctionsHash, name, URI, NULL);
+}
+
+/**
+ * xsltRegisterExtModuleElement:
+ * @name: the element name
+ * @URI: the element namespace URI
+ * @precomp: the pre-computation callback
+ * @transform: the transformation callback
+ *
+ * Registers an extension module element.
+ *
+ * Returns 0 if successful, -1 in case of error.
+ */
+int
+xsltRegisterExtModuleElement (const xmlChar *name, const xmlChar *URI,
+ xsltPreComputeFunction precomp,
+ xsltTransformFunction transform) {
+ xsltExtElementPtr ext;
+
+ if ((name == NULL) || (URI == NULL) || (transform == NULL))
+ return(-1);
+
+ if (xsltElementsHash == NULL)
+ xsltElementsHash = xmlHashCreate(10);
+ if (xsltElementsHash == NULL)
+ return(-1);
+ ext = xsltNewExtElement(precomp, transform);
+ if (ext == NULL)
+ return(-1);
+
+ xmlHashUpdateEntry2(xsltElementsHash, name, URI, (void *) ext,
+ (xmlHashDeallocator) xsltFreeExtElement);
+
+ return(0);
+}
+
+/**
+ * xsltExtElementLookup:
+ * @ctxt: an XSLT process context
+ * @name: the element name
+ * @URI: the element namespace URI
+ *
+ * Looks up an extension element. @ctxt can be NULL to search only in
+ * module elements.
+ *
+ * Returns the element callback or NULL if not found
+ */
+xsltTransformFunction
+xsltExtElementLookup (xsltTransformContextPtr ctxt,
+ const xmlChar *name, const xmlChar *URI) {
+ xsltTransformFunction ret;
+
+ if ((name == NULL) || (URI == NULL))
+ return(NULL);
+
+ if ((ctxt != NULL) && (ctxt->extElements != NULL)) {
+ ret = (xsltTransformFunction)
+ xmlHashLookup2(ctxt->extElements, name, URI);
+ if (ret != NULL)
+ return(ret);
+ }
+ return xsltExtModuleElementLookup(name, URI);
+}
+
+/**
+ * xsltExtModuleElementLookup:
+ * @name: the element name
+ * @URI: the element namespace URI
+ *
+ * Looks up an extension module element
+ *
+ * Returns the callback function if found, NULL otherwise.
+ */
+xsltTransformFunction
+xsltExtModuleElementLookup (const xmlChar *name, const xmlChar *URI) {
+ xsltExtElementPtr ext;
+
+ if ((xsltElementsHash == NULL) || (name == NULL) || (URI == NULL))
+ return(NULL);
+
+ ext = (xsltExtElementPtr) xmlHashLookup2(xsltElementsHash, name, URI);
+
+ if (ext == NULL)
+ return(NULL);
+ return(ext->transform);
+}
+
+/**
+ * xsltExtModuleElementPreComputeLookup:
+ * @name: the element name
+ * @URI: the element namespace URI
+ *
+ * Looks up an extension module element pre-computation function
+ *
+ * Returns the callback function if found, NULL otherwise.
+ */
+xsltPreComputeFunction
+xsltExtModuleElementPreComputeLookup (const xmlChar *name,
+ const xmlChar *URI) {
+ xsltExtElementPtr ext;
+
+ if ((xsltElementsHash == NULL) || (name == NULL) || (URI == NULL))
+ return(NULL);
+
+ ext = (xsltExtElementPtr) xmlHashLookup2(xsltElementsHash, name, URI);
+
+ if (ext == NULL)
+ return(NULL);
+ return(ext->precomp);
+}
+
+/**
+ * xsltUnregisterExtModuleElement:
+ * @name: the element name
+ * @URI: the element namespace URI
+ *
+ * Unregisters an extension module element
+ *
+ * Returns 0 if successful, -1 in case of error.
+ */
+int
+xsltUnregisterExtModuleElement (const xmlChar *name,
+ const xmlChar *URI) {
+ if ((xsltElementsHash == NULL) || (name == NULL) || (URI == NULL))
+ return(-1);
+
+ return xmlHashRemoveEntry2 (xsltElementsHash, name, URI,
+ (xmlHashDeallocator) xsltFreeExtElement);
+}
+
+/**
+ * xsltRegisterExtModuleTopLevel:
+ * @name: the top-level element name
+ * @URI: the top-level element namespace URI
+ * @function: the top-level element callback
+ *
+ * Registers an extension module top-level element.
+ *
+ * Returns 0 if successful, -1 in case of error.
+ */
+int
+xsltRegisterExtModuleTopLevel (const xmlChar *name, const xmlChar *URI,
+ xsltPreComputeFunction function) {
+ if ((name == NULL) || (URI == NULL) || (function == NULL))
+ return(-1);
+
+ if (xsltTopLevelsHash == NULL)
+ xsltTopLevelsHash = xmlHashCreate(10);
+ if (xsltTopLevelsHash == NULL)
+ return(-1);
+
+ xmlHashUpdateEntry2(xsltTopLevelsHash, name, URI,
+ (void *) function, NULL);
+
+ return(0);
+}
+
+/**
+ * xsltExtModuleTopLevelLookup:
+ * @name: the top-level element name
+ * @URI: the top-level element namespace URI
+ *
+ * Looks up an extension module top-level element
+ *
+ * Returns the callback function if found, NULL otherwise.
+ */
+xsltPreComputeFunction
+xsltExtModuleTopLevelLookup (const xmlChar *name, const xmlChar *URI) {
+ if ((xsltTopLevelsHash == NULL) || (name == NULL) || (URI == NULL))
+ return(NULL);
+
+ return xmlHashLookup2(xsltTopLevelsHash, name, URI);
+}
+
+/**
+ * xsltUnregisterExtModuleTopLevel:
+ * @name: the top-level element name
+ * @URI: the top-level element namespace URI
+ *
+ * Unregisters an extension module top-level element
+ *
+ * Returns 0 if successful, -1 in case of error.
+ */
+int
+xsltUnregisterExtModuleTopLevel (const xmlChar *name,
+ const xmlChar *URI) {
+ if ((xsltTopLevelsHash == NULL) || (name == NULL) || (URI == NULL))
+ return(-1);
+
+ return xmlHashRemoveEntry2 (xsltTopLevelsHash, name, URI, NULL);
+}
+
+
+/************************************************************************
+ * *
+ * Test module http://xmlsoft.org/XSLT/ *
+ * *
+ ************************************************************************/
+
+/************************************************************************
+ * *
+ * Test of the extension module API *
+ * *
+ ************************************************************************/
+
+static xmlChar *testData = NULL;
+static xmlChar *testStyleData = NULL;
+
+/**
+ * xsltExtFunctionTest:
+ * @ctxt: the XPath Parser context
+ * @nargs: the number of arguments
+ *
+ * function libxslt:test() for testing the extensions support.
+ */
+static void
+xsltExtFunctionTest(xmlXPathParserContextPtr ctxt, int nargs)
+{
+ xsltTransformContextPtr tctxt;
+ void *data;
+
+ tctxt = xsltXPathGetTransformContext(ctxt);
+
+ if (testData == NULL) {
+ xsltGenericDebug(xsltGenericDebugContext,
+ "xsltExtFunctionTest: not initialized,"
+ " calling xsltGetExtData\n");
+ data = xsltGetExtData(tctxt, (const xmlChar *) XSLT_DEFAULT_URL);
+ if (data == NULL) {
+ xsltPrintErrorContext(tctxt, NULL, NULL);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtElementTest: not initialized\n");
+ return;
+ }
+ }
+ if (tctxt == NULL) {
+ xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtFunctionTest: failed to get the transformation context\n");
+ return;
+ }
+ if (data == NULL)
+ data = xsltGetExtData(tctxt, (const xmlChar *) XSLT_DEFAULT_URL);
+ if (data == NULL) {
+ xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtFunctionTest: failed to get module data\n");
+ return;
+ }
+ if (data != testData) {
+ xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtFunctionTest: got wrong module data\n");
+ return;
+ }
+#ifdef WITH_XSLT_DEBUG_FUNCTION
+ xsltGenericDebug(xsltGenericDebugContext,
+ "libxslt:test() called with %d args\n", nargs);
+#endif
+}
+
+/**
+ * xsltExtElementPreCompTest:
+ * @style: the stylesheet
+ * @inst: the instruction in the stylesheet
+ *
+ * Process a libxslt:test node
+ */
+static void
+xsltExtElementPreCompTest(xsltStylesheetPtr style, xmlNodePtr inst) {
+ if (style == NULL) {
+ xsltPrintErrorContext(NULL, NULL, inst);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtElementTest: no transformation context\n");
+ return;
+ }
+ if (testStyleData == NULL) {
+ xsltGenericDebug(xsltGenericDebugContext,
+ "xsltExtElementPreCompTest: not initialized,"
+ " calling xsltStyleGetExtData\n");
+ xsltStyleGetExtData(style, (const xmlChar *) XSLT_DEFAULT_URL);
+ if (testStyleData == NULL) {
+ xsltPrintErrorContext(NULL, NULL, inst);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtElementPreCompTest: not initialized\n");
+ style->errors++;
+ return;
+ }
+ }
+ if (inst == NULL) {
+ xsltPrintErrorContext(NULL, NULL, inst);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtElementPreCompTest: no instruction\n");
+ style->errors++;
+ return;
+ }
+}
+
+/**
+ * xsltExtElementTest:
+ * @ctxt: an XSLT processing context
+ * @node: The current node
+ * @inst: the instruction in the stylesheet
+ * @comp: precomputed informations
+ *
+ * Process a libxslt:test node
+ */
+static void
+xsltExtElementTest(xsltTransformContextPtr ctxt, xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp ATTRIBUTE_UNUSED)
+{
+ xmlNodePtr comment;
+
+ if (testData == NULL) {
+ xsltGenericDebug(xsltGenericDebugContext,
+ "xsltExtElementTest: not initialized,"
+ " calling xsltGetExtData\n");
+ xsltGetExtData(ctxt, (const xmlChar *) XSLT_DEFAULT_URL);
+ if (testData == NULL) {
+ xsltPrintErrorContext(ctxt, NULL, inst);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtElementTest: not initialized\n");
+ return;
+ }
+ }
+ if (ctxt == NULL) {
+ xsltPrintErrorContext(ctxt, NULL, inst);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtElementTest: no transformation context\n");
+ return;
+ }
+ if (node == NULL) {
+ xsltPrintErrorContext(ctxt, NULL, inst);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtElementTest: no current node\n");
+ return;
+ }
+ if (inst == NULL) {
+ xsltPrintErrorContext(ctxt, NULL, inst);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtElementTest: no instruction\n");
+ return;
+ }
+ if (ctxt->insert == NULL) {
+ xsltPrintErrorContext(ctxt, NULL, inst);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtElementTest: no insertion point\n");
+ return;
+ }
+ comment =
+ xmlNewComment((const xmlChar *)
+ "libxslt:test element test worked");
+ xmlAddChild(ctxt->insert, comment);
+}
+
+/**
+ * xsltExtInitTest:
+ * @ctxt: an XSLT transformation context
+ * @URI: the namespace URI for the extension
+ *
+ * A function called at initialization time of an XSLT extension module
+ *
+ * Returns a pointer to the module specific data for this transformation
+ */
+static void *
+xsltExtInitTest(xsltTransformContextPtr ctxt, const xmlChar * URI) {
+ if (testStyleData == NULL) {
+ xsltGenericDebug(xsltGenericErrorContext,
+ "xsltExtInitTest: not initialized,"
+ " calling xsltStyleGetExtData\n");
+ xsltStyleGetExtData(ctxt->style, URI);
+ if (testStyleData == NULL) {
+ xsltPrintErrorContext(ctxt, NULL, NULL);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtInitTest: not initialized\n");
+ return (NULL);
+ }
+ }
+ if (testData != NULL) {
+ xsltPrintErrorContext(ctxt, NULL, NULL);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtInitTest: already initialized\n");
+ return (NULL);
+ }
+ testData = (void *) "test data";
+ xsltGenericDebug(xsltGenericDebugContext,
+ "Registered test module : %s\n", URI);
+ return (testData);
+}
+
+
+/**
+ * xsltExtShutdownTest:
+ * @ctxt: an XSLT transformation context
+ * @URI: the namespace URI for the extension
+ * @data: the data associated to this module
+ *
+ * A function called at shutdown time of an XSLT extension module
+ */
+static void
+xsltExtShutdownTest(xsltTransformContextPtr ctxt,
+ const xmlChar * URI, void *data) {
+ if (testData == NULL) {
+ xsltPrintErrorContext(ctxt, NULL, NULL);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtShutdownTest: not initialized\n");
+ return;
+ }
+ if (data != testData) {
+ xsltPrintErrorContext(ctxt, NULL, NULL);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtShutdownTest: wrong data\n");
+ }
+ testData = NULL;
+ xsltGenericDebug(xsltGenericDebugContext,
+ "Unregistered test module : %s\n", URI);
+}
+/**
+ * xsltExtStyleInitTest:
+ * @style: an XSLT stylesheet
+ * @URI: the namespace URI for the extension
+ *
+ * A function called at initialization time of an XSLT extension module
+ *
+ * Returns a pointer to the module specific data for this transformation
+ */
+static void *
+xsltExtStyleInitTest(xsltStylesheetPtr style, const xmlChar * URI)
+{
+ if (testStyleData != NULL) {
+ xsltPrintErrorContext(NULL, NULL, NULL);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtInitTest: already initialized\n");
+ return (NULL);
+ }
+ testStyleData = (void *) "test data";
+ xsltGenericDebug(xsltGenericDebugContext,
+ "Registered test module : %s\n", URI);
+ return (testStyleData);
+}
+
+
+/**
+ * xsltExtStyleShutdownTest:
+ * @style: an XSLT stylesheet
+ * @URI: the namespace URI for the extension
+ * @data: the data associated to this module
+ *
+ * A function called at shutdown time of an XSLT extension module
+ */
+static void
+xsltExtStyleShutdownTest(xsltStylesheetPtr style,
+ const xmlChar * URI, void *data) {
+ if (testStyleData == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtShutdownTest: not initialized\n");
+ return;
+ }
+ if (data != testStyleData) {
+ xsltPrintErrorContext(NULL, NULL, NULL);
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtShutdownTest: wrong data\n");
+ }
+ testStyleData = NULL;
+ xsltGenericDebug(xsltGenericDebugContext,
+ "Unregistered test module : %s\n", URI);
+}
+
+/**
+ * xsltRegisterTestModule:
+ *
+ * Registers the test module
+ */
+void
+xsltRegisterTestModule (void) {
+ xsltRegisterExtModuleFull((const xmlChar *) XSLT_DEFAULT_URL,
+ xsltExtInitTest, xsltExtShutdownTest,
+ xsltExtStyleInitTest,
+ xsltExtStyleShutdownTest);
+ xsltRegisterExtModuleFunction((const xmlChar *) "test",
+ (const xmlChar *) XSLT_DEFAULT_URL,
+ xsltExtFunctionTest);
+ xsltRegisterExtModuleElement((const xmlChar *) "test",
+ (const xmlChar *) XSLT_DEFAULT_URL,
+ xsltExtElementPreCompTest ,
+ xsltExtElementTest);
+}
Index: libxslt/extensions.h
===================================================================
RCS file: /cvs/gnome/libxslt/libxslt/extensions.h,v
retrieving revision 1.6
diff -u -r1.6 extensions.h
--- libxslt/extensions.h 2001/07/04 13:22:39 1.6
+++ libxslt/extensions.h 2001/07/25 14:54:35
@@ -21,6 +21,30 @@
*/
/**
+ * xsltStyleExtInitFunction:
+ * @ctxt: an XSLT stylesheet
+ * @URI: the namespace URI for the extension
+ *
+ * A function called at initialization time of an XSLT extension module
+ *
+ * Returns a pointer to the module specific data for this transformation
+ */
+typedef void * (*xsltStyleExtInitFunction) (xsltStylesheetPtr style,
+ const xmlChar *URI);
+
+/**
+ * xsltStyleExtShutdownFunction:
+ * @ctxt: an XSLT stylesheet
+ * @URI: the namespace URI for the extension
+ * @data: the data associated to this module
+ *
+ * A function called at shutdown time of an XSLT extension module
+ */
+typedef void (*xsltStyleExtShutdownFunction) (xsltStylesheetPtr style,
+ const xmlChar *URI,
+ void *data);
+
+/**
* xsltExtInitFunction:
* @ctxt: an XSLT transformation context
* @URI: the namespace URI for the extension
@@ -47,6 +71,12 @@
int xsltRegisterExtModule (const xmlChar *URI,
xsltExtInitFunction initFunc,
xsltExtShutdownFunction shutdownFunc);
+int xsltRegisterExtModuleFull
+ (const xmlChar * URI,
+ xsltExtInitFunction initFunc,
+ xsltExtShutdownFunction shutdownFunc,
+ xsltStyleExtInitFunction styleInitFunc,
+ xsltStyleExtShutdownFunction styleShutdownFunc);
int xsltUnregisterExtModule (const xmlChar * URI);
@@ -55,16 +85,76 @@
void * xsltGetExtData (xsltTransformContextPtr ctxt,
const xmlChar *URI);
+void * xsltStyleGetExtData (xsltStylesheetPtr style,
+ const xmlChar *URI);
+
void xsltShutdownCtxtExts (xsltTransformContextPtr ctxt);
+void xsltShutdownExts (xsltStylesheetPtr style);
+
xsltTransformContextPtr
xsltXPathGetTransformContext
(xmlXPathParserContextPtr ctxt);
+/*
+ * extension functions
+*/
+int xsltRegisterExtModuleFunction (const xmlChar *name,
+ const xmlChar *URI,
+ xmlXPathFunction function);
+xmlXPathFunction
+ xsltExtFunctionLookup (xsltTransformContextPtr ctxt,
+ const xmlChar *name,
+ const xmlChar *URI);
+xmlXPathFunction
+ xsltExtModuleFunctionLookup (const xmlChar *name,
+ const xmlChar *URI);
+int xsltUnregisterExtModuleFunction (const xmlChar *name,
+ const xmlChar *URI);
+
+/*
+ * extension elements
+ */
+typedef void
+ (*xsltPreComputeFunction) (xsltStylesheetPtr ctxt,
+ xmlNodePtr inst);
+
+int xsltRegisterExtModuleElement (const xmlChar *name,
+ const xmlChar *URI,
+ xsltPreComputeFunction precomp,
+ xsltTransformFunction transform);
+xsltTransformFunction
+ xsltExtElementLookup (xsltTransformContextPtr ctxt,
+ const xmlChar *name,
+ const xmlChar *URI);
+xsltTransformFunction
+ xsltExtModuleElementLookup (const xmlChar *name,
+ const xmlChar *URI);
+xsltPreComputeFunction
+ xsltExtModuleElementPreComputeLookup
+ (const xmlChar *name,
+ const xmlChar *URI);
+int xsltUnregisterExtModuleElement (const xmlChar *name,
+ const xmlChar *URI);
+
+/*
+ * top-level elements
+ */
+int xsltRegisterExtModuleTopLevel (const xmlChar *name,
+ const xmlChar *URI,
+ xsltPreComputeFunction function);
+xsltPreComputeFunction
+ xsltExtModuleTopLevelLookup (const xmlChar *name,
+ const xmlChar *URI);
+int xsltUnregisterExtModuleTopLevel (const xmlChar *name,
+ const xmlChar *URI);
+
+
+/* These 2 functions are deprecated for use within modules */
int xsltRegisterExtFunction (xsltTransformContextPtr ctxt,
const xmlChar *name,
const xmlChar *URI,
- xmlXPathEvalFunc function);
+ xmlXPathFunction function);
int xsltRegisterExtElement (xsltTransformContextPtr ctxt,
const xmlChar *name,
const xmlChar *URI,
@@ -84,6 +174,11 @@
void xsltFreeCtxtExts (xsltTransformContextPtr ctxt);
void xsltFreeExts (xsltStylesheetPtr style);
+
+/**
+ * Test module http://xmlsoft.org/XSLT/
+ */
+void xsltRegisterTestModule (void);
#ifdef __cplusplus
}
Index: libxslt/functions.c
===================================================================
RCS file: /cvs/gnome/libxslt/libxslt/functions.c,v
retrieving revision 1.34
diff -u -r1.34 functions.c
--- libxslt/functions.c 2001/07/23 00:55:43 1.34
+++ libxslt/functions.c 2001/07/25 14:54:36
@@ -51,6 +51,41 @@
*/
#define DOCBOOK_XSL_HACK
+/**
+ * xsltXPathFunctionLookup:
+ * @ctxt: a void * but the XSLT transformation context actually
+ * @name: the function name
+ * @ns_uri: the function namespace URI
+ *
+ * This is the entry point when a function is needed by the XPath
+ * interpretor.
+ *
+ * Returns the callback function or NULL if not found
+ */
+xmlXPathFunction
+xsltXPathFunctionLookup (void *ctxt ATTRIBUTE_UNUSED,
+ const xmlChar *name, const xmlChar *ns_uri) {
+ xmlXPathFunction ret;
+
+ if ((name == NULL) || (ns_uri == NULL))
+ return (NULL);
+
+#ifdef WITH_XSLT_DEBUG_FUNCTION
+ xsltGenericDebug(xsltGenericDebugContext,
+ "Lookup function {%s}%s\n", ns_uri, name);
+#endif
+
+ ret = xsltExtModuleFunctionLookup(name, ns_uri);
+
+#ifdef WITH_XSLT_DEBUG_FUNCTION
+ if (ret != NULL)
+ xsltGenericDebug(xsltGenericDebugContext,
+ "found function %s\n", name);
+#endif
+ return(ret);
+}
+
+
/************************************************************************
* *
* Module interfaces *
@@ -625,7 +660,11 @@
name = xmlSplitQName2(obj->stringval, &prefix);
if (name == NULL) {
+ xmlNsPtr ns;
+
name = xmlStrdup(obj->stringval);
+ ns = xmlSearchNs(tctxt->inst->doc, tctxt->inst, NULL);
+ nsURI = xmlStrdup(ns->href);
} else {
nsURI = xmlXPathNsLookup(ctxt->context, prefix);
if (nsURI == NULL) {
@@ -636,7 +675,7 @@
}
}
- if (xmlHashLookup2(tctxt->extElements, name, nsURI) != NULL) {
+ if (xsltExtElementLookup(tctxt, name, nsURI) != NULL) {
valuePush(ctxt, xmlXPathNewBoolean(1));
} else {
valuePush(ctxt, xmlXPathNewBoolean(0));
@@ -737,171 +776,6 @@
/************************************************************************
* *
- * Test of the extension module API *
- * *
- ************************************************************************/
-
-static xmlChar *testData = NULL;
-
-/**
- * xsltExtFunctionTest:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * function libxslt:test() for testing the extensions support.
- */
-static void
-xsltExtFunctionTest(xmlXPathParserContextPtr ctxt, int nargs)
-{
- xsltTransformContextPtr tctxt;
- void *data;
-
- if (testData == NULL) {
- xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL);
- xsltGenericError(xsltGenericErrorContext,
- "xsltExtFunctionTest: not initialized\n");
- return;
- }
- tctxt = xsltXPathGetTransformContext(ctxt);
- if (tctxt == NULL) {
- xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL);
- xsltGenericError(xsltGenericErrorContext,
- "xsltExtFunctionTest: failed to get the transformation context\n");
- return;
- }
- data = xsltGetExtData(tctxt, (const xmlChar *) XSLT_DEFAULT_URL);
- if (data == NULL) {
- xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL);
- xsltGenericError(xsltGenericErrorContext,
- "xsltExtFunctionTest: failed to get module data\n");
- return;
- }
- if (data != testData) {
- xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL);
- xsltGenericError(xsltGenericErrorContext,
- "xsltExtFunctionTest: got wrong module data\n");
- return;
- }
-#ifdef WITH_XSLT_DEBUG_FUNCTION
- xsltGenericDebug(xsltGenericDebugContext,
- "libxslt:test() called with %d args\n", nargs);
-#endif
-}
-
-/**
- * xsltExtElementTest:
- * @ctxt: an XSLT processing context
- * @node: The current node
- * @inst: the instruction in the stylesheet
- * @comp: precomputed informations
- *
- * Process a libxslt:test node
- */
-static void
-xsltExtElementTest(xsltTransformContextPtr ctxt, xmlNodePtr node,
- xmlNodePtr inst,
- xsltStylePreCompPtr comp ATTRIBUTE_UNUSED)
-{
- xmlNodePtr comment;
-
- if (testData == NULL) {
- xsltPrintErrorContext(ctxt, NULL, inst);
- xsltGenericError(xsltGenericErrorContext,
- "xsltExtElementTest: not initialized\n");
- return;
- }
- if (ctxt == NULL) {
- xsltPrintErrorContext(ctxt, NULL, inst);
- xsltGenericError(xsltGenericErrorContext,
- "xsltExtElementTest: no transformation context\n");
- return;
- }
- if (node == NULL) {
- xsltPrintErrorContext(ctxt, NULL, inst);
- xsltGenericError(xsltGenericErrorContext,
- "xsltExtElementTest: no current node\n");
- return;
- }
- if (inst == NULL) {
- xsltPrintErrorContext(ctxt, NULL, inst);
- xsltGenericError(xsltGenericErrorContext,
- "xsltExtElementTest: no instruction\n");
- return;
- }
- if (ctxt->insert == NULL) {
- xsltPrintErrorContext(ctxt, NULL, inst);
- xsltGenericError(xsltGenericErrorContext,
- "xsltExtElementTest: no insertion point\n");
- return;
- }
- comment =
- xmlNewComment((const xmlChar *)
- "libxslt:test element test worked");
- xmlAddChild(ctxt->insert, comment);
-}
-
-/**
- * xsltExtInitTest:
- * @ctxt: an XSLT transformation context
- * @URI: the namespace URI for the extension
- *
- * A function called at initialization time of an XSLT extension module
- *
- * Returns a pointer to the module specific data for this transformation
- */
-static void *
-xsltExtInitTest(xsltTransformContextPtr ctxt, const xmlChar * URI)
-{
- if (testData != NULL) {
- xsltPrintErrorContext(ctxt, NULL, NULL);
- xsltGenericError(xsltGenericErrorContext,
- "xsltExtInitTest: already initialized\n");
- return (NULL);
- }
- testData = (void *) "test data";
- xsltRegisterExtFunction(ctxt, (const xmlChar *) "test",
- (const xmlChar *) XSLT_DEFAULT_URL,
- xsltExtFunctionTest);
- xsltRegisterExtElement(ctxt, (const xmlChar *) "test",
- (const xmlChar *) XSLT_DEFAULT_URL,
- xsltExtElementTest);
-
- xsltGenericDebug(xsltGenericDebugContext,
- "Registered test module : %s\n", URI);
- return (testData);
-}
-
-
-/**
- * xsltExtShutdownTest:
- * @ctxt: an XSLT transformation context
- * @URI: the namespace URI for the extension
- * @data: the data associated to this module
- *
- * A function called at shutdown time of an XSLT extension module
- */
-static void
-xsltExtShutdownTest(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
- const xmlChar * URI, void *data)
-{
- if (testData == NULL) {
- xsltPrintErrorContext(ctxt, NULL, NULL);
- xsltGenericError(xsltGenericErrorContext,
- "xsltExtShutdownTest: not initialized\n");
- return;
- }
- if (data != testData) {
- xsltPrintErrorContext(ctxt, NULL, NULL);
- xsltGenericError(xsltGenericErrorContext,
- "xsltExtShutdownTest: wrong data\n");
- }
- testData = NULL;
- xsltGenericDebug(xsltGenericDebugContext,
- "Unregistered test module : %s\n", URI);
-}
-
-/************************************************************************
- * *
* Registration of XSLT and libxslt functions *
* *
************************************************************************/
@@ -932,8 +806,4 @@
xsltElementAvailableFunction);
xmlXPathRegisterFunc(ctxt, (const xmlChar *) "function-available",
xsltFunctionAvailableFunction);
-
- xsltRegisterExtModule((const xmlChar *) XSLT_DEFAULT_URL,
- xsltExtInitTest,
- xsltExtShutdownTest);
}
Index: libxslt/functions.h
===================================================================
RCS file: /cvs/gnome/libxslt/libxslt/functions.h,v
retrieving revision 1.5
diff -u -r1.5 functions.h
--- libxslt/functions.h 2001/06/28 14:23:39 1.5
+++ libxslt/functions.h 2001/07/25 14:54:36
@@ -18,6 +18,19 @@
extern "C" {
#endif
+/**
+ * XSLT_REGISTER_FUNCTION_LOOKUP:
+ *
+ * registering macro, not general purpose at all but used in different modules
+ */
+#define XSLT_REGISTER_FUNCTION_LOOKUP(ctxt) \
+ xmlXPathRegisterFuncLookup((ctxt)->xpathCtxt, \
+ xsltXPathFunctionLookup, (void *)(ctxt));
+
+xmlXPathFunction
+ xsltXPathFunctionLookup (void *ctxt, const xmlChar *name,
+ const xmlChar *ns_uri);
+
/*
* Interfaces for the functions implementations
*/
Index: libxslt/preproc.c
===================================================================
RCS file: /cvs/gnome/libxslt/libxslt/preproc.c,v
retrieving revision 1.26
diff -u -r1.26 preproc.c
--- libxslt/preproc.c 2001/07/14 20:01:17 1.26
+++ libxslt/preproc.c 2001/07/25 14:54:36
@@ -36,6 +36,7 @@
#include "preproc.h"
#include "extra.h"
#include "imports.h"
+#include "extensions.h"
#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_PREPROC
@@ -1343,6 +1344,15 @@
if (IS_XSLT_NAME(inst, "document")) {
xsltDocumentComp(style, inst);
} else {
+ xsltPreComputeFunction function;
+ /*
+ * Precompute the element
+ */
+ function =
+ xsltExtModuleElementPreComputeLookup(inst->name,
+ inst->ns->href);
+ if (function != NULL)
+ function(style, inst);
/*
* Mark the element for later recognition.
*/
Index: libxslt/transform.c
===================================================================
RCS file: /cvs/gnome/libxslt/libxslt/transform.c,v
retrieving revision 1.129
diff -u -r1.129 transform.c
--- libxslt/transform.c 2001/07/12 01:32:04 1.129
+++ libxslt/transform.c 2001/07/25 14:54:37
@@ -232,6 +232,7 @@
cur->xpathCtxt->proximityPosition = 0;
cur->xpathCtxt->contextSize = 0;
XSLT_REGISTER_VARIABLE_LOOKUP(cur);
+ XSLT_REGISTER_FUNCTION_LOOKUP(cur);
cur->xpathCtxt->nsHash = style->nsHash;
docu = xsltNewDocument(cur, doc);
if (docu == NULL) {
@@ -631,7 +632,7 @@
************************************************************************/
void xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node,
- xsltStackElemPtr params);
+ xsltStackElemPtr params);
/**
* xsltDefaultProcessOneNode:
* @ctxt: a XSLT process context
@@ -1128,8 +1129,7 @@
* Flagged as an extension element
*/
function = (xsltTransformFunction)
- xmlHashLookup2(ctxt->extElements, cur->name,
- cur->ns->href);
+ xsltExtElementLookup(ctxt, cur->name, cur->ns->href);
if (function == NULL) {
xmlNodePtr child;
int found = 0;
Index: libxslt/transform.h
===================================================================
RCS file: /cvs/gnome/libxslt/libxslt/transform.h,v
retrieving revision 1.15
diff -u -r1.15 transform.h
--- libxslt/transform.h 2001/07/08 20:21:05 1.15
+++ libxslt/transform.h 2001/07/25 14:54:37
@@ -26,6 +26,11 @@
/**
* Private Interfaces
*/
+xsltTransformFunction
+ xsltExtElementLookup (xsltTransformContextPtr ctxt,
+ const xmlChar *name,
+ const xmlChar *URI);
+
xmlDocPtr xsltApplyStylesheet (xsltStylesheetPtr style,
xmlDocPtr doc,
const char **params);
Index: libxslt/variables.c
===================================================================
RCS file: /cvs/gnome/libxslt/libxslt/variables.c,v
retrieving revision 1.46
diff -u -r1.46 variables.c
--- libxslt/variables.c 2001/07/12 01:32:04 1.46
+++ libxslt/variables.c 2001/07/25 14:54:38
@@ -358,7 +358,7 @@
xmlNodePtr oldInsert;
container = xmlNewDocNode(ctxt->output, NULL,
- (const xmlChar *) "fake", NULL);
+ (const xmlChar *) "fake", NULL);
if (container == NULL)
return(NULL);
@@ -472,7 +472,7 @@
xmlNodePtr oldInsert;
container = xmlNewDocNode(ctxt->output, NULL,
- (const xmlChar *) "fake", NULL);
+ (const xmlChar *) "fake", NULL);
if (container == NULL)
return(NULL);
Index: libxslt/xslt.c
===================================================================
RCS file: /cvs/gnome/libxslt/libxslt/xslt.c,v
retrieving revision 1.62
diff -u -r1.62 xslt.c
--- libxslt/xslt.c 2001/07/12 01:32:04 1.62
+++ libxslt/xslt.c 2001/07/25 14:54:39
@@ -328,6 +328,7 @@
cur->exclPrefixNr = 0;
cur->exclPrefixMax = 0;
cur->exclPrefixTab = NULL;
+ cur->extInfos = NULL;
return(cur);
}
@@ -369,6 +370,7 @@
xsltFreeNamespaceAliasHashes(sheet);
xsltFreeStyleDocuments(sheet);
xsltFreeStylePreComps(sheet);
+ xsltShutdownExts(sheet);
if (sheet->doc != NULL)
xmlFreeDoc(sheet->doc);
if (sheet->variables != NULL)
@@ -1247,24 +1249,21 @@
/**
* xsltParseTemplateContent:
* @style: the XSLT stylesheet
- * @ret: the "template" structure
* @template: the container node (can be a document for literal results)
*
- * parse an XSLT template element content
+ * parse a template content-model
* Clean-up the template content from unwanted ignorable blank nodes
* and process xslt:text
*/
-static void
-xsltParseTemplateContent(xsltStylesheetPtr style, xsltTemplatePtr ret,
- xmlNodePtr template) {
+void
+xsltParseTemplateContent(xsltStylesheetPtr style, xmlNodePtr template) {
xmlNodePtr cur, delete;
/*
* This content comes from the stylesheet
* For stylesheets, the set of whitespace-preserving
* element names consists of just xsl:text.
*/
- ret->elem = template;
cur = template->children;
delete = NULL;
while (cur != NULL) {
@@ -1412,8 +1411,6 @@
break;
cur = cur->next;
}
-
- ret->content = template->children;
}
/**
@@ -1599,7 +1596,9 @@
/*
* parse the content and register the pattern
*/
- xsltParseTemplateContent(style, ret, template);
+ xsltParseTemplateContent(style, template);
+ ret->elem = template;
+ ret->content = template->children;
xsltAddTemplate(style, ret, mode, modeURI);
error:
@@ -1652,28 +1651,44 @@
cur = top->children;
+ /*
+ * process xsl:import elements
+ */
while (cur != NULL) {
if (IS_BLANK_NODE(cur)) {
cur = cur->next;
continue;
- }
- if (!(IS_XSLT_ELEM(cur))) {
-#ifdef WITH_XSLT_DEBUG_PARSING
- xsltGenericDebug(xsltGenericDebugContext,
- "xsltParseStylesheetTop : found foreign element %s\n",
- cur->name);
-#endif
- cur = cur->next;
- continue;
}
- if (IS_XSLT_NAME(cur, "import")) {
+ if (IS_XSLT_ELEM(cur) && IS_XSLT_NAME(cur, "import")) {
xsltParseStylesheetImport(style, cur);
} else
break;
cur = cur->next;
}
+ /*
+ * process other top-level elements
+ */
while (cur != NULL) {
+ if (IS_BLANK_NODE(cur)) {
+ cur = cur->next;
+ continue;
+ }
+ if ((cur->type == XML_ELEMENT_NODE) && (cur->ns == NULL)) {
+ xsltGenericError(xsltGenericErrorContext,
+ "Found a top-level element %s with null namespace URI\n",
+ cur->name);
+ style->errors++;
+ cur = cur->next;
+ continue;
+ }
if (!(IS_XSLT_ELEM(cur))) {
+ xsltPreComputeFunction function;
+
+ function = xsltExtModuleTopLevelLookup(cur->name,
+ cur->ns->href);
+ if (function != NULL)
+ function(style, cur);
+
#ifdef WITH_XSLT_DEBUG_PARSING
xsltGenericDebug(xsltGenericDebugContext,
"xsltParseStylesheetTop : found foreign element %s\n",
@@ -1819,7 +1834,9 @@
/*
* parse the content and register the pattern
*/
- xsltParseTemplateContent(ret, template, (xmlNodePtr) doc);
+ xsltParseTemplateContent(ret, (xmlNodePtr) doc);
+ template->elem = (xmlNodePtr) doc;
+ template->content = doc->children;
xsltAddTemplate(ret, template, NULL, NULL);
}
Index: libxslt/xsltInternals.h
===================================================================
RCS file: /cvs/gnome/libxslt/libxslt/xsltInternals.h,v
retrieving revision 1.57
diff -u -r1.57 xsltInternals.h
--- libxslt/xsltInternals.h 2001/07/23 00:55:43 1.57
+++ libxslt/xsltInternals.h 2001/07/25 14:54:39
@@ -323,6 +323,11 @@
int exclPrefixMax; /* size of the array */
void *_private; /* user defined data */
+
+ /*
+ * Extensions
+ */
+ xmlHashTablePtr extInfos; /* the extension data */
};
/*
Index: libxslt/xsltutils.c
===================================================================
RCS file: /cvs/gnome/libxslt/libxslt/xsltutils.c,v
retrieving revision 1.44
diff -u -r1.44 xsltutils.c
--- libxslt/xsltutils.c 2001/07/23 00:55:43 1.44
+++ libxslt/xsltutils.c 2001/07/25 14:54:40
@@ -288,7 +288,7 @@
const xmlChar *name = NULL;
const char *type = "error";
- if ((node != NULL) && (ctxt != NULL))
+ if ((node == NULL) && (ctxt != NULL))
node = ctxt->inst;
if (node != NULL) {
Index: xsltproc/xsltproc.c
===================================================================
RCS file: /cvs/gnome/libxslt/xsltproc/xsltproc.c,v
retrieving revision 1.3
diff -u -r1.3 xsltproc.c
--- xsltproc/xsltproc.c 2001/07/23 21:47:41 1.3
+++ xsltproc/xsltproc.c 2001/07/25 14:54:40
@@ -406,9 +406,10 @@
xmlSubstituteEntitiesDefault(1);
/*
- * Register the EXSLT extensions
+ * Register the EXSLT extensions and the test module
*/
exsltRegisterAll();
+ xsltRegisterTestModule();
for (i = 1; i < argc; i++) {
if ((!strcmp(argv[i], "-maxdepth")) ||
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]