mirror of
https://github.com/GNOME/libxml2.git
synced 2025-03-13 18:47:01 +08:00
More cleanups, XSLT induced, start looking okay:
- xpath.[ch]: still a lot of cleanup based on XSLT, added xmlXPathConvert{String,Number,Boolean} to be able to make type casts without a context stack, fixed some implementation problems related to the absence of context at parse-time, added xmlXPathEvalPredicate() and xmlXPathFreeCompExpr() in the public API too - xpointer.c xpathInternals.h: we need to know at parse time whether we are compiling an XPointer Daniel
This commit is contained in:
parent
afcbe1cb12
commit
fbf8a2d0c8
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
||||
Mon Mar 19 16:50:52 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
||||
|
||||
* xpath.[ch]: still a lot of cleanup based on XSLT, added
|
||||
xmlXPathConvert{String,Number,Boolean} to be able to make
|
||||
type casts without a context stack, fixed some implementation
|
||||
problems related to the absence of context at parse-time,
|
||||
added xmlXPathEvalPredicate() and xmlXPathFreeCompExpr()
|
||||
in the public API too
|
||||
* xpointer.c xpathInternals.h: we need to know at parse time
|
||||
whether we are compiling an XPointer
|
||||
|
||||
Mon Mar 19 11:54:31 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
||||
|
||||
* xpath.[ch] xpointer.c: restaured the Binary and API compatibility
|
||||
|
@ -244,7 +244,7 @@ struct _xmlXPathParserContext {
|
||||
xmlXPathObjectPtr *valueTab; /* stack of values */
|
||||
|
||||
xmlXPathCompExprPtr comp; /* the precompiled expression */
|
||||
|
||||
int xptr; /* it this an XPointer expression */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -271,6 +271,12 @@ void xmlXPathFreeNodeSet (xmlNodeSetPtr obj);
|
||||
xmlXPathObjectPtr xmlXPathObjectCopy (xmlXPathObjectPtr val);
|
||||
int xmlXPathCmpNodes (xmlNodePtr node1,
|
||||
xmlNodePtr node2);
|
||||
/**
|
||||
* Conversion functions to basic types
|
||||
*/
|
||||
xmlXPathObjectPtr xmlXPathConvertBoolean (xmlXPathObjectPtr val);
|
||||
xmlXPathObjectPtr xmlXPathConvertNumber (xmlXPathObjectPtr val);
|
||||
xmlXPathObjectPtr xmlXPathConvertString (xmlXPathObjectPtr val);
|
||||
|
||||
/**
|
||||
* Context handling
|
||||
@ -288,13 +294,15 @@ xmlXPathObjectPtr xmlXPathEvalXPtrExpr (const xmlChar *str,
|
||||
xmlXPathContextPtr ctxt);
|
||||
xmlXPathObjectPtr xmlXPathEvalExpression (const xmlChar *str,
|
||||
xmlXPathContextPtr ctxt);
|
||||
int xmlXPathEvalPredicate (xmlXPathContextPtr ctxt,
|
||||
xmlXPathObjectPtr res);
|
||||
/**
|
||||
* Separate compilation/evaluation entry points
|
||||
*/
|
||||
xmlXPathCompExprPtr xmlXPathCompile (const xmlChar *str);
|
||||
xmlXPathObjectPtr xmlXPathCompiledEval (xmlXPathCompExprPtr comp,
|
||||
xmlXPathContextPtr ctx);
|
||||
|
||||
void xmlXPathFreeCompExpr (xmlXPathCompExprPtr comp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
379
xpath.c
379
xpath.c
@ -2351,6 +2351,7 @@ xmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) {
|
||||
ret->valueMax = 10;
|
||||
ret->value = NULL;
|
||||
|
||||
ret->context = ctxt;
|
||||
ret->comp = comp;
|
||||
|
||||
return(ret);
|
||||
@ -4444,6 +4445,71 @@ xmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
||||
xmlXPathFreeObject(cur);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* xmlXPathConvertString:
|
||||
* @val: an XPath object
|
||||
*
|
||||
* Converts an existing object to its string() equivalent
|
||||
*
|
||||
* Returns the new object, the old one is freed (or the operation
|
||||
* is done directly on @val)
|
||||
*/
|
||||
xmlXPathObjectPtr
|
||||
xmlXPathConvertString(xmlXPathObjectPtr val) {
|
||||
xmlXPathObjectPtr ret;
|
||||
|
||||
if (val == NULL)
|
||||
return(xmlXPathNewCString(""));
|
||||
switch (val->type) {
|
||||
case XPATH_UNDEFINED:
|
||||
#ifdef DEBUG_EXPR
|
||||
xmlGenericError(xmlGenericErrorContext, "String: undefined\n");
|
||||
#endif
|
||||
ret = xmlXPathNewCString("");
|
||||
break;
|
||||
case XPATH_XSLT_TREE:
|
||||
case XPATH_NODESET:
|
||||
if (val->nodesetval == NULL)
|
||||
ret = xmlXPathNewCString("");
|
||||
else if (val->nodesetval->nodeNr == 0) {
|
||||
ret = xmlXPathNewCString("");
|
||||
} else {
|
||||
xmlChar *res;
|
||||
|
||||
xmlXPathNodeSetSort(val->nodesetval);
|
||||
res = xmlNodeGetContent(val->nodesetval->nodeTab[0]);
|
||||
/* TODO: avoid allocating res to free it */
|
||||
ret = xmlXPathNewString(res);
|
||||
if (res != NULL)
|
||||
xmlFree(res);
|
||||
}
|
||||
break;
|
||||
case XPATH_STRING:
|
||||
return(val);
|
||||
case XPATH_BOOLEAN:
|
||||
if (val->boolval) ret = xmlXPathNewCString("true");
|
||||
else ret = xmlXPathNewCString("false");
|
||||
break;
|
||||
case XPATH_NUMBER: {
|
||||
char buf[100];
|
||||
|
||||
xmlXPathFormatNumber(val->floatval, buf, sizeof(buf));
|
||||
ret = xmlXPathNewCString(buf);
|
||||
break;
|
||||
}
|
||||
case XPATH_USERS:
|
||||
case XPATH_POINT:
|
||||
case XPATH_RANGE:
|
||||
case XPATH_LOCATIONSET:
|
||||
TODO
|
||||
ret = xmlXPathNewCString("");
|
||||
break;
|
||||
}
|
||||
xmlXPathFreeObject(val);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlXPathStringFunction:
|
||||
* @ctxt: the XPath Parser context
|
||||
@ -4492,54 +4558,8 @@ xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
||||
CHECK_ARITY(1);
|
||||
cur = valuePop(ctxt);
|
||||
if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
|
||||
switch (cur->type) {
|
||||
case XPATH_UNDEFINED:
|
||||
#ifdef DEBUG_EXPR
|
||||
xmlGenericError(xmlGenericErrorContext, "String: undefined\n");
|
||||
#endif
|
||||
valuePush(ctxt, xmlXPathNewCString(""));
|
||||
break;
|
||||
case XPATH_XSLT_TREE:
|
||||
case XPATH_NODESET:
|
||||
if (cur->nodesetval == NULL)
|
||||
valuePush(ctxt, xmlXPathNewCString(""));
|
||||
else if (cur->nodesetval->nodeNr == 0) {
|
||||
valuePush(ctxt, xmlXPathNewCString(""));
|
||||
} else {
|
||||
xmlChar *res;
|
||||
int i = 0; /* Should be first in document order !!!!! */
|
||||
res = xmlNodeGetContent(cur->nodesetval->nodeTab[i]);
|
||||
valuePush(ctxt, xmlXPathNewString(res));
|
||||
if (res != NULL)
|
||||
xmlFree(res);
|
||||
}
|
||||
xmlXPathFreeObject(cur);
|
||||
return;
|
||||
case XPATH_STRING:
|
||||
valuePush(ctxt, cur);
|
||||
return;
|
||||
case XPATH_BOOLEAN:
|
||||
if (cur->boolval) valuePush(ctxt, xmlXPathNewCString("true"));
|
||||
else valuePush(ctxt, xmlXPathNewCString("false"));
|
||||
xmlXPathFreeObject(cur);
|
||||
return;
|
||||
case XPATH_NUMBER: {
|
||||
char buf[100];
|
||||
|
||||
xmlXPathFormatNumber(cur->floatval, buf, sizeof(buf));
|
||||
valuePush(ctxt, xmlXPathNewCString(buf));
|
||||
xmlXPathFreeObject(cur);
|
||||
return;
|
||||
}
|
||||
case XPATH_USERS:
|
||||
case XPATH_POINT:
|
||||
case XPATH_RANGE:
|
||||
case XPATH_LOCATIONSET:
|
||||
TODO
|
||||
valuePush(ctxt, xmlXPathNewCString(""));
|
||||
break;
|
||||
}
|
||||
STRANGE
|
||||
cur = xmlXPathConvertString(cur);
|
||||
valuePush(ctxt, cur);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4995,6 +5015,47 @@ xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
||||
xmlXPathFreeObject(to);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlXPathConvertBoolean:
|
||||
* @val: an XPath object
|
||||
*
|
||||
* Converts an existing object to its boolean() equivalent
|
||||
*
|
||||
* Returns the new object, the old one is freed (or the operation
|
||||
* is done directly on @val)
|
||||
*/
|
||||
xmlXPathObjectPtr
|
||||
xmlXPathConvertBoolean(xmlXPathObjectPtr val) {
|
||||
int res = 0;
|
||||
|
||||
if (val == NULL)
|
||||
return(NULL);
|
||||
switch (val->type) {
|
||||
case XPATH_NODESET:
|
||||
case XPATH_XSLT_TREE:
|
||||
if ((val->nodesetval == NULL) ||
|
||||
(val->nodesetval->nodeNr == 0)) res = 0;
|
||||
else
|
||||
res = 1;
|
||||
break;
|
||||
case XPATH_STRING:
|
||||
if ((val->stringval == NULL) ||
|
||||
(val->stringval[0] == 0)) res = 0;
|
||||
else
|
||||
res = 1;
|
||||
break;
|
||||
case XPATH_BOOLEAN:
|
||||
return(val);
|
||||
case XPATH_NUMBER:
|
||||
if (val->floatval) res = 1;
|
||||
break;
|
||||
default:
|
||||
STRANGE
|
||||
}
|
||||
xmlXPathFreeObject(val);
|
||||
return(xmlXPathNewBoolean(res));
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlXPathBooleanFunction:
|
||||
* @ctxt: the XPath Parser context
|
||||
@ -5011,36 +5072,12 @@ xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
||||
void
|
||||
xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
||||
xmlXPathObjectPtr cur;
|
||||
int res = 0;
|
||||
|
||||
CHECK_ARITY(1);
|
||||
cur = valuePop(ctxt);
|
||||
if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
|
||||
switch (cur->type) {
|
||||
case XPATH_NODESET:
|
||||
case XPATH_XSLT_TREE:
|
||||
if ((cur->nodesetval == NULL) ||
|
||||
(cur->nodesetval->nodeNr == 0)) res = 0;
|
||||
else
|
||||
res = 1;
|
||||
break;
|
||||
case XPATH_STRING:
|
||||
if ((cur->stringval == NULL) ||
|
||||
(cur->stringval[0] == 0)) res = 0;
|
||||
else
|
||||
res = 1;
|
||||
break;
|
||||
case XPATH_BOOLEAN:
|
||||
valuePush(ctxt, cur);
|
||||
return;
|
||||
case XPATH_NUMBER:
|
||||
if (cur->floatval) res = 1;
|
||||
break;
|
||||
default:
|
||||
STRANGE
|
||||
}
|
||||
xmlXPathFreeObject(cur);
|
||||
valuePush(ctxt, xmlXPathNewBoolean(res));
|
||||
cur = xmlXPathConvertBoolean(cur);
|
||||
valuePush(ctxt, cur);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -5135,6 +5172,55 @@ not_equal:
|
||||
valuePush(ctxt, xmlXPathNewBoolean(ret));
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlXPathConvertNumber:
|
||||
* @val: an XPath object
|
||||
*
|
||||
* Converts an existing object to its number() equivalent
|
||||
*
|
||||
* Returns the new object, the old one is freed (or the operation
|
||||
* is done directly on @val)
|
||||
*/
|
||||
xmlXPathObjectPtr
|
||||
xmlXPathConvertNumber(xmlXPathObjectPtr val) {
|
||||
xmlXPathObjectPtr ret;
|
||||
double res;
|
||||
|
||||
if (val == NULL)
|
||||
return(xmlXPathNewFloat(0.0));
|
||||
switch (val->type) {
|
||||
case XPATH_UNDEFINED:
|
||||
#ifdef DEBUG_EXPR
|
||||
xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n");
|
||||
#endif
|
||||
ret = xmlXPathNewFloat(0.0);
|
||||
break;
|
||||
case XPATH_XSLT_TREE:
|
||||
case XPATH_NODESET:
|
||||
val = xmlXPathConvertString(val);
|
||||
/* no break on purpose */
|
||||
case XPATH_STRING:
|
||||
res = xmlXPathStringEvalNumber(val->stringval);
|
||||
ret = xmlXPathNewFloat(res);
|
||||
break;
|
||||
case XPATH_BOOLEAN:
|
||||
if (val->boolval) ret = xmlXPathNewFloat(1.0);
|
||||
else ret = xmlXPathNewFloat(0.0);
|
||||
break;
|
||||
case XPATH_NUMBER:
|
||||
return(val);
|
||||
case XPATH_USERS:
|
||||
case XPATH_POINT:
|
||||
case XPATH_RANGE:
|
||||
case XPATH_LOCATIONSET:
|
||||
TODO
|
||||
ret = xmlXPathNewFloat(0.0);
|
||||
break;
|
||||
}
|
||||
xmlXPathFreeObject(val);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlXPathNumberFunction:
|
||||
* @ctxt: the XPath Parser context
|
||||
@ -5163,40 +5249,8 @@ xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
||||
|
||||
CHECK_ARITY(1);
|
||||
cur = valuePop(ctxt);
|
||||
switch (cur->type) {
|
||||
case XPATH_UNDEFINED:
|
||||
#ifdef DEBUG_EXPR
|
||||
xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n");
|
||||
#endif
|
||||
valuePush(ctxt, xmlXPathNewFloat(0.0));
|
||||
break;
|
||||
case XPATH_XSLT_TREE:
|
||||
case XPATH_NODESET:
|
||||
valuePush(ctxt, cur);
|
||||
xmlXPathStringFunction(ctxt, 1);
|
||||
cur = valuePop(ctxt);
|
||||
case XPATH_STRING:
|
||||
res = xmlXPathStringEvalNumber(cur->stringval);
|
||||
valuePush(ctxt, xmlXPathNewFloat(res));
|
||||
xmlXPathFreeObject(cur);
|
||||
return;
|
||||
case XPATH_BOOLEAN:
|
||||
if (cur->boolval) valuePush(ctxt, xmlXPathNewFloat(1.0));
|
||||
else valuePush(ctxt, xmlXPathNewFloat(0.0));
|
||||
xmlXPathFreeObject(cur);
|
||||
return;
|
||||
case XPATH_NUMBER:
|
||||
valuePush(ctxt, cur);
|
||||
return;
|
||||
case XPATH_USERS:
|
||||
case XPATH_POINT:
|
||||
case XPATH_RANGE:
|
||||
case XPATH_LOCATIONSET:
|
||||
TODO
|
||||
valuePush(ctxt, xmlXPathNewFloat(0.0));
|
||||
break;
|
||||
}
|
||||
STRANGE
|
||||
cur = xmlXPathConvertNumber(cur);
|
||||
valuePush(ctxt, cur);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -5535,6 +5589,50 @@ xmlXPathCompNumber(xmlXPathParserContextPtr ctxt) {
|
||||
xmlXPathNewFloat(ret), NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlXPathParseLiteral:
|
||||
* @ctxt: the XPath Parser context
|
||||
*
|
||||
* Parse a Literal
|
||||
*
|
||||
* [29] Literal ::= '"' [^"]* '"'
|
||||
* | "'" [^']* "'"
|
||||
*
|
||||
* Returns the value found or NULL in case of error
|
||||
*/
|
||||
static xmlChar *
|
||||
xmlXPathParseLiteral(xmlXPathParserContextPtr ctxt) {
|
||||
const xmlChar *q;
|
||||
xmlChar *ret = NULL;
|
||||
|
||||
if (CUR == '"') {
|
||||
NEXT;
|
||||
q = CUR_PTR;
|
||||
while ((IS_CHAR(CUR)) && (CUR != '"'))
|
||||
NEXT;
|
||||
if (!IS_CHAR(CUR)) {
|
||||
XP_ERROR0(XPATH_UNFINISHED_LITERAL_ERROR);
|
||||
} else {
|
||||
ret = xmlStrndup(q, CUR_PTR - q);
|
||||
NEXT;
|
||||
}
|
||||
} else if (CUR == '\'') {
|
||||
NEXT;
|
||||
q = CUR_PTR;
|
||||
while ((IS_CHAR(CUR)) && (CUR != '\''))
|
||||
NEXT;
|
||||
if (!IS_CHAR(CUR)) {
|
||||
XP_ERROR0(XPATH_UNFINISHED_LITERAL_ERROR);
|
||||
} else {
|
||||
ret = xmlStrndup(q, CUR_PTR - q);
|
||||
NEXT;
|
||||
}
|
||||
} else {
|
||||
XP_ERROR0(XPATH_START_LITERAL_ERROR);
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlXPathCompLiteral:
|
||||
* @ctxt: the XPath Parser context
|
||||
@ -5613,6 +5711,7 @@ xmlXPathCompVariableReference(xmlXPathParserContextPtr ctxt) {
|
||||
if (name == NULL) {
|
||||
XP_ERROR(XPATH_VARIABLE_REF_ERROR);
|
||||
}
|
||||
ctxt->comp->last = -1;
|
||||
PUSH_LONG_EXPR(XPATH_OP_VARIABLE, 0, 0, 0,
|
||||
name, prefix);
|
||||
SKIP_BLANKS;
|
||||
@ -6369,13 +6468,8 @@ xmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
|
||||
if (name != NULL)
|
||||
xmlFree(name);
|
||||
|
||||
xmlXPathCompLiteral(ctxt);
|
||||
name = xmlXPathParseLiteral(ctxt);
|
||||
CHECK_ERROR 0;
|
||||
xmlXPathStringFunction(ctxt, 1);
|
||||
CHECK_ERROR0;
|
||||
cur = valuePop(ctxt);
|
||||
name = xmlStrdup(cur->stringval);
|
||||
xmlXPathFreeObject(cur);
|
||||
SKIP_BLANKS;
|
||||
}
|
||||
if (CUR != ')') {
|
||||
@ -6391,14 +6485,22 @@ xmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
|
||||
NEXT;
|
||||
|
||||
/*
|
||||
* get the namespace name for this prefix
|
||||
* Since currently the parser context don't have a
|
||||
* namespace list associated:
|
||||
* The namespace name for this prefix can be computed
|
||||
* only at evaluation time. The compilation is done
|
||||
* outside of any context.
|
||||
*/
|
||||
#if 0
|
||||
*prefix = xmlXPathNsLookup(ctxt->context, name);
|
||||
if (name != NULL)
|
||||
xmlFree(name);
|
||||
if (*prefix == NULL) {
|
||||
XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR);
|
||||
}
|
||||
#else
|
||||
*prefix = name;
|
||||
#endif
|
||||
|
||||
if (CUR == '*') {
|
||||
/*
|
||||
@ -6574,7 +6676,7 @@ xmlXPathCompStep(xmlXPathParserContextPtr ctxt) {
|
||||
* The modification needed for XPointer change to the production
|
||||
*/
|
||||
#ifdef LIBXML_XPTR_ENABLED
|
||||
if (ctxt->context->xptr) {
|
||||
if (ctxt->xptr) {
|
||||
name = xmlXPathParseNCName(ctxt);
|
||||
if ((name != NULL) && (xmlStrEqual(name, BAD_CAST "range-to"))) {
|
||||
int op1 = ctxt->comp->last;
|
||||
@ -6758,7 +6860,7 @@ xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt) {
|
||||
*
|
||||
* Evaluate the Precompiled XPath operation
|
||||
*/
|
||||
void
|
||||
static void
|
||||
xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) {
|
||||
int equal, ret;
|
||||
xmlXPathCompExprPtr comp;
|
||||
@ -7188,7 +7290,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) {
|
||||
*
|
||||
* Evaluate the Precompiled XPath expression in the given context.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
xmlXPathRunEval(xmlXPathParserContextPtr ctxt) {
|
||||
xmlXPathCompExprPtr comp;
|
||||
|
||||
@ -7219,6 +7321,42 @@ xmlXPathRunEval(xmlXPathParserContextPtr ctxt) {
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* xmlXPathEvalPredicate:
|
||||
* @ctxt: the XPath context
|
||||
* @res: the Predicate Expression evaluation result
|
||||
*
|
||||
* Evaluate a predicate result for the current node.
|
||||
* A PredicateExpr is evaluated by evaluating the Expr and converting
|
||||
* the result to a boolean. If the result is a number, the result will
|
||||
* be converted to true if the number is equal to the position of the
|
||||
* context node in the context node list (as returned by the position
|
||||
* function) and will be converted to false otherwise; if the result
|
||||
* is not a number, then the result will be converted as if by a call
|
||||
* to the boolean function.
|
||||
*
|
||||
* Return 1 if predicate is true, 0 otherwise
|
||||
*/
|
||||
int
|
||||
xmlXPathEvalPredicate(xmlXPathContextPtr ctxt, xmlXPathObjectPtr res) {
|
||||
if (res == NULL) return(0);
|
||||
switch (res->type) {
|
||||
case XPATH_BOOLEAN:
|
||||
return(res->boolval);
|
||||
case XPATH_NUMBER:
|
||||
return(res->floatval == ctxt->proximityPosition);
|
||||
case XPATH_NODESET:
|
||||
case XPATH_XSLT_TREE:
|
||||
return(res->nodesetval->nodeNr != 0);
|
||||
case XPATH_STRING:
|
||||
return((res->stringval != NULL) &&
|
||||
(xmlStrlen(res->stringval) != 0));
|
||||
default:
|
||||
STRANGE
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlXPathEvaluatePredicateResult:
|
||||
* @ctxt: the XPath Parser context
|
||||
@ -7310,9 +7448,6 @@ xmlXPathCompiledEval(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctx) {
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"xmlXPathEval: evaluation failed\n");
|
||||
res = NULL;
|
||||
} else if (*ctxt->cur != 0) {
|
||||
xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
|
||||
res = NULL;
|
||||
} else {
|
||||
res = valuePop(ctxt);
|
||||
}
|
||||
@ -7329,13 +7464,13 @@ xmlXPathCompiledEval(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctx) {
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"xmlXPathEval: %d object left on the stack\n",
|
||||
stack);
|
||||
xmlXPathDebugDumpCompExpr(stdout, ctxt->comp, 0);
|
||||
}
|
||||
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
||||
xmlXPathFreeObject(res);
|
||||
res = NULL;
|
||||
}
|
||||
|
||||
xmlXPathDebugDumpCompExpr(stdout, ctxt->comp, 0);
|
||||
|
||||
ctxt->comp = NULL;
|
||||
xmlXPathFreeParserContext(ctxt);
|
||||
|
12
xpath.h
12
xpath.h
@ -244,7 +244,7 @@ struct _xmlXPathParserContext {
|
||||
xmlXPathObjectPtr *valueTab; /* stack of values */
|
||||
|
||||
xmlXPathCompExprPtr comp; /* the precompiled expression */
|
||||
|
||||
int xptr; /* it this an XPointer expression */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -271,6 +271,12 @@ void xmlXPathFreeNodeSet (xmlNodeSetPtr obj);
|
||||
xmlXPathObjectPtr xmlXPathObjectCopy (xmlXPathObjectPtr val);
|
||||
int xmlXPathCmpNodes (xmlNodePtr node1,
|
||||
xmlNodePtr node2);
|
||||
/**
|
||||
* Conversion functions to basic types
|
||||
*/
|
||||
xmlXPathObjectPtr xmlXPathConvertBoolean (xmlXPathObjectPtr val);
|
||||
xmlXPathObjectPtr xmlXPathConvertNumber (xmlXPathObjectPtr val);
|
||||
xmlXPathObjectPtr xmlXPathConvertString (xmlXPathObjectPtr val);
|
||||
|
||||
/**
|
||||
* Context handling
|
||||
@ -288,13 +294,15 @@ xmlXPathObjectPtr xmlXPathEvalXPtrExpr (const xmlChar *str,
|
||||
xmlXPathContextPtr ctxt);
|
||||
xmlXPathObjectPtr xmlXPathEvalExpression (const xmlChar *str,
|
||||
xmlXPathContextPtr ctxt);
|
||||
int xmlXPathEvalPredicate (xmlXPathContextPtr ctxt,
|
||||
xmlXPathObjectPtr res);
|
||||
/**
|
||||
* Separate compilation/evaluation entry points
|
||||
*/
|
||||
xmlXPathCompExprPtr xmlXPathCompile (const xmlChar *str);
|
||||
xmlXPathObjectPtr xmlXPathCompiledEval (xmlXPathCompExprPtr comp,
|
||||
xmlXPathContextPtr ctx);
|
||||
|
||||
void xmlXPathFreeCompExpr (xmlXPathCompExprPtr comp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1292,6 +1292,7 @@ xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {
|
||||
return(NULL);
|
||||
|
||||
ctxt = xmlXPathNewParserContext(str, ctx);
|
||||
ctxt->xptr = 1;
|
||||
xmlXPtrEvalXPointer(ctxt);
|
||||
|
||||
if ((ctxt->value != NULL) &&
|
||||
|
Loading…
x
Reference in New Issue
Block a user