[xslt] xsltInit preventing multiple transformations with libxslt:node-set



	I have the following code within my program:

xsltStylesheetPtr cur = NULL;
xmlDocPtr 		xmlFile = NULL;

xmlFile = xmlParseFile(xmlStr);

xmlSubstituteEntitiesDefault(1);
cur = xsltParseStylesheetFile((const xmlChar *)xslStr);
if (cur)
{
	res = xsltApplyStylesheet(cur, xmlFile, params);
	if (res)
	{
		if (xsltSaveResultToFilename(destStr, res, cur, 0) > 0)
			success = true;
		xmlFreeDoc(res);
	}
	xsltFreeStylesheet(cur);
}

if (xmlFile)
	xmlFreeDoc(xmlFile);

xsltCleanupGlobals();
xmlCleanupParser();

	This is pretty much taken from the example code
	The problem I'm having is that if it is run twice in a row with
a particular XSL file, the second pass will not work. The first pass
will work perfectly. I've traced through the code, and I know what the
problem is.
	The XSLT being used has the following line in a template

	<xsl:variable name="issueXML"
select="libxslt:node-set($issueList)"/>
	
	The libxslt:node-set function doesn't work the second time.
	The problem is happening in xsltInit() in xslt.c:

static void
xsltInit (void) {
    static int initialized = 0;

    if (initialized == 0) {
	initialized = 1;
	xsltRegisterAllExtras();
    }
}

	This function uses a static local variable 'initialized' to see
if it needs to call xsltRegisterAllExtras(). That will fill in the
global 'xsltFunctionsHash' which contains the information about the
libxslt:node-set function. The 'xsltFunctionsHash' global is being
unloaded with the xsltCleanupGlobals() call. That doesn't have access to
xsltInit::initialized, and so can't clear it.
	The second time through, xsltInit() sees that 'initialized' is
still set to 1, and so it doesn't need to call xsltRegisterAllExtras().
'xsltFunctionsHash' remains NULL, and when the libxslt:node-set function
is encountered, it is unrecognized.
	I can see how this problem can be missed, because
libxslt:node-set isn't a standard xslt function and it works the first
time. I think the best solution to this problem would be to change
'initialized' into a global, so that xsltCleanupGlobals() could reset it
to 0. Another possibility is to have the check for initialization
instead just check if xsltFunctionsHash is not NULL.




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]