mirror of
https://gitlab.gnome.org/GNOME/libxslt
synced 2025-08-05 23:35:48 +03:00
new extension framework. Added stylesheet module data, top-level and
* libxslt/extensions.[ch] libxslt/functions.[ch] libxslt/preproc.c libxslt/transform.[ch] libxslt/variables.c libxslt/xslt.c libxslt/xsltInternals.h: new extension framework. Added stylesheet module data, top-level and extension elements precomputing, global registration of top-level elements and extension elements and functions. Extensions are no longer initialized from extension-element-prefixes declarations but when modules need the data. init/shutdown functions registered with xsltRegisterExtModule{,Full} only allocate and free module data, they shouldn't register the elements and functions any more. * libxslt/xsltutils.c: fixed a bug in xsltPrintErrorContext when @node wasn't NULL. * libxslt/xslt.c: fixed xsltPrecomputeStylesheetTop which allowed non-XSLT top-level elements before any xsl:import element. * libexslt/common.c libexslt/functions.c libexslt/math.c libexslt/sets.c: adapted to use the new extension framework. * libxslt/functions.c libxslt/extensions[ch] xsltproc/xsltproc.c: moved the test module from functions.c to extensions.[ch], modified it to use the new extension framework. Updated xsltproc to register the test module.
This commit is contained in:
24
ChangeLog
24
ChangeLog
@@ -1,3 +1,27 @@
|
||||
Thu Jul 26 19:05:48 CEST 2001 Thomas Broyer <tbroyer@ltgt.net>
|
||||
|
||||
* libxslt/extensions.[ch] libxslt/functions.[ch] libxslt/preproc.c
|
||||
libxslt/transform.[ch] libxslt/variables.c libxslt/xslt.c
|
||||
libxslt/xsltInternals.h: new extension framework.
|
||||
Added stylesheet module data, top-level and extension elements
|
||||
precomputing, global registration of top-level elements and
|
||||
extension elements and functions.
|
||||
Extensions are no longer initialized from extension-element-prefixes
|
||||
declarations but when modules need the data.
|
||||
init/shutdown functions registered with xsltRegisterExtModule{,Full}
|
||||
only allocate and free module data, they shouldn't register the
|
||||
elements and functions any more.
|
||||
* libxslt/xsltutils.c: fixed a bug in xsltPrintErrorContext when
|
||||
@node wasn't NULL.
|
||||
* libxslt/xslt.c: fixed xsltPrecomputeStylesheetTop which allowed
|
||||
non-XSLT top-level elements before any xsl:import element.
|
||||
* libexslt/common.c libexslt/functions.c libexslt/math.c
|
||||
libexslt/sets.c: adapted to use the new extension framework.
|
||||
* libxslt/functions.c libxslt/extensions[ch] xsltproc/xsltproc.c:
|
||||
moved the test module from functions.c to extensions.[ch],
|
||||
modified it to use the new extension framework. Updated xsltproc
|
||||
to register the test module.
|
||||
|
||||
Thu Jul 26 10:20:19 EDT 2001 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
* libxslt/pattern.c: fixed an ugly problem with namespaces
|
||||
|
@@ -52,19 +52,6 @@ exsltObjectTypeFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
||||
}
|
||||
|
||||
|
||||
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 @@ exsltCommonInit (xsltTransformContextPtr ctxt, const xmlChar *URI) {
|
||||
|
||||
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);
|
||||
}
|
||||
|
@@ -23,12 +23,32 @@ struct _exsltFuncData {
|
||||
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:
|
||||
@@ -41,6 +61,7 @@ static void exsltFuncResultElem (xsltTransformContextPtr ctxt,
|
||||
*/
|
||||
static exsltFuncData *
|
||||
exsltFuncInit (xsltTransformContextPtr ctxt, const xmlChar *URI) {
|
||||
xmlHashTablePtr hash;
|
||||
exsltFuncData *ret;
|
||||
|
||||
ret = (exsltFuncData *) xmlMalloc (sizeof(exsltFuncData));
|
||||
@@ -51,15 +72,13 @@ exsltFuncInit (xsltTransformContextPtr ctxt, const xmlChar *URI) {
|
||||
}
|
||||
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 @@ exsltFuncInit (xsltTransformContextPtr ctxt, const xmlChar *URI) {
|
||||
/**
|
||||
* 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 @@ static void
|
||||
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 (void) {
|
||||
"exsltFuncNewFunctionData: not enough memory\n");
|
||||
return (NULL);
|
||||
}
|
||||
memset(ret, 0, sizeof(exsltFuncFunctionData));
|
||||
|
||||
ret->nargs = 0;
|
||||
ret->content = NULL;
|
||||
@@ -124,11 +160,12 @@ exsltFuncNewFunctionData (void) {
|
||||
* @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 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
||||
* 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,15 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
||||
valuePush(ctxt, ret);
|
||||
}
|
||||
|
||||
|
||||
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 +304,36 @@ exsltFuncFunctionElem (xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -416,3 +462,25 @@ exsltFuncResultElem (xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
@@ -271,19 +271,6 @@ exsltMathLowestFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
||||
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 @@ exsltMathInit (xsltTransformContextPtr ctxt, const xmlChar *URI) {
|
||||
|
||||
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);
|
||||
}
|
||||
|
@@ -221,24 +221,6 @@ exsltSetsTrailingFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
||||
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 @@ exsltSetsInit (xsltTransformContextPtr ctxt, const xmlChar *URI) {
|
||||
|
||||
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);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -20,6 +20,30 @@ extern "C" {
|
||||
* Extension Modules API
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -47,6 +71,12 @@ typedef void (*xsltExtShutdownFunction) (xsltTransformContextPtr ctxt,
|
||||
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 xsltUnregisterAllExtModules(void);
|
||||
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,
|
||||
@@ -85,6 +175,11 @@ void xsltFreeCtxtExts (xsltTransformContextPtr ctxt);
|
||||
void xsltFreeExts (xsltStylesheetPtr style);
|
||||
|
||||
|
||||
/**
|
||||
* Test module http://xmlsoft.org/XSLT/
|
||||
*/
|
||||
void xsltRegisterTestModule (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -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 @@ xsltElementAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){
|
||||
|
||||
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 @@ xsltElementAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){
|
||||
}
|
||||
}
|
||||
|
||||
if (xmlHashLookup2(tctxt->extElements, name, nsURI) != NULL) {
|
||||
if (xsltExtElementLookup(tctxt, name, nsURI) != NULL) {
|
||||
valuePush(ctxt, xmlXPathNewBoolean(1));
|
||||
} else {
|
||||
valuePush(ctxt, xmlXPathNewBoolean(0));
|
||||
@@ -735,171 +774,6 @@ xsltCurrentFunction(xmlXPathParserContextPtr ctxt, int nargs){
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
* 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 @@ xsltRegisterAllFunctions(xmlXPathContextPtr ctxt)
|
||||
xsltElementAvailableFunction);
|
||||
xmlXPathRegisterFunc(ctxt, (const xmlChar *) "function-available",
|
||||
xsltFunctionAvailableFunction);
|
||||
|
||||
xsltRegisterExtModule((const xmlChar *) XSLT_DEFAULT_URL,
|
||||
xsltExtInitTest,
|
||||
xsltExtShutdownTest);
|
||||
}
|
||||
|
@@ -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
|
||||
*/
|
||||
|
@@ -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 @@ xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr inst) {
|
||||
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.
|
||||
*/
|
||||
|
@@ -233,6 +233,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
|
||||
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) {
|
||||
@@ -1129,8 +1130,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
* 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;
|
||||
|
@@ -26,6 +26,11 @@ int xsltGetXIncludeDefault (void);
|
||||
/**
|
||||
* Private Interfaces
|
||||
*/
|
||||
xsltTransformFunction
|
||||
xsltExtElementLookup (xsltTransformContextPtr ctxt,
|
||||
const xmlChar *name,
|
||||
const xmlChar *URI);
|
||||
|
||||
xmlDocPtr xsltApplyStylesheet (xsltStylesheetPtr style,
|
||||
xmlDocPtr doc,
|
||||
const char **params);
|
||||
|
@@ -328,6 +328,7 @@ xsltNewStylesheet(void) {
|
||||
cur->exclPrefixNr = 0;
|
||||
cur->exclPrefixMax = 0;
|
||||
cur->exclPrefixTab = NULL;
|
||||
cur->extInfos = NULL;
|
||||
return(cur);
|
||||
}
|
||||
|
||||
@@ -369,6 +370,7 @@ xsltFreeStylesheet(xsltStylesheetPtr sheet)
|
||||
xsltFreeNamespaceAliasHashes(sheet);
|
||||
xsltFreeStyleDocuments(sheet);
|
||||
xsltFreeStylePreComps(sheet);
|
||||
xsltShutdownExts(sheet);
|
||||
if (sheet->doc != NULL)
|
||||
xmlFreeDoc(sheet->doc);
|
||||
if (sheet->variables != NULL)
|
||||
@@ -1247,24 +1249,21 @@ xsltGatherNamespaces(xsltStylesheetPtr style) {
|
||||
/**
|
||||
* 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 @@ skip_children:
|
||||
break;
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
ret->content = template->children;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1599,7 +1596,9 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
|
||||
/*
|
||||
* 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 @@ xsltParseStylesheetTop(xsltStylesheetPtr style, xmlNodePtr top) {
|
||||
|
||||
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 @@ xsltParseStylesheetProcess(xsltStylesheetPtr ret, xmlDocPtr doc) {
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
@@ -323,6 +323,11 @@ struct _xsltStylesheet {
|
||||
int exclPrefixMax; /* size of the array */
|
||||
|
||||
void *_private; /* user defined data */
|
||||
|
||||
/*
|
||||
* Extensions
|
||||
*/
|
||||
xmlHashTablePtr extInfos; /* the extension data */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -449,6 +454,9 @@ xmlXPathError xsltFormatNumberConversion(xsltDecimalFormatPtr self,
|
||||
double number,
|
||||
xmlChar **result);
|
||||
|
||||
void xsltParseTemplateContent(xsltStylesheetPtr style,
|
||||
xmlNodePtr template);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -288,7 +288,7 @@ xsltPrintErrorContext(xsltTransformContextPtr ctxt,
|
||||
const xmlChar *name = NULL;
|
||||
const char *type = "error";
|
||||
|
||||
if ((node != NULL) && (ctxt != NULL))
|
||||
if ((node == NULL) && (ctxt != NULL))
|
||||
node = ctxt->inst;
|
||||
|
||||
if (node != NULL) {
|
||||
|
@@ -406,9 +406,10 @@ main(int argc, char **argv)
|
||||
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")) ||
|
||||
|
Reference in New Issue
Block a user