summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@src.gnome.org>2001-03-19 17:52:26 +0000
committerDaniel Veillard <veillard@src.gnome.org>2001-03-19 17:52:26 +0000
commit7f6e74674b2407a13b710d253face364ff28a2ab (patch)
treea9d6b31e09afda854c1cf2deb69f05951b423c7b
parent79699ad7dad7e7e956fe8a9e7924ed4ad68f02ad (diff)
downloadlibxslt-7f6e74674b2407a13b710d253face364ff28a2ab.tar.gz
Switched all the processing to compiled XPath form, there is a
small problem showing up in the mediaobject.filename template of DocBook, but the way unparsed-entity-uri() doesn't follow the spec it seems so ...: - xsltutils.h: cleanup some garbage added last night - xsltInternals.h variables.c transform.c templates.[ch] preproc.c pattern.c keys.c: switched the whole XSLt processing to use XPath precompiled expressions and reusing them. - functions.c: some cleanup, seems people don't use unparsed-entity-uri() the way it's supposed to be used Daniel
-rw-r--r--ChangeLog9
-rw-r--r--libxslt/functions.c19
-rw-r--r--libxslt/keys.c29
-rw-r--r--libxslt/pattern.c28
-rw-r--r--libxslt/preproc.c2
-rw-r--r--libxslt/templates.c75
-rw-r--r--libxslt/templates.h4
-rw-r--r--libxslt/transform.c209
-rw-r--r--libxslt/variables.c37
-rw-r--r--libxslt/xsltInternals.h2
-rw-r--r--libxslt/xsltutils.h1
11 files changed, 158 insertions, 257 deletions
diff --git a/ChangeLog b/ChangeLog
index eef15e02..36860223 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Mon Mar 19 18:40:40 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+ * xsltutils.h: cleanup some garbage added last night
+ * xsltInternals.h variables.c transform.c templates.[ch]
+ preproc.c pattern.c keys.c: switched the whole XSLt processing
+ to use XPath precompiled expressions and reusing them.
+ * functions.c: some cleanup, seems people don't use
+ unparsed-entity-uri() the way it's supposed to be used
+
Mon Mar 19 01:08:05 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* libxslt/keys.c libxslt/templates.c libxslt/transform.c
diff --git a/libxslt/functions.c b/libxslt/functions.c
index c6c0a934..69667506 100644
--- a/libxslt/functions.c
+++ b/libxslt/functions.c
@@ -295,19 +295,19 @@ xsltUnparsedEntityURIFunction(xmlXPathParserContextPtr ctxt, int nargs){
xmlXPathObjectPtr obj;
xmlChar *str;
- if (nargs != 1) {
+ if ((nargs != 1) || (ctxt->value == NULL)) {
xsltGenericError(xsltGenericErrorContext,
- "system-property() : expects one string arg\n");
+ "unparsed-entity-uri() : expects one string arg\n");
ctxt->error = XPATH_INVALID_ARITY;
return;
}
- if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
+ obj = valuePop(ctxt);
+ if (obj->type != XPATH_STRING) {
xsltGenericError(xsltGenericErrorContext,
- "generate-id() : invalid arg expecting a string\n");
- ctxt->error = XPATH_INVALID_TYPE;
- return;
+ "unparsed-entity-uri() : invalid arg expecting a string\n");
+ obj = xmlXPathConvertString(obj);
}
- obj = valuePop(ctxt);
+
str = obj->stringval;
if (str == NULL) {
valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
@@ -321,8 +321,7 @@ xsltUnparsedEntityURIFunction(xmlXPathParserContextPtr ctxt, int nargs){
if (entity->URI != NULL)
valuePush(ctxt, xmlXPathNewString(entity->URI));
else
- valuePush(ctxt, xmlXPathNewString(
- xmlStrdup((const xmlChar *)"")));
+ valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
}
}
xmlXPathFreeObject(obj);
@@ -416,7 +415,7 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
return;
}
cur = nodelist->nodeTab[0];
- for (i = 2;i <= nodelist->nodeNr;i++) {
+ for (i = 1;i < nodelist->nodeNr;i++) {
ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]);
if (ret == -1)
cur = nodelist->nodeTab[i];
diff --git a/libxslt/keys.c b/libxslt/keys.c
index fd2f6c3b..ca531076 100644
--- a/libxslt/keys.c
+++ b/libxslt/keys.c
@@ -291,11 +291,12 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr doc,
int i;
xmlChar *pattern = NULL;
xmlNodeSetPtr nodelist = NULL, keylist;
- xmlXPathObjectPtr res = NULL, tmp;
+ xmlXPathObjectPtr res = NULL;
xmlChar *str;
- xmlXPathParserContextPtr xpathParserCtxt;
+ xmlXPathCompExprPtr comp;
xsltKeyTablePtr table;
+
/*
* Prepare the search
*/
@@ -310,22 +311,14 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr doc,
* Evaluate the nodelist
*/
- xpathParserCtxt =
- xmlXPathNewParserContext(pattern, ctxt->xpathCtxt);
- if (xpathParserCtxt == NULL)
+ comp = xmlXPathCompile(pattern);
+ if (comp == NULL)
goto error;
ctxt->document = doc;
ctxt->node = (xmlNodePtr) doc->doc;
ctxt->xpathCtxt->node = (xmlNodePtr) doc->doc;
- xmlXPathEvalExpr(xpathParserCtxt);
- xmlXPathRunEval(xpathParserCtxt);
- res = valuePop(xpathParserCtxt);
- do {
- tmp = valuePop(xpathParserCtxt);
- if (tmp != NULL) {
- xmlXPathFreeObject(tmp);
- }
- } while (tmp != NULL);
+ res = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
+ xmlXPathFreeCompExpr(comp);
if (res != NULL) {
if (res->type == XPATH_NODESET) {
nodelist = res->nodesetval;
@@ -359,9 +352,12 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr doc,
if (table == NULL)
goto error;
+ comp = xmlXPathCompile(keyd->use);
+ if (comp == NULL)
+ goto error;
for (i = 0;i < nodelist->nodeNr;i++) {
ctxt->node = nodelist->nodeTab[i];
- str = xsltEvalXPathString(ctxt, keyd->use);
+ str = xsltEvalXPathString(ctxt, comp);
if (str != NULL) {
#ifdef DEBUG_KEYS
xsltGenericDebug(xsltGenericDebugContext,
@@ -385,6 +381,7 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr doc,
#endif
}
}
+ xmlXPathFreeCompExpr(comp);
table->next = doc->keys;
doc->keys = table;
@@ -392,8 +389,6 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr doc,
error:
if (res != NULL)
xmlXPathFreeObject(res);
- if (xpathParserCtxt != NULL)
- xmlXPathFreeParserContext(xpathParserCtxt);
if (pattern != NULL)
xmlFree(pattern);
}
diff --git a/libxslt/pattern.c b/libxslt/pattern.c
index 787db93d..0a07ed0f 100644
--- a/libxslt/pattern.c
+++ b/libxslt/pattern.c
@@ -65,6 +65,7 @@ struct _xsltStepOp {
xmlChar *value;
xmlChar *value2;
xmlChar *value3;
+ xmlXPathCompExprPtr comp;
/*
* Optimisations for count
*/
@@ -150,6 +151,8 @@ xsltFreeCompMatch(xsltCompMatchPtr comp) {
xmlFree(op->value2);
if (op->value3 != NULL)
xmlFree(op->value3);
+ if (op->comp != NULL)
+ xmlXPathFreeCompExpr(op->comp);
}
memset(comp, -1, sizeof(xsltCompMatch));
xmlFree(comp);
@@ -655,21 +658,30 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
oldNode = ctxt->node;
ctxt->node = node;
- if ((step->value == NULL) ||
- (!xsltEvalXPathPredicate(ctxt, step->value))) {
- if (pos != 0) {
- ctxt->xpathCtxt->contextSize = oldCS;
- ctxt->xpathCtxt->proximityPosition = oldCP;
- }
- ctxt->node = oldNode;
- return(0);
+ if (step->value == NULL)
+ goto wrong_index;
+
+ if (step->comp == NULL) {
+ step->comp = xmlXPathCompile(step->value);
+ if (step->comp == NULL)
+ goto wrong_index;
}
+ if (!xsltEvalXPathPredicate(ctxt, step->comp))
+ goto wrong_index;
+
if (pos != 0) {
ctxt->xpathCtxt->contextSize = oldCS;
ctxt->xpathCtxt->proximityPosition = oldCP;
}
ctxt->node = oldNode;
break;
+wrong_index:
+ if (pos != 0) {
+ ctxt->xpathCtxt->contextSize = oldCS;
+ ctxt->xpathCtxt->proximityPosition = oldCP;
+ }
+ ctxt->node = oldNode;
+ return(0);
}
case XSLT_OP_PI:
if (node->type != XML_PI_NODE)
diff --git a/libxslt/preproc.c b/libxslt/preproc.c
index 1476aea5..1bb30795 100644
--- a/libxslt/preproc.c
+++ b/libxslt/preproc.c
@@ -158,6 +158,8 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
xmlFree(comp->numdata.value);
if (comp->numdata.format != NULL)
xmlFree(comp->numdata.format);
+ if (comp->comp != NULL)
+ xmlXPathFreeCompExpr(comp->comp);
memset(comp, -1, sizeof(xsltStylePreComp));
diff --git a/libxslt/templates.c b/libxslt/templates.c
index 14e1640a..23e3a3ee 100644
--- a/libxslt/templates.c
+++ b/libxslt/templates.c
@@ -39,7 +39,7 @@
/**
* xsltEvalXPathPredicate:
* @ctxt: the XSLT transformation context
- * @str: the XPath expression
+ * @comp: the XPath compiled expression
*
* Process the expression using XPath and evaluate the result as
* an XPath predicate
@@ -47,47 +47,36 @@
* Returns 1 is the predicate was true, 0 otherwise
*/
int
-xsltEvalXPathPredicate(xsltTransformContextPtr ctxt, const xmlChar *expr) {
- int ret;
- xmlXPathObjectPtr res, tmp;
- xmlXPathParserContextPtr xpathParserCtxt;
-
- xpathParserCtxt =
- xmlXPathNewParserContext(expr, ctxt->xpathCtxt);
- if (xpathParserCtxt == NULL)
- return(0);
+xsltEvalXPathPredicate(xsltTransformContextPtr ctxt,
+ xmlXPathCompExprPtr comp) {
+ int ret, position;
+ xmlXPathObjectPtr res;
+
+ position = ctxt->xpathCtxt->proximityPosition;
ctxt->xpathCtxt->node = ctxt->node;
- xmlXPathEvalExpr(xpathParserCtxt);
- xmlXPathRunEval(xpathParserCtxt);
- res = valuePop(xpathParserCtxt);
- do {
- tmp = valuePop(xpathParserCtxt);
- if (tmp != NULL) {
- xmlXPathFreeObject(tmp);
- }
- } while (tmp != NULL);
+ res = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
+ ctxt->xpathCtxt->proximityPosition = position;
if (res != NULL) {
- ret = xmlXPathEvaluatePredicateResult(xpathParserCtxt, res);
+ ret = xmlXPathEvalPredicate(ctxt->xpathCtxt, res);
xmlXPathFreeObject(res);
#ifdef DEBUG_TEMPLATES
xsltGenericDebug(xsltGenericDebugContext,
- "xsltEvalXPathPredicate: %s returns %d\n", expr, ret);
+ "xsltEvalXPathPredicate: returns %d\n", ret);
#endif
} else {
#ifdef DEBUG_TEMPLATES
xsltGenericDebug(xsltGenericDebugContext,
- "xsltEvalXPathPredicate: %s failed\n", expr);
+ "xsltEvalXPathPredicate: failed\n");
#endif
ret = 0;
}
- xmlXPathFreeParserContext(xpathParserCtxt);
return(ret);
}
/**
* xsltEvalXPathString:
* @ctxt: the XSLT transformation context
- * @str: the XPath expression
+ * @comp: the compiled XPath expression
*
* Process the expression using XPath and get a string
*
@@ -95,27 +84,15 @@ xsltEvalXPathPredicate(xsltTransformContextPtr ctxt, const xmlChar *expr) {
* caller.
*/
xmlChar *
-xsltEvalXPathString(xsltTransformContextPtr ctxt, const xmlChar *expr) {
+xsltEvalXPathString(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp) {
xmlChar *ret = NULL;
- xmlXPathObjectPtr res, tmp;
- xmlXPathParserContextPtr xpathParserCtxt;
+ xmlXPathObjectPtr res;
- xpathParserCtxt =
- xmlXPathNewParserContext(expr, ctxt->xpathCtxt);
- if (xpathParserCtxt == NULL)
- return(NULL);
ctxt->xpathCtxt->node = ctxt->node;
- xmlXPathEvalExpr(xpathParserCtxt);
- xmlXPathRunEval(xpathParserCtxt);
- xmlXPathStringFunction(xpathParserCtxt, 1);
- res = valuePop(xpathParserCtxt);
- do {
- tmp = valuePop(xpathParserCtxt);
- if (tmp != NULL) {
- xmlXPathFreeObject(tmp);
- }
- } while (tmp != NULL);
+ res = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
if (res != NULL) {
+ if (res->type != XPATH_STRING)
+ res = xmlXPathConvertString(res);
if (res->type == XPATH_STRING) {
ret = res->stringval;
res->stringval = NULL;
@@ -125,10 +102,9 @@ xsltEvalXPathString(xsltTransformContextPtr ctxt, const xmlChar *expr) {
}
xmlXPathFreeObject(res);
}
- xmlXPathFreeParserContext(xpathParserCtxt);
#ifdef DEBUG_TEMPLATES
xsltGenericDebug(xsltGenericDebugContext,
- "xsltEvalXPathString: %s returns %s\n", expr, ret);
+ "xsltEvalXPathString: returns %s\n", ret);
#endif
return(ret);
}
@@ -208,7 +184,13 @@ xsltAttrTemplateValueProcess(xsltTransformContextPtr ctxt, const xmlChar *str) {
if (expr == NULL)
return(ret);
else {
- val = xsltEvalXPathString(ctxt, expr);
+ xmlXPathCompExprPtr comp;
+ /*
+ * TODO: keep precompiled form around
+ */
+ comp = xmlXPathCompile(expr);
+ val = xsltEvalXPathString(ctxt, comp);
+ xmlXPathFreeCompExpr(comp);
xmlFree(expr);
if (val != NULL) {
ret = xmlStrcat(ret, val);
@@ -254,8 +236,9 @@ xsltEvalAttrValueTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
return(NULL);
/*
- * TODO: accelerator if there is no AttrValueTemplate in the stylesheet
- * return expr directly
+ * TODO: though now {} is detected ahead, it would still be good to
+ * optimize both functions to keep the splitted value if the
+ * attribute content and the XPath precompiled expressions around
*/
ret = xsltAttrTemplateValueProcess(ctxt, expr);
diff --git a/libxslt/templates.h b/libxslt/templates.h
index be2f6c09..93294f61 100644
--- a/libxslt/templates.h
+++ b/libxslt/templates.h
@@ -18,7 +18,7 @@ extern "C" {
#endif
int xsltEvalXPathPredicate (xsltTransformContextPtr ctxt,
- const xmlChar *expr);
+ xmlXPathCompExprPtr comp);
xmlChar * xsltEvalTemplateString (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr parent);
@@ -30,7 +30,7 @@ xmlChar * xsltEvalStaticAttrValueTemplate (xsltTransformContextPtr ctxt,
const xmlChar *name,
int *found);
xmlChar * xsltEvalXPathString (xsltTransformContextPtr ctxt,
- const xmlChar *expr);
+ xmlXPathCompExprPtr comp);
xmlNodePtr * xsltTemplateProcess (xsltTransformContextPtr ctxt,
xmlNodePtr node);
xmlAttrPtr xsltAttrListTemplateProcess (xsltTransformContextPtr ctxt,
diff --git a/libxslt/transform.c b/libxslt/transform.c
index d8bd3d4b..1b6b7185 100644
--- a/libxslt/transform.c
+++ b/libxslt/transform.c
@@ -1132,9 +1132,7 @@ xsltSort(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst, xsltStylePreCompPtr comp) {
xmlXPathObjectPtr *results = NULL;
xmlNodeSetPtr list = NULL;
- xmlXPathParserContextPtr xpathParserCtxt = NULL;
- xmlXPathObjectPtr res, tmp;
- const xmlChar *start;
+ xmlXPathObjectPtr res;
int len = 0;
int i;
xmlNodePtr oldNode;
@@ -1148,6 +1146,12 @@ xsltSort(xsltTransformContextPtr ctxt, xmlNodePtr node,
return;
if (comp->select == NULL)
return;
+ if (comp->comp == NULL) {
+ comp->comp = xmlXPathCompile(comp->select);
+ if (comp->comp == NULL)
+ return;
+ }
+
list = ctxt->nodeList;
if ((list == NULL) || (list->nodeNr <= 1))
@@ -1159,9 +1163,6 @@ xsltSort(xsltTransformContextPtr ctxt, xmlNodePtr node,
/* TODO: xsl:sort case-order attribute */
- xpathParserCtxt = xmlXPathNewParserContext(comp->select, ctxt->xpathCtxt);
- if (xpathParserCtxt == NULL)
- goto error;
results = xmlMalloc(len * sizeof(xmlXPathObjectPtr));
if (results == NULL) {
xsltGenericError(xsltGenericErrorContext,
@@ -1169,28 +1170,18 @@ xsltSort(xsltTransformContextPtr ctxt, xmlNodePtr node,
goto error;
}
- start = xpathParserCtxt->cur;
oldNode = ctxt->node;
for (i = 0;i < len;i++) {
- xpathParserCtxt->cur = start;
ctxt->xpathCtxt->contextSize = len;
ctxt->xpathCtxt->proximityPosition = i + 1;
ctxt->node = list->nodeTab[i];
ctxt->xpathCtxt->node = ctxt->node;
- xmlXPathEvalExpr(xpathParserCtxt);
- xmlXPathRunEval(xpathParserCtxt);
- xmlXPathStringFunction(xpathParserCtxt, 1);
- if (comp->number)
- xmlXPathNumberFunction(xpathParserCtxt, 1);
- res = valuePop(xpathParserCtxt);
- do {
- tmp = valuePop(xpathParserCtxt);
- if (tmp != NULL) {
- xmlXPathFreeObject(tmp);
- }
- } while (tmp != NULL);
-
+ res = xmlXPathCompiledEval(comp->comp, ctxt->xpathCtxt);
if (res != NULL) {
+ if (res->type != XPATH_STRING)
+ res = xmlXPathConvertString(res);
+ if (comp->number)
+ res = xmlXPathConvertNumber(res);
if (comp->number) {
if (res->type == XPATH_NUMBER) {
results[i] = res;
@@ -1219,8 +1210,6 @@ xsltSort(xsltTransformContextPtr ctxt, xmlNodePtr node,
xsltSortFunction(list, &results[0], comp->descending, comp->number);
error:
- if (xpathParserCtxt != NULL)
- xmlXPathFreeParserContext(xpathParserCtxt);
if (results != NULL) {
for (i = 0;i < len;i++)
xmlXPathFreeObject(results[i]);
@@ -1674,8 +1663,7 @@ error:
void
xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst, xsltStylePreCompPtr comp) {
- xmlXPathObjectPtr res = NULL, tmp;
- xmlXPathParserContextPtr xpathParserCtxt = NULL;
+ xmlXPathObjectPtr res = NULL;
xmlNodePtr copy = NULL;
xmlNodeSetPtr list = NULL;
int i;
@@ -1685,25 +1673,18 @@ xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
if (comp->select == NULL)
return;
+ if (comp->comp == NULL) {
+ comp->comp = xmlXPathCompile(comp->select);
+ if (comp->comp == NULL)
+ return;
+ }
#ifdef DEBUG_PROCESS
xsltGenericDebug(xsltGenericDebugContext,
"xsltCopyOf: select %s\n", comp->select);
#endif
- xpathParserCtxt =
- xmlXPathNewParserContext(comp->select, ctxt->xpathCtxt);
- if (xpathParserCtxt == NULL)
- goto error;
ctxt->xpathCtxt->node = node;
- xmlXPathEvalExpr(xpathParserCtxt);
- xmlXPathRunEval(xpathParserCtxt);
- res = valuePop(xpathParserCtxt);
- do {
- tmp = valuePop(xpathParserCtxt);
- if (tmp != NULL) {
- xmlXPathFreeObject(tmp);
- }
- } while (tmp != NULL);
+ res = xmlXPathCompiledEval(comp->comp, ctxt->xpathCtxt);
if (res != NULL) {
if (res->type == XPATH_NODESET) {
list = res->nodesetval;
@@ -1735,9 +1716,7 @@ xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
}
} else {
/* convert to a string */
- valuePush(xpathParserCtxt, res);
- xmlXPathStringFunction(xpathParserCtxt, 1);
- res = valuePop(xpathParserCtxt);
+ res = xmlXPathConvertString(res);
if ((res != NULL) && (res->type == XPATH_STRING)) {
/* append content as text node */
copy = xmlNewText(res->stringval);
@@ -1745,12 +1724,6 @@ xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlAddChild(ctxt->insert, copy);
}
}
- do {
- tmp = valuePop(xpathParserCtxt);
- if (tmp != NULL) {
- xmlXPathFreeObject(tmp);
- }
- } while (tmp != NULL);
if (copy == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltDefaultProcessOneNode: text copy failed\n");
@@ -1763,11 +1736,6 @@ xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
}
}
-error:
- if (xpathParserCtxt != NULL) {
- xmlXPathFreeParserContext(xpathParserCtxt);
- xpathParserCtxt = NULL;
- }
if (res != NULL)
xmlXPathFreeObject(res);
}
@@ -1784,8 +1752,7 @@ error:
void
xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst, xsltStylePreCompPtr comp) {
- xmlXPathObjectPtr res = NULL, tmp;
- xmlXPathParserContextPtr xpathParserCtxt = NULL;
+ xmlXPathObjectPtr res = NULL;
xmlNodePtr copy = NULL;
if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
@@ -1793,28 +1760,22 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
if (comp->select == NULL)
return;
+ if (comp->comp == NULL) {
+ comp->comp = xmlXPathCompile(comp->select);
+ if (comp->comp == NULL)
+ return;
+ }
#ifdef DEBUG_PROCESS
xsltGenericDebug(xsltGenericDebugContext,
"xsltValueOf: select %s\n", comp->select);
#endif
- xpathParserCtxt =
- xmlXPathNewParserContext(comp->select, ctxt->xpathCtxt);
- if (xpathParserCtxt == NULL)
- goto error;
ctxt->xpathCtxt->node = node;
- xmlXPathEvalExpr(xpathParserCtxt);
- xmlXPathRunEval(xpathParserCtxt);
- xmlXPathStringFunction(xpathParserCtxt, 1);
- res = valuePop(xpathParserCtxt);
- do {
- tmp = valuePop(xpathParserCtxt);
- if (tmp != NULL) {
- xmlXPathFreeObject(tmp);
- }
- } while (tmp != NULL);
+ res = xmlXPathCompiledEval(comp->comp, ctxt->xpathCtxt);
if (res != NULL) {
+ if (res->type != XPATH_STRING)
+ res = xmlXPathConvertString(res);
if (res->type == XPATH_STRING) {
copy = xmlNewText(res->stringval);
if (copy != NULL) {
@@ -1833,11 +1794,6 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
xsltGenericDebug(xsltGenericDebugContext,
"xsltValueOf: result %s\n", res->stringval);
#endif
-error:
- if (xpathParserCtxt != NULL) {
- xmlXPathFreeParserContext(xpathParserCtxt);
- xpathParserCtxt = NULL;
- }
if (res != NULL)
xmlXPathFreeObject(res);
}
@@ -1968,9 +1924,8 @@ void
xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst, xsltStylePreCompPtr comp) {
xmlNodePtr cur, delete = NULL;
- xmlXPathObjectPtr res = NULL, tmp;
+ xmlXPathObjectPtr res = NULL;
xmlNodeSetPtr list = NULL, oldlist;
- xmlXPathParserContextPtr xpathParserCtxt = NULL;
int i, oldProximityPosition, oldContextSize;
const xmlChar *oldmode, *oldmodeURI;
int have_sort=0;
@@ -1998,27 +1953,18 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
ctxt->modeURI = comp->modeURI;
if (comp->select != NULL) {
+ if (comp->comp == NULL) {
+ comp->comp = xmlXPathCompile(comp->select);
+ if (comp->comp == NULL)
+ goto error;
+ }
#ifdef DEBUG_PROCESS
xsltGenericDebug(xsltGenericDebugContext,
"xsltApplyTemplates: select %s\n", comp->select);
#endif
- if (ctxt->xpathCtxt == NULL) {
- }
- xpathParserCtxt =
- xmlXPathNewParserContext(comp->select, ctxt->xpathCtxt);
- if (xpathParserCtxt == NULL)
- goto error;
ctxt->xpathCtxt->node = node;
- xmlXPathEvalExpr(xpathParserCtxt);
- xmlXPathRunEval(xpathParserCtxt);
- res = valuePop(xpathParserCtxt);
- do {
- tmp = valuePop(xpathParserCtxt);
- if (tmp != NULL) {
- xmlXPathFreeObject(tmp);
- }
- } while (tmp != NULL);
+ res = xmlXPathCompiledEval(comp->comp, ctxt->xpathCtxt);
if (res != NULL) {
if (res->type == XPATH_NODESET) {
list = res->nodesetval;
@@ -2142,8 +2088,6 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
error:
ctxt->mode = oldmode;
ctxt->modeURI = oldmodeURI;
- if (xpathParserCtxt != NULL)
- xmlXPathFreeParserContext(xpathParserCtxt);
if (res != NULL)
xmlXPathFreeObject(res);
if (list != NULL)
@@ -2164,8 +2108,7 @@ void
xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst, xsltStylePreCompPtr comp) {
xmlChar *prop = NULL;
- xmlXPathObjectPtr res = NULL, tmp;
- xmlXPathParserContextPtr xpathParserCtxt = NULL;
+ xmlXPathObjectPtr res = NULL;
xmlNodePtr replacement, when;
int doit = 1;
@@ -2188,7 +2131,8 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node,
goto error;
}
while (IS_XSLT_ELEM(replacement) && (IS_XSLT_NAME(replacement, "when"))) {
-
+ xmlXPathCompExprPtr comp;
+ /* TODO: build a precompiled block for when too ! */
when = replacement;
prop = xmlGetNsProp(when, (const xmlChar *)"test", XSLT_NAMESPACE);
if (prop == NULL) {
@@ -2201,22 +2145,15 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node,
"xsl:when: test %s\n", prop);
#endif
- xpathParserCtxt = xmlXPathNewParserContext(prop, ctxt->xpathCtxt);
- if (xpathParserCtxt == NULL)
+ comp = xmlXPathCompile(prop);
+ if (comp == NULL)
goto error;
ctxt->xpathCtxt->node = node;
- xmlXPathEvalExpr(xpathParserCtxt);
- xmlXPathRunEval(xpathParserCtxt);
- xmlXPathBooleanFunction(xpathParserCtxt, 1);
- res = valuePop(xpathParserCtxt);
- do {
- tmp = valuePop(xpathParserCtxt);
- if (tmp != NULL) {
- xmlXPathFreeObject(tmp);
- }
- } while (tmp != NULL);
-
+ res = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
+ xmlXPathFreeCompExpr(comp);
if (res != NULL) {
+ if (res->type != XPATH_BOOLEAN)
+ res = xmlXPathConvertBoolean(res);
if (res->type == XPATH_BOOLEAN)
doit = res->boolval;
else {
@@ -2238,9 +2175,6 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node,
xsltFreeStackElemList(varsPop(ctxt));
goto done;
}
- if (xpathParserCtxt != NULL)
- xmlXPathFreeParserContext(xpathParserCtxt);
- xpathParserCtxt = NULL;
if (prop != NULL)
xmlFree(prop);
prop = NULL;
@@ -2267,8 +2201,6 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node,
done:
error:
- if (xpathParserCtxt != NULL)
- xmlXPathFreeParserContext(xpathParserCtxt);
if (prop != NULL)
xmlFree(prop);
if (res != NULL)
@@ -2287,8 +2219,7 @@ error:
void
xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst, xsltStylePreCompPtr comp) {
- xmlXPathObjectPtr res = NULL, tmp;
- xmlXPathParserContextPtr xpathParserCtxt = NULL;
+ xmlXPathObjectPtr res = NULL;
int doit = 1;
if (comp == NULL) {
@@ -2300,28 +2231,22 @@ xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr node,
if (comp->test == NULL)
return;
+ if (comp->comp == NULL) {
+ comp->comp = xmlXPathCompile(comp->test);
+ if (comp->comp == NULL)
+ return;
+ }
#ifdef DEBUG_PROCESS
xsltGenericDebug(xsltGenericDebugContext,
"xsltIf: test %s\n", comp->test);
#endif
- xpathParserCtxt = xmlXPathNewParserContext(comp->test, ctxt->xpathCtxt);
- if (xpathParserCtxt == NULL)
- goto error;
ctxt->xpathCtxt->node = node;
- xmlXPathEvalExpr(xpathParserCtxt);
- xmlXPathRunEval(xpathParserCtxt);
- xmlXPathBooleanFunction(xpathParserCtxt, 1);
- res = valuePop(xpathParserCtxt);
- do {
- tmp = valuePop(xpathParserCtxt);
- if (tmp != NULL) {
- xmlXPathFreeObject(tmp);
- }
- } while (tmp != NULL);
-
+ res = xmlXPathCompiledEval(comp->comp, ctxt->xpathCtxt);
if (res != NULL) {
+ if (res->type != XPATH_BOOLEAN)
+ res = xmlXPathConvertBoolean(res);
if (res->type == XPATH_BOOLEAN)
doit = res->boolval;
else {
@@ -2344,8 +2269,6 @@ xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr node,
}
error:
- if (xpathParserCtxt != NULL)
- xmlXPathFreeParserContext(xpathParserCtxt);
if (res != NULL)
xmlXPathFreeObject(res);
}
@@ -2362,10 +2285,9 @@ error:
void
xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst, xsltStylePreCompPtr comp) {
- xmlXPathObjectPtr res = NULL, tmp;
+ xmlXPathObjectPtr res = NULL;
xmlNodePtr replacement;
xmlNodeSetPtr list = NULL, oldlist;
- xmlXPathParserContextPtr xpathParserCtxt = NULL;
int i, oldProximityPosition, oldContextSize;
/* xmlNodePtr oldInsert = ctxt->insert; */
xmlNodePtr oldNode = ctxt->node;
@@ -2379,26 +2301,19 @@ xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr node,
if (comp->select == NULL)
return;
+ if (comp->comp == NULL) {
+ comp->comp = xmlXPathCompile(comp->select);
+ if (comp->comp == NULL)
+ return;
+ }
#ifdef DEBUG_PROCESS
xsltGenericDebug(xsltGenericDebugContext,
"xsltForEach: select %s\n", comp->select);
#endif
- xpathParserCtxt = xmlXPathNewParserContext(comp->select, ctxt->xpathCtxt);
- if (xpathParserCtxt == NULL)
- goto error;
ctxt->xpathCtxt->node = node;
- xmlXPathEvalExpr(xpathParserCtxt);
- xmlXPathRunEval(xpathParserCtxt);
- res = valuePop(xpathParserCtxt);
- do {
- tmp = valuePop(xpathParserCtxt);
- if (tmp != NULL) {
- xmlXPathFreeObject(tmp);
- }
- } while (tmp != NULL);
-
+ res = xmlXPathCompiledEval(comp->comp, ctxt->xpathCtxt);
if (res != NULL) {
if (res->type == XPATH_NODESET)
list = res->nodesetval;
@@ -2445,8 +2360,6 @@ xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr node,
ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
error:
- if (xpathParserCtxt != NULL)
- xmlXPathFreeParserContext(xpathParserCtxt);
if (res != NULL)
xmlXPathFreeObject(res);
}
diff --git a/libxslt/variables.c b/libxslt/variables.c
index 3d33e2b3..c47c0dd9 100644
--- a/libxslt/variables.c
+++ b/libxslt/variables.c
@@ -243,9 +243,7 @@ xsltStackLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
* Returns 0 in case of success, -1 in case of error
*/
int
-xsltEvalVariables(xsltTransformContextPtr ctxt, xsltStackElemPtr elem) {
- xmlXPathParserContextPtr xpathParserCtxt;
-
+xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr elem) {
if ((ctxt == NULL) || (elem == NULL))
return(-1);
@@ -254,30 +252,19 @@ xsltEvalVariables(xsltTransformContextPtr ctxt, xsltStackElemPtr elem) {
"Evaluating variable %s\n", elem->name);
#endif
if (elem->select != NULL) {
- xmlXPathObjectPtr result, tmp;
+ xmlXPathCompExprPtr comp;
+ xmlXPathObjectPtr result;
- xpathParserCtxt = xmlXPathNewParserContext(elem->select,
- ctxt->xpathCtxt);
- if (xpathParserCtxt == NULL)
+ comp = xmlXPathCompile(elem->select);
+ if (comp == NULL)
return(-1);
ctxt->xpathCtxt->node = (xmlNodePtr) ctxt->node;
- xmlXPathEvalExpr(xpathParserCtxt);
- xmlXPathRunEval(xpathParserCtxt);
- result = valuePop(xpathParserCtxt);
- do {
- tmp = valuePop(xpathParserCtxt);
- if (tmp != NULL) {
- xmlXPathFreeObject(tmp);
- }
- } while (tmp != NULL);
-
+ result = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
+ xmlXPathFreeCompExpr(comp);
if (result == NULL) {
xsltGenericError(xsltGenericErrorContext,
"Evaluating global variable %s failed\n");
- }
- if (xpathParserCtxt != NULL)
- xmlXPathFreeParserContext(xpathParserCtxt);
- if (result != NULL) {
+ } else {
#ifdef DEBUG_VARIABLE
#ifdef LIBXML_DEBUG_ENABLED
if ((xsltGenericDebugContext == stdout) ||
@@ -359,7 +346,7 @@ xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) {
elem = style->variables;
while (elem != NULL) {
- xsltEvalVariables(ctxt, elem);
+ xsltEvalVariable(ctxt, elem);
elem = elem->next;
}
@@ -463,7 +450,7 @@ xsltBuildVariable(xsltTransformContextPtr ctxt, const xmlChar *name,
if (ns_uri)
elem->nameURI = xmlStrdup(ns_uri);
elem->tree = tree;
- xsltEvalVariables(ctxt, elem);
+ xsltEvalVariable(ctxt, elem);
return(elem);
}
@@ -554,7 +541,7 @@ xsltGlobalVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
xsltGenericDebug(xsltGenericDebugContext,
"uncomputed global variable %s\n", name);
#endif
- xsltEvalVariables(ctxt, elem);
+ xsltEvalVariable(ctxt, elem);
}
if (elem->value != NULL)
return(xmlXPathObjectCopy(elem->value));
@@ -593,7 +580,7 @@ xsltVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
xsltGenericDebug(xsltGenericDebugContext,
"uncomputed variable %s\n", name);
#endif
- xsltEvalVariables(ctxt, elem);
+ xsltEvalVariable(ctxt, elem);
}
if (elem->value != NULL)
return(xmlXPathObjectCopy(elem->value));
diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h
index 77eb4289..4893fee0 100644
--- a/libxslt/xsltInternals.h
+++ b/libxslt/xsltInternals.h
@@ -257,6 +257,8 @@ struct _xsltStylePreComp {
xmlChar *filename; /* document URL */
xsltNumberData numdata; /* number */
+
+ xmlXPathCompExprPtr comp; /* a precompiled XPath expression */
};
/*
diff --git a/libxslt/xsltutils.h b/libxslt/xsltutils.h
index 966ec762..44238e59 100644
--- a/libxslt/xsltutils.h
+++ b/libxslt/xsltutils.h
@@ -23,7 +23,6 @@ extern "C" {
int xmlXPathIsNodeType(const xmlChar *name);
xmlChar *xmlSplitQName2(const xmlChar *name, xmlChar **prefix);
void xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathRunEval(xmlXPathParserContextPtr ctxt);
/*********
void xmlXPathRegisterVariableLookup(xmlXPathContextPtr ctxt,
xmlXPathVariableLookupFunc f, void *data)