mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-07-29 11:41:22 +03:00
XPath fixes and cleanup, 2 general bug fixes:
- xpath.[ch] : fixed some serious XPath Predicate evaluation problems - Makefile.am : added XPath regression tests to normal tests - uri.c: fixed a problem with local paths, cleanup - parser.c: fixed a problem with large CData sections Daniel
This commit is contained in:
@ -1,3 +1,11 @@
|
|||||||
|
Sun Oct 1 16:28:22 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
|
||||||
|
|
||||||
|
* xpath.[ch] : fixed some serious XPath Predicate evaluation
|
||||||
|
problems
|
||||||
|
* Makefile.am : added XPath regression tests to normal tests
|
||||||
|
* uri.c: fixed a problem with local paths, cleanup
|
||||||
|
* parser.c: fixed a problem with large CData sections
|
||||||
|
|
||||||
Sat Sep 30 16:35:54 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
|
Sat Sep 30 16:35:54 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
|
||||||
|
|
||||||
* configure.in xml-config.in: patch from "Ben Taylor"
|
* configure.in xml-config.in: patch from "Ben Taylor"
|
||||||
|
@ -99,9 +99,9 @@ install-data: $(srcdir)/libxml
|
|||||||
|
|
||||||
$(libxml_la_SOURCES): $(srcdir)/libxml
|
$(libxml_la_SOURCES): $(srcdir)/libxml
|
||||||
|
|
||||||
testall : tests SVGtests SAXtests XPathtests
|
testall : tests SVGtests SAXtests
|
||||||
|
|
||||||
tests: XMLtests XMLenttests HTMLtests Validtests URItests
|
tests: XMLtests XMLenttests HTMLtests Validtests URItests XPathtests
|
||||||
|
|
||||||
HTMLtests : testHTML
|
HTMLtests : testHTML
|
||||||
@(rm -f .memdump ; touch .memdump)
|
@(rm -f .memdump ; touch .memdump)
|
||||||
|
@ -45,17 +45,19 @@ struct _xmlNodeSet {
|
|||||||
* @@ XPointer will add more types !
|
* @@ XPointer will add more types !
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define XPATH_UNDEFINED 0
|
typedef enum {
|
||||||
#define XPATH_NODESET 1
|
XPATH_UNDEFINED = 0,
|
||||||
#define XPATH_BOOLEAN 2
|
XPATH_NODESET = 1,
|
||||||
#define XPATH_NUMBER 3
|
XPATH_BOOLEAN = 2,
|
||||||
#define XPATH_STRING 4
|
XPATH_NUMBER = 3,
|
||||||
#define XPATH_USERS 5
|
XPATH_STRING = 4,
|
||||||
|
XPATH_USERS = 5
|
||||||
|
} xmlXPathObjectType;
|
||||||
|
|
||||||
typedef struct _xmlXPathObject xmlXPathObject;
|
typedef struct _xmlXPathObject xmlXPathObject;
|
||||||
typedef xmlXPathObject *xmlXPathObjectPtr;
|
typedef xmlXPathObject *xmlXPathObjectPtr;
|
||||||
struct _xmlXPathObject {
|
struct _xmlXPathObject {
|
||||||
int type;
|
xmlXPathObjectType type;
|
||||||
xmlNodeSetPtr nodesetval;
|
xmlNodeSetPtr nodesetval;
|
||||||
int boolval;
|
int boolval;
|
||||||
double floatval;
|
double floatval;
|
||||||
@ -163,6 +165,10 @@ struct _xmlXPathContext {
|
|||||||
xmlNsPtr *namespaces; /* The namespaces lookup */
|
xmlNsPtr *namespaces; /* The namespaces lookup */
|
||||||
int nsNr; /* the current Namespace index */
|
int nsNr; /* the current Namespace index */
|
||||||
void *user; /* user defined extra info */
|
void *user; /* user defined extra info */
|
||||||
|
|
||||||
|
/* extra variables */
|
||||||
|
int contextSize; /* the context size */
|
||||||
|
int proximityPosition; /* the proximity position */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
6
parser.c
6
parser.c
@ -6014,6 +6014,7 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
|
|||||||
int r, rl;
|
int r, rl;
|
||||||
int s, sl;
|
int s, sl;
|
||||||
int cur, l;
|
int cur, l;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
if ((NXT(0) == '<') && (NXT(1) == '!') &&
|
if ((NXT(0) == '<') && (NXT(1) == '!') &&
|
||||||
(NXT(2) == '[') && (NXT(3) == 'C') &&
|
(NXT(2) == '[') && (NXT(3) == 'C') &&
|
||||||
@ -6070,6 +6071,11 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
|
|||||||
rl = sl;
|
rl = sl;
|
||||||
s = cur;
|
s = cur;
|
||||||
sl = l;
|
sl = l;
|
||||||
|
count++;
|
||||||
|
if (count > 50) {
|
||||||
|
GROW;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
NEXTL(l);
|
NEXTL(l);
|
||||||
cur = CUR_CHAR(l);
|
cur = CUR_CHAR(l);
|
||||||
}
|
}
|
||||||
|
52
uri.c
52
uri.c
@ -1372,16 +1372,11 @@ xmlNormalizeURIPath(char *path) {
|
|||||||
xmlChar *
|
xmlChar *
|
||||||
xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
|
xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
|
||||||
xmlChar *val = NULL;
|
xmlChar *val = NULL;
|
||||||
int ret, len, index, cur, out;
|
int ret, ret2, len, index, cur, out;
|
||||||
xmlURIPtr ref = NULL;
|
xmlURIPtr ref = NULL;
|
||||||
xmlURIPtr bas = NULL;
|
xmlURIPtr bas = NULL;
|
||||||
xmlURIPtr res = NULL;
|
xmlURIPtr res = NULL;
|
||||||
|
|
||||||
if ((URI == NULL) && (base == NULL))
|
|
||||||
return(NULL);
|
|
||||||
if (URI == NULL)
|
|
||||||
return((xmlChar *) xmlMemStrdup((const char *) base));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 1) The URI reference is parsed into the potential four components and
|
* 1) The URI reference is parsed into the potential four components and
|
||||||
* fragment identifier, as described in Section 4.3.
|
* fragment identifier, as described in Section 4.3.
|
||||||
@ -1390,20 +1385,43 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
|
|||||||
* as a reference to "." rather than as a synonym for the current
|
* as a reference to "." rather than as a synonym for the current
|
||||||
* URI. Should we do that here?
|
* URI. Should we do that here?
|
||||||
*/
|
*/
|
||||||
ref = xmlCreateURI();
|
if (URI == NULL)
|
||||||
if (ref == NULL)
|
ret = -1;
|
||||||
goto done;
|
else {
|
||||||
if (*URI) {
|
ref = xmlCreateURI();
|
||||||
ret = xmlParseURIReference(ref, (const char *) URI);
|
if (ref == NULL)
|
||||||
if (ret != 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
|
if (*URI)
|
||||||
|
ret = xmlParseURIReference(ref, (const char *) URI);
|
||||||
|
else
|
||||||
|
ret = -1;
|
||||||
}
|
}
|
||||||
bas = xmlCreateURI();
|
if (base == NULL)
|
||||||
if (bas == NULL)
|
ret2 = -1;
|
||||||
|
else {
|
||||||
|
bas = xmlCreateURI();
|
||||||
|
if (bas == NULL)
|
||||||
|
goto done;
|
||||||
|
ret2 = xmlParseURIReference(bas, (const char *) base);
|
||||||
|
}
|
||||||
|
if ((ret != 0) && (ret2 != 0))
|
||||||
goto done;
|
goto done;
|
||||||
ret = xmlParseURIReference(bas, (const char *) base);
|
if (ret != 0) {
|
||||||
if (ret != 0)
|
/*
|
||||||
|
* the base fragment must be ignored
|
||||||
|
*/
|
||||||
|
if (bas->fragment != NULL) {
|
||||||
|
xmlFree(bas->fragment);
|
||||||
|
bas->fragment = NULL;
|
||||||
|
}
|
||||||
|
val = xmlSaveUri(bas);
|
||||||
goto done;
|
goto done;
|
||||||
|
}
|
||||||
|
if (ret2 != 0) {
|
||||||
|
val = xmlSaveUri(ref);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2) If the path component is empty and the scheme, authority, and
|
* 2) If the path component is empty and the scheme, authority, and
|
||||||
@ -1552,7 +1570,7 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
|
|||||||
/*
|
/*
|
||||||
* Ensure the path includes a '/'
|
* Ensure the path includes a '/'
|
||||||
*/
|
*/
|
||||||
if (out == 0)
|
if ((out == 0) && (bas->server != NULL))
|
||||||
res->path[out++] = '/';
|
res->path[out++] = '/';
|
||||||
while (ref->path[index] != 0) {
|
while (ref->path[index] != 0) {
|
||||||
res->path[out++] = ref->path[index++];
|
res->path[out++] = ref->path[index++];
|
||||||
|
131
xpath.c
131
xpath.c
@ -262,6 +262,8 @@ PUSH_AND_POP(xmlXPathObjectPtr, value)
|
|||||||
#define XPATH_INVALID_OPERAND 10
|
#define XPATH_INVALID_OPERAND 10
|
||||||
#define XPATH_INVALID_TYPE 11
|
#define XPATH_INVALID_TYPE 11
|
||||||
#define XPATH_INVALID_ARITY 12
|
#define XPATH_INVALID_ARITY 12
|
||||||
|
#define XPATH_INVALID_CTXT_SIZE 13
|
||||||
|
#define XPATH_INVALID_CTXT_POSITION 14
|
||||||
|
|
||||||
const char *xmlXPathErrorMessages[] = {
|
const char *xmlXPathErrorMessages[] = {
|
||||||
"Ok",
|
"Ok",
|
||||||
@ -277,6 +279,8 @@ const char *xmlXPathErrorMessages[] = {
|
|||||||
"Invalid operand",
|
"Invalid operand",
|
||||||
"Invalid type",
|
"Invalid type",
|
||||||
"Invalid number of arguments",
|
"Invalid number of arguments",
|
||||||
|
"Invalid context size",
|
||||||
|
"Invalid context position",
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -835,6 +839,9 @@ xmlXPathNewContext(xmlDocPtr doc) {
|
|||||||
ret->namespaces = NULL;
|
ret->namespaces = NULL;
|
||||||
ret->user = NULL;
|
ret->user = NULL;
|
||||||
ret->nsNr = 0;
|
ret->nsNr = 0;
|
||||||
|
|
||||||
|
ret->contextSize = -1;
|
||||||
|
ret->proximityPosition = -1;
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2191,13 +2198,13 @@ xmlXPathRoot(xmlXPathParserContextPtr ctxt) {
|
|||||||
void
|
void
|
||||||
xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
||||||
CHECK_ARITY(0);
|
CHECK_ARITY(0);
|
||||||
if ((ctxt->context->nodelist == NULL) ||
|
if (ctxt->context->contextSize > 0) {
|
||||||
(ctxt->context->node == NULL) ||
|
valuePush(ctxt, xmlXPathNewFloat((double) ctxt->context->contextSize));
|
||||||
(ctxt->context->nodelist->nodeNr == 0)) {
|
#ifdef DEBUG_EXPR
|
||||||
valuePush(ctxt, xmlXPathNewFloat((double) 0));
|
fprintf(xmlXPathDebug, "last() : %d\n", ctxt->context->contextSize);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
valuePush(ctxt,
|
XP_ERROR(XPATH_INVALID_CTXT_SIZE);
|
||||||
xmlXPathNewFloat((double) ctxt->context->nodelist->nodeNr));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2212,21 +2219,17 @@ xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
||||||
int i;
|
|
||||||
|
|
||||||
CHECK_ARITY(0);
|
CHECK_ARITY(0);
|
||||||
if ((ctxt->context->nodelist == NULL) ||
|
if (ctxt->context->proximityPosition > 0) {
|
||||||
(ctxt->context->node == NULL) ||
|
valuePush(ctxt,
|
||||||
(ctxt->context->nodelist->nodeNr == 0)) {
|
xmlXPathNewFloat((double) ctxt->context->proximityPosition));
|
||||||
valuePush(ctxt, xmlXPathNewFloat((double) 0));
|
#ifdef DEBUG_EXPR
|
||||||
|
fprintf(xmlXPathDebug, "position() : %d\n",
|
||||||
|
ctxt->context->proximityPosition);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
XP_ERROR(XPATH_INVALID_CTXT_POSITION);
|
||||||
}
|
}
|
||||||
for (i = 0; i < ctxt->context->nodelist->nodeNr;i++) {
|
|
||||||
if (ctxt->context->node == ctxt->context->nodelist->nodeTab[i]) {
|
|
||||||
valuePush(ctxt, xmlXPathNewFloat((double) i + 1));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
valuePush(ctxt, xmlXPathNewFloat((double) 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4137,13 +4140,13 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
|
xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
|
||||||
xmlXPathObjectPtr res, int index) {
|
xmlXPathObjectPtr res) {
|
||||||
if (res == NULL) return(0);
|
if (res == NULL) return(0);
|
||||||
switch (res->type) {
|
switch (res->type) {
|
||||||
case XPATH_BOOLEAN:
|
case XPATH_BOOLEAN:
|
||||||
return(res->boolval);
|
return(res->boolval);
|
||||||
case XPATH_NUMBER:
|
case XPATH_NUMBER:
|
||||||
return(res->floatval == index);
|
return(res->floatval == ctxt->context->proximityPosition);
|
||||||
case XPATH_NODESET:
|
case XPATH_NODESET:
|
||||||
return(res->nodesetval->nodeNr != 0);
|
return(res->nodesetval->nodeNr != 0);
|
||||||
case XPATH_STRING:
|
case XPATH_STRING:
|
||||||
@ -4162,6 +4165,15 @@ xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
|
|||||||
* [8] Predicate ::= '[' PredicateExpr ']'
|
* [8] Predicate ::= '[' PredicateExpr ']'
|
||||||
* [9] PredicateExpr ::= Expr
|
* [9] PredicateExpr ::= Expr
|
||||||
*
|
*
|
||||||
|
* ---------------------
|
||||||
|
* For each node in the node-set to be filtered, the PredicateExpr is
|
||||||
|
* evaluated with that node as the context node, with the number of nodes
|
||||||
|
* in the node-set as the context size, and with the proximity position
|
||||||
|
* of the node in the node-set with respect to the axis as the context
|
||||||
|
* position; if PredicateExpr evaluates to true for that node, the node
|
||||||
|
* is included in the new node-set; otherwise, it is not included.
|
||||||
|
* ---------------------
|
||||||
|
*
|
||||||
* Parse and evaluate a predicate for all the elements of the
|
* Parse and evaluate a predicate for all the elements of the
|
||||||
* current node list. Then refine the list by removing all
|
* current node list. Then refine the list by removing all
|
||||||
* nodes where the predicate is false.
|
* nodes where the predicate is false.
|
||||||
@ -4169,8 +4181,9 @@ xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
|
|||||||
void
|
void
|
||||||
xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt) {
|
xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt) {
|
||||||
const xmlChar *cur;
|
const xmlChar *cur;
|
||||||
xmlXPathObjectPtr res, listHolder = NULL;
|
xmlXPathObjectPtr res;
|
||||||
xmlNodeSetPtr newset = NULL;
|
xmlNodeSetPtr newset = NULL;
|
||||||
|
xmlNodeSetPtr oldset;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
@ -4179,59 +4192,75 @@ xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt) {
|
|||||||
}
|
}
|
||||||
NEXT;
|
NEXT;
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
if ((ctxt->context->nodelist == NULL) ||
|
|
||||||
(ctxt->context->nodelist->nodeNr == 0)) {
|
/*
|
||||||
ctxt->context->node = NULL;
|
* Extract the old set, and then evaluate the result of the
|
||||||
|
* expression for all the element in the set. use it to grow
|
||||||
|
* up a new set.
|
||||||
|
*/
|
||||||
|
oldset = ctxt->context->nodelist;
|
||||||
|
ctxt->context->nodelist = NULL;
|
||||||
|
ctxt->context->node = NULL;
|
||||||
|
|
||||||
|
if ((oldset == NULL) || (oldset->nodeNr == 0)) {
|
||||||
xmlXPathEvalExpr(ctxt);
|
xmlXPathEvalExpr(ctxt);
|
||||||
CHECK_ERROR;
|
CHECK_ERROR;
|
||||||
|
ctxt->context->contextSize = 0;
|
||||||
|
ctxt->context->proximityPosition = 0;
|
||||||
res = valuePop(ctxt);
|
res = valuePop(ctxt);
|
||||||
if (res != NULL)
|
if (res != NULL)
|
||||||
xmlXPathFreeObject(res);
|
xmlXPathFreeObject(res);
|
||||||
} else {
|
} else {
|
||||||
|
/*
|
||||||
|
* Save the expression pointer since we will have to evaluate
|
||||||
|
* it multiple times. Initialize the new set.
|
||||||
|
*/
|
||||||
cur = ctxt->cur;
|
cur = ctxt->cur;
|
||||||
newset = xmlXPathNodeSetCreate(NULL);
|
newset = xmlXPathNodeSetCreate(NULL);
|
||||||
|
|
||||||
/* Create a copy of the current node set because it is important: */
|
for (i = 0; i < oldset->nodeNr; i++) {
|
||||||
listHolder = xmlXPathNewNodeSetList(ctxt->context->nodelist);
|
|
||||||
|
|
||||||
for (i = 0; i < ctxt->context->nodelist->nodeNr; i++) {
|
|
||||||
ctxt->cur = cur;
|
ctxt->cur = cur;
|
||||||
ctxt->context->node = ctxt->context->nodelist->nodeTab[i];
|
|
||||||
|
|
||||||
/* This nodeset is useful for the loop but no, longer necessary this iteration: */
|
/*
|
||||||
if (ctxt->context->nodelist != NULL)
|
* Run the evaluation with a node list made of a single item
|
||||||
xmlXPathFreeNodeSet(ctxt->context->nodelist);
|
* in the nodeset.
|
||||||
|
*/
|
||||||
/* This line was missed out: */
|
ctxt->context->node = oldset->nodeTab[i];
|
||||||
ctxt->context->nodelist = xmlXPathNodeSetCreate(ctxt->context->node);
|
ctxt->context->nodelist = NULL;
|
||||||
|
ctxt->context->contextSize = oldset->nodeNr;
|
||||||
|
ctxt->context->proximityPosition = i + 1;
|
||||||
|
|
||||||
xmlXPathEvalExpr(ctxt);
|
xmlXPathEvalExpr(ctxt);
|
||||||
CHECK_ERROR;
|
CHECK_ERROR;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The result of the evaluation need to be tested to
|
||||||
|
* decided whether the filter succeeded or not
|
||||||
|
*/
|
||||||
res = valuePop(ctxt);
|
res = valuePop(ctxt);
|
||||||
if (xmlXPathEvaluatePredicateResult(ctxt, res, i + 1))
|
if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
|
||||||
{
|
xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
|
||||||
/* Add the current node as the result has proven correct: */
|
}
|
||||||
xmlXPathNodeSetAdd(newset, listHolder->nodesetval->nodeTab[i]);
|
|
||||||
}
|
|
||||||
if (res != NULL)
|
if (res != NULL)
|
||||||
xmlXPathFreeObject(res);
|
xmlXPathFreeObject(res);
|
||||||
|
|
||||||
/* Copy the contents of the temporary list back to the node list for the next round: */
|
ctxt->context->node = NULL;
|
||||||
ctxt->context->nodelist = xmlXPathNewNodeSetList(listHolder->nodesetval)->nodesetval;
|
|
||||||
}
|
}
|
||||||
if (ctxt->context->nodelist != NULL)
|
|
||||||
xmlXPathFreeNodeSet(ctxt->context->nodelist);
|
/*
|
||||||
|
* The result is used as the new evaluation set.
|
||||||
/* Clean up after temporary variable holder: */
|
*/
|
||||||
if (listHolder != NULL)
|
|
||||||
xmlXPathFreeObject(listHolder);
|
|
||||||
|
|
||||||
ctxt->context->nodelist = newset;
|
ctxt->context->nodelist = newset;
|
||||||
ctxt->context->node = NULL;
|
ctxt->context->node = NULL;
|
||||||
|
ctxt->context->contextSize = -1;
|
||||||
|
ctxt->context->proximityPosition = -1;
|
||||||
}
|
}
|
||||||
if (CUR != ']') {
|
if (CUR != ']') {
|
||||||
XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
|
XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
|
||||||
}
|
}
|
||||||
|
if (oldset != NULL)
|
||||||
|
xmlXPathFreeNodeSet(oldset);
|
||||||
|
|
||||||
NEXT;
|
NEXT;
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
|
20
xpath.h
20
xpath.h
@ -45,17 +45,19 @@ struct _xmlNodeSet {
|
|||||||
* @@ XPointer will add more types !
|
* @@ XPointer will add more types !
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define XPATH_UNDEFINED 0
|
typedef enum {
|
||||||
#define XPATH_NODESET 1
|
XPATH_UNDEFINED = 0,
|
||||||
#define XPATH_BOOLEAN 2
|
XPATH_NODESET = 1,
|
||||||
#define XPATH_NUMBER 3
|
XPATH_BOOLEAN = 2,
|
||||||
#define XPATH_STRING 4
|
XPATH_NUMBER = 3,
|
||||||
#define XPATH_USERS 5
|
XPATH_STRING = 4,
|
||||||
|
XPATH_USERS = 5
|
||||||
|
} xmlXPathObjectType;
|
||||||
|
|
||||||
typedef struct _xmlXPathObject xmlXPathObject;
|
typedef struct _xmlXPathObject xmlXPathObject;
|
||||||
typedef xmlXPathObject *xmlXPathObjectPtr;
|
typedef xmlXPathObject *xmlXPathObjectPtr;
|
||||||
struct _xmlXPathObject {
|
struct _xmlXPathObject {
|
||||||
int type;
|
xmlXPathObjectType type;
|
||||||
xmlNodeSetPtr nodesetval;
|
xmlNodeSetPtr nodesetval;
|
||||||
int boolval;
|
int boolval;
|
||||||
double floatval;
|
double floatval;
|
||||||
@ -163,6 +165,10 @@ struct _xmlXPathContext {
|
|||||||
xmlNsPtr *namespaces; /* The namespaces lookup */
|
xmlNsPtr *namespaces; /* The namespaces lookup */
|
||||||
int nsNr; /* the current Namespace index */
|
int nsNr; /* the current Namespace index */
|
||||||
void *user; /* user defined extra info */
|
void *user; /* user defined extra info */
|
||||||
|
|
||||||
|
/* extra variables */
|
||||||
|
int contextSize; /* the context size */
|
||||||
|
int proximityPosition; /* the proximity position */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user