/**
* 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
* 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
*
* 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;
}
xmlXPathFreeObject(res);
}
- xmlXPathFreeParserContext(xpathParserCtxt);
#ifdef DEBUG_TEMPLATES
xsltGenericDebug(xsltGenericDebugContext,
- "xsltEvalXPathString: %s returns %s\n", expr, ret);
+ "xsltEvalXPathString: returns %s\n", ret);
#endif
return(ret);
}
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);
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);
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;
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))
/* 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,
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;
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]);
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;
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;
}
} 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);
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");
}
}
-error:
- if (xpathParserCtxt != NULL) {
- xmlXPathFreeParserContext(xpathParserCtxt);
- xpathParserCtxt = NULL;
- }
if (res != NULL)
xmlXPathFreeObject(res);
}
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))
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) {
xsltGenericDebug(xsltGenericDebugContext,
"xsltValueOf: result %s\n", res->stringval);
#endif
-error:
- if (xpathParserCtxt != NULL) {
- xmlXPathFreeParserContext(xpathParserCtxt);
- xpathParserCtxt = NULL;
- }
if (res != NULL)
xmlXPathFreeObject(res);
}
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;
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;
error:
ctxt->mode = oldmode;
ctxt->modeURI = oldmodeURI;
- if (xpathParserCtxt != NULL)
- xmlXPathFreeParserContext(xpathParserCtxt);
if (res != NULL)
xmlXPathFreeObject(res);
if (list != NULL)
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;
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) {
"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 {
xsltFreeStackElemList(varsPop(ctxt));
goto done;
}
- if (xpathParserCtxt != NULL)
- xmlXPathFreeParserContext(xpathParserCtxt);
- xpathParserCtxt = NULL;
if (prop != NULL)
xmlFree(prop);
prop = NULL;
done:
error:
- if (xpathParserCtxt != NULL)
- xmlXPathFreeParserContext(xpathParserCtxt);
if (prop != NULL)
xmlFree(prop);
if (res != NULL)
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) {
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 {
}
error:
- if (xpathParserCtxt != NULL)
- xmlXPathFreeParserContext(xpathParserCtxt);
if (res != NULL)
xmlXPathFreeObject(res);
}
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;
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;
ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
error:
- if (xpathParserCtxt != NULL)
- xmlXPathFreeParserContext(xpathParserCtxt);
if (res != NULL)
xmlXPathFreeObject(res);
}
* 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);
"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) ||
elem = style->variables;
while (elem != NULL) {
- xsltEvalVariables(ctxt, elem);
+ xsltEvalVariable(ctxt, elem);
elem = elem->next;
}
if (ns_uri)
elem->nameURI = xmlStrdup(ns_uri);
elem->tree = tree;
- xsltEvalVariables(ctxt, elem);
+ xsltEvalVariable(ctxt, elem);
return(elem);
}
xsltGenericDebug(xsltGenericDebugContext,
"uncomputed global variable %s\n", name);
#endif
- xsltEvalVariables(ctxt, elem);
+ xsltEvalVariable(ctxt, elem);
}
if (elem->value != NULL)
return(xmlXPathObjectCopy(elem->value));
xsltGenericDebug(xsltGenericDebugContext,
"uncomputed variable %s\n", name);
#endif
- xsltEvalVariables(ctxt, elem);
+ xsltEvalVariable(ctxt, elem);
}
if (elem->value != NULL)
return(xmlXPathObjectCopy(elem->value));