Commit aed0cca0 authored by Christian Ceelen's avatar Christian Ceelen Committed by Nick Wellnhofer

Use hash table to lookup named templates

For big XSLTs (>50000 templates) this results in a huge improvement of the
compilation time.

Thanks to Christian Ceelen for the original patch.

Fixes GitHub pull request #1
parent 23333e41
......@@ -400,17 +400,12 @@ xsltFindTemplate(xsltTransformContextPtr ctxt, const xmlChar *name,
return(NULL);
style = ctxt->style;
while (style != NULL) {
cur = style->templates;
while (cur != NULL) {
if (xmlStrEqual(name, cur->name)) {
if (((nameURI == NULL) && (cur->nameURI == NULL)) ||
((nameURI != NULL) && (cur->nameURI != NULL) &&
(xmlStrEqual(nameURI, cur->nameURI)))) {
return(cur);
}
}
cur = cur->next;
}
if (style->namedTemplates != NULL) {
cur = (xsltTemplatePtr)
xmlHashLookup2(style->namedTemplates, name, nameURI);
if (cur != NULL)
return(cur);
}
style = xsltNextImport(style);
}
......
......@@ -2090,9 +2090,34 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur,
const xmlChar *name = NULL;
float priority; /* the priority */
if ((style == NULL) || (cur == NULL) || (cur->match == NULL))
if ((style == NULL) || (cur == NULL))
return(-1);
/* Register named template */
if (cur->name != NULL) {
if (style->namedTemplates == NULL) {
style->namedTemplates = xmlHashCreate(10);
if (style->namedTemplates == NULL)
return(-1);
}
else {
void *dup = xmlHashLookup2(style->namedTemplates, cur->name,
cur->nameURI);
if (dup != NULL) {
xsltTransformError(NULL, style, NULL,
"xsl:template: error duplicate name '%s'\n",
cur->name);
style->errors++;
return(-1);
}
}
xmlHashAddEntry2(style->namedTemplates, cur->name, cur->nameURI, cur);
}
if (cur->match == NULL)
return(0);
priority = cur->priority;
pat = xsltCompilePatternInternal(cur->match, style->doc, cur->elem,
style, NULL, 1);
......@@ -2562,5 +2587,7 @@ xsltFreeTemplateHashes(xsltStylesheetPtr style) {
xsltFreeCompMatchList(style->piMatch);
if (style->commentMatch != NULL)
xsltFreeCompMatchList(style->commentMatch);
if (style->namedTemplates != NULL)
xmlHashFree(style->namedTemplates, NULL);
}
......@@ -5382,7 +5382,6 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
prop = xmlGetNsProp(template, (const xmlChar *)"name", NULL);
if (prop != NULL) {
const xmlChar *URI;
xsltTemplatePtr cur;
/*
* TODO: Don't use xsltGetQNameURI().
......@@ -5405,19 +5404,6 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
ret->nameURI = xmlDictLookup(style->dict, BAD_CAST URI, -1);
else
ret->nameURI = NULL;
cur = ret->next;
while (cur != NULL) {
if ((URI != NULL && xmlStrEqual(cur->name, ret->name) &&
xmlStrEqual(cur->nameURI, URI) ) ||
(URI == NULL && cur->nameURI == NULL &&
xmlStrEqual(cur->name, ret->name))) {
xsltTransformError(NULL, style, template,
"xsl:template: error duplicate name '%s'\n", ret->name);
style->errors++;
goto error;
}
cur = cur->next;
}
}
}
......
......@@ -1639,6 +1639,8 @@ struct _xsltStylesheet {
* Forwards-compatible processing
*/
int forwards_compatible;
xmlHashTablePtr namedTemplates; /* hash table of named templates */
};
typedef struct _xsltTransformCache xsltTransformCache;
......
compilation error: file test-6.1.xsl line 11 element template
xsl:template: error duplicate name 'duplicateTemplateName'
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- reject this XSLT named templates should have unique template name + nameURI combinations -->
<xsl:template match="doc">
<xsl:call-template name="duplicateTemplateName"/>
</xsl:template>
<xsl:template name="duplicateTemplateName">
<xsl:text>XSLT should be rejected</xsl:text>
</xsl:template>
<xsl:template name="duplicateTemplateName">
<xsl:text>XSLT should be rejected</xsl:text>
</xsl:template>
</xsl:stylesheet>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment