mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-07-29 11:41:22 +03:00
Big XPath cleanup continues, one URI fix:
- xpath.[ch] debugXML.c testXPath.c: fixed the XPath evaluation engine, should be far more stable, incorporated a new version of preceding/following axis, need testing - uri.c: fixed file:///c:/a/b/c problem - test/XPath/tests/idsimple: augmented the XPath tests Daniel
This commit is contained in:
@ -1,3 +1,11 @@
|
|||||||
|
Mon Oct 2 23:47:32 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
|
||||||
|
|
||||||
|
* xpath.[ch] debugXML.c testXPath.c: fixed the XPath evaluation
|
||||||
|
engine, should be far more stable, incorporated a new version of
|
||||||
|
preceding/following axis, need testing
|
||||||
|
* uri.c: fixed file:///c:/a/b/c problem
|
||||||
|
* test/XPath/tests/idsimple: augmented the XPath tests
|
||||||
|
|
||||||
Sun Oct 1 22:33:00 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
|
Sun Oct 1 22:33:00 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
|
||||||
|
|
||||||
* doc/* rebuilding docs for 2.2.4 release
|
* doc/* rebuilding docs for 2.2.4 release
|
||||||
|
31
debugXML.c
31
debugXML.c
@ -1649,9 +1649,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
|
|||||||
} else {
|
} else {
|
||||||
ctxt->pctxt->node = ctxt->node;
|
ctxt->pctxt->node = ctxt->node;
|
||||||
#ifdef LIBXML_XPATH_ENABLED
|
#ifdef LIBXML_XPATH_ENABLED
|
||||||
if (ctxt->pctxt->nodelist != NULL)
|
ctxt->pctxt->node = ctxt->node;
|
||||||
xmlXPathFreeNodeSet(ctxt->pctxt->nodelist);
|
|
||||||
ctxt->pctxt->nodelist = xmlXPathNodeSetCreate(ctxt->node);
|
|
||||||
list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
|
list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
|
||||||
#else
|
#else
|
||||||
list = NULL;
|
list = NULL;
|
||||||
@ -1688,21 +1686,14 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
|
|||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s: no such node\n", arg);
|
fprintf(stderr, "%s: no such node\n", arg);
|
||||||
}
|
}
|
||||||
#ifdef LIBXML_XPATH_ENABLED
|
ctxt->pctxt->node = NULL;
|
||||||
if (ctxt->pctxt->nodelist != NULL)
|
|
||||||
xmlXPathFreeNodeSet(ctxt->pctxt->nodelist);
|
|
||||||
#endif /* LIBXML_XPATH_ENABLED */
|
|
||||||
ctxt->pctxt->nodelist = NULL;
|
|
||||||
}
|
}
|
||||||
} else if (!strcmp(command, "cd")) {
|
} else if (!strcmp(command, "cd")) {
|
||||||
if (arg[0] == 0) {
|
if (arg[0] == 0) {
|
||||||
ctxt->node = (xmlNodePtr) ctxt->doc;
|
ctxt->node = (xmlNodePtr) ctxt->doc;
|
||||||
} else {
|
} else {
|
||||||
ctxt->pctxt->node = ctxt->node;
|
|
||||||
#ifdef LIBXML_XPATH_ENABLED
|
#ifdef LIBXML_XPATH_ENABLED
|
||||||
if (ctxt->pctxt->nodelist != NULL)
|
ctxt->pctxt->node = ctxt->node;
|
||||||
xmlXPathFreeNodeSet(ctxt->pctxt->nodelist);
|
|
||||||
ctxt->pctxt->nodelist = xmlXPathNodeSetCreate(ctxt->node);
|
|
||||||
list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
|
list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
|
||||||
#else
|
#else
|
||||||
list = NULL;
|
list = NULL;
|
||||||
@ -1733,11 +1724,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
|
|||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s: no such node\n", arg);
|
fprintf(stderr, "%s: no such node\n", arg);
|
||||||
}
|
}
|
||||||
#ifdef LIBXML_XPATH_ENABLED
|
ctxt->pctxt->node = NULL;
|
||||||
if (ctxt->pctxt->nodelist != NULL)
|
|
||||||
xmlXPathFreeNodeSet(ctxt->pctxt->nodelist);
|
|
||||||
#endif /* LIBXML_XPATH_ENABLED */
|
|
||||||
ctxt->pctxt->nodelist = NULL;
|
|
||||||
}
|
}
|
||||||
} else if (!strcmp(command, "cat")) {
|
} else if (!strcmp(command, "cat")) {
|
||||||
if (arg[0] == 0) {
|
if (arg[0] == 0) {
|
||||||
@ -1745,9 +1732,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
|
|||||||
} else {
|
} else {
|
||||||
ctxt->pctxt->node = ctxt->node;
|
ctxt->pctxt->node = ctxt->node;
|
||||||
#ifdef LIBXML_XPATH_ENABLED
|
#ifdef LIBXML_XPATH_ENABLED
|
||||||
if (ctxt->pctxt->nodelist != NULL)
|
ctxt->pctxt->node = ctxt->node;
|
||||||
xmlXPathFreeNodeSet(ctxt->pctxt->nodelist);
|
|
||||||
ctxt->pctxt->nodelist = xmlXPathNodeSetCreate(ctxt->node);
|
|
||||||
list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
|
list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
|
||||||
#else
|
#else
|
||||||
list = NULL;
|
list = NULL;
|
||||||
@ -1781,11 +1766,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
|
|||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s: no such node\n", arg);
|
fprintf(stderr, "%s: no such node\n", arg);
|
||||||
}
|
}
|
||||||
#ifdef LIBXML_XPATH_ENABLED
|
ctxt->pctxt->node = NULL;
|
||||||
if (ctxt->pctxt->nodelist != NULL)
|
|
||||||
xmlXPathFreeNodeSet(ctxt->pctxt->nodelist);
|
|
||||||
#endif /* LIBXML_XPATH_ENABLED */
|
|
||||||
ctxt->pctxt->nodelist = NULL;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unknown command %s\n", command);
|
fprintf(stderr, "Unknown command %s\n", command);
|
||||||
|
@ -143,7 +143,6 @@ struct _xmlXPathAxis {
|
|||||||
struct _xmlXPathContext {
|
struct _xmlXPathContext {
|
||||||
xmlDocPtr doc; /* The current document */
|
xmlDocPtr doc; /* The current document */
|
||||||
xmlNodePtr node; /* The current node */
|
xmlNodePtr node; /* The current node */
|
||||||
xmlNodeSetPtr nodelist; /* The current node list */
|
|
||||||
|
|
||||||
int nb_variables; /* number of defined variables */
|
int nb_variables; /* number of defined variables */
|
||||||
int max_variables; /* max number of variables */
|
int max_variables; /* max number of variables */
|
||||||
|
24
result/XPath/tests/idsimple
Normal file
24
result/XPath/tests/idsimple
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
Object is a Node Set :
|
||||||
|
Set contains 1 nodes:
|
||||||
|
1 ELEMENT EXAMPLE
|
||||||
|
ATTRIBUTE id
|
||||||
|
TEXT
|
||||||
|
content=root
|
||||||
|
ATTRIBUTE prop1
|
||||||
|
TEXT
|
||||||
|
content=gnome is great
|
||||||
|
ATTRIBUTE prop2
|
||||||
|
TEXT
|
||||||
|
content=& linux too
|
||||||
|
Object is a Node Set :
|
||||||
|
Set contains 1 nodes:
|
||||||
|
1 ELEMENT chapter
|
||||||
|
ATTRIBUTE id
|
||||||
|
TEXT
|
||||||
|
content=chapter2
|
||||||
|
Object is a Node Set :
|
||||||
|
Set contains 1 nodes:
|
||||||
|
1 ELEMENT chapter
|
||||||
|
ATTRIBUTE id
|
||||||
|
TEXT
|
||||||
|
content=chapter5
|
3
test/XPath/tests/idsimple
Normal file
3
test/XPath/tests/idsimple
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
//*[@id="root"]
|
||||||
|
//*[@id="chapter2"]
|
||||||
|
//*[@id="chapter5"]
|
@ -40,8 +40,10 @@
|
|||||||
#include <libxml/parser.h>
|
#include <libxml/parser.h>
|
||||||
#include <libxml/debugXML.h>
|
#include <libxml/debugXML.h>
|
||||||
#include <libxml/xmlmemory.h>
|
#include <libxml/xmlmemory.h>
|
||||||
|
#include <libxml/parserInternals.h>
|
||||||
|
|
||||||
static int debug = 0;
|
static int debug = 0;
|
||||||
|
static int valid = 0;
|
||||||
static int expr = 0;
|
static int expr = 0;
|
||||||
static xmlDocPtr document = NULL;
|
static xmlDocPtr document = NULL;
|
||||||
|
|
||||||
@ -171,6 +173,8 @@ int main(int argc, char **argv) {
|
|||||||
for (i = 1; i < argc ; i++) {
|
for (i = 1; i < argc ; i++) {
|
||||||
if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
|
if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
|
||||||
debug++;
|
debug++;
|
||||||
|
if ((!strcmp(argv[i], "-valid")) || (!strcmp(argv[i], "--valid")))
|
||||||
|
valid++;
|
||||||
if ((!strcmp(argv[i], "-expr")) || (!strcmp(argv[i], "--expr")))
|
if ((!strcmp(argv[i], "-expr")) || (!strcmp(argv[i], "--expr")))
|
||||||
expr++;
|
expr++;
|
||||||
if ((!strcmp(argv[i], "-i")) || (!strcmp(argv[i], "--input")))
|
if ((!strcmp(argv[i], "-i")) || (!strcmp(argv[i], "--input")))
|
||||||
@ -178,6 +182,7 @@ int main(int argc, char **argv) {
|
|||||||
if ((!strcmp(argv[i], "-f")) || (!strcmp(argv[i], "--file")))
|
if ((!strcmp(argv[i], "-f")) || (!strcmp(argv[i], "--file")))
|
||||||
usefile++;
|
usefile++;
|
||||||
}
|
}
|
||||||
|
if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
|
||||||
if (document == NULL) {
|
if (document == NULL) {
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
document = xmlParseDoc(buffer);
|
document = xmlParseDoc(buffer);
|
||||||
@ -201,6 +206,7 @@ int main(int argc, char **argv) {
|
|||||||
argv[0]);
|
argv[0]);
|
||||||
printf("\tParse the XPath strings and output the result of the parsing\n");
|
printf("\tParse the XPath strings and output the result of the parsing\n");
|
||||||
printf("\t--debug : dump a debug version of the result\n");
|
printf("\t--debug : dump a debug version of the result\n");
|
||||||
|
printf("\t--valid : switch on DTD support in the parser\n");
|
||||||
printf("\t--expr : debug XPath expressions only\n");
|
printf("\t--expr : debug XPath expressions only\n");
|
||||||
printf("\t--input filename : or\n");
|
printf("\t--input filename : or\n");
|
||||||
printf("\t-i filename : read the document from filename\n");
|
printf("\t-i filename : read the document from filename\n");
|
||||||
|
26
uri.c
26
uri.c
@ -373,6 +373,17 @@ xmlSaveUri(xmlURIPtr uri) {
|
|||||||
ret[len++] = lo + (lo > 9? 'A'-10 : '0');
|
ret[len++] = lo + (lo > 9? 'A'-10 : '0');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (uri->scheme != NULL) {
|
||||||
|
if (len + 3 >= max) {
|
||||||
|
max *= 2;
|
||||||
|
ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
|
||||||
|
if (ret == NULL) {
|
||||||
|
fprintf(stderr, "xmlSaveUri: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret[len++] = '/';
|
||||||
|
ret[len++] = '/';
|
||||||
}
|
}
|
||||||
if (uri->path != NULL) {
|
if (uri->path != NULL) {
|
||||||
p = uri->path;
|
p = uri->path;
|
||||||
@ -766,12 +777,25 @@ xmlParseURIServer(xmlURIPtr uri, const char **str) {
|
|||||||
}
|
}
|
||||||
cur = *str;
|
cur = *str;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* This can be empty in the case where there is no server
|
||||||
|
*/
|
||||||
|
host = cur;
|
||||||
|
if (*cur == '/') {
|
||||||
|
if (uri != NULL) {
|
||||||
|
if (uri->authority != NULL) xmlFree(uri->authority);
|
||||||
|
uri->authority = NULL;
|
||||||
|
if (uri->server != NULL) xmlFree(uri->server);
|
||||||
|
uri->server = NULL;
|
||||||
|
uri->port = 0;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* host part of hostport can derive either an IPV4 address
|
* host part of hostport can derive either an IPV4 address
|
||||||
* or an unresolved name. Check the IP first, it easier to detect
|
* or an unresolved name. Check the IP first, it easier to detect
|
||||||
* errors if wrong one
|
* errors if wrong one
|
||||||
*/
|
*/
|
||||||
host = cur;
|
|
||||||
if (IS_DIGIT(*cur)) {
|
if (IS_DIGIT(*cur)) {
|
||||||
while(IS_DIGIT(*cur)) cur++;
|
while(IS_DIGIT(*cur)) cur++;
|
||||||
if (*cur != '.')
|
if (*cur != '.')
|
||||||
|
428
xpath.c
428
xpath.c
@ -646,7 +646,7 @@ xmlXPathNewBoolean(int val) {
|
|||||||
|
|
||||||
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
||||||
if (ret == NULL) {
|
if (ret == NULL) {
|
||||||
fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n");
|
fprintf(xmlXPathDebug, "xmlXPathNewBoolean: out of memory\n");
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
||||||
@ -669,7 +669,7 @@ xmlXPathNewString(const xmlChar *val) {
|
|||||||
|
|
||||||
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
||||||
if (ret == NULL) {
|
if (ret == NULL) {
|
||||||
fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n");
|
fprintf(xmlXPathDebug, "xmlXPathNewString: out of memory\n");
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
||||||
@ -692,7 +692,7 @@ xmlXPathNewCString(const char *val) {
|
|||||||
|
|
||||||
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
||||||
if (ret == NULL) {
|
if (ret == NULL) {
|
||||||
fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n");
|
fprintf(xmlXPathDebug, "xmlXPathNewCString: out of memory\n");
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
||||||
@ -716,7 +716,7 @@ xmlXPathNewNodeSet(xmlNodePtr val) {
|
|||||||
|
|
||||||
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
||||||
if (ret == NULL) {
|
if (ret == NULL) {
|
||||||
fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n");
|
fprintf(xmlXPathDebug, "xmlXPathNewNodeSet: out of memory\n");
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
||||||
@ -753,6 +753,29 @@ xmlXPathNewNodeSetList(xmlNodeSetPtr val) {
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathWrapNodeSet:
|
||||||
|
* @val: the NodePtr value
|
||||||
|
*
|
||||||
|
* Wrap the Nodeset @val in a new xmlXPathObjectPtr
|
||||||
|
*
|
||||||
|
* Returns the newly created object.
|
||||||
|
*/
|
||||||
|
xmlXPathObjectPtr
|
||||||
|
xmlXPathWrapNodeSet(xmlNodeSetPtr val) {
|
||||||
|
xmlXPathObjectPtr ret;
|
||||||
|
|
||||||
|
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
||||||
|
if (ret == NULL) {
|
||||||
|
fprintf(xmlXPathDebug, "xmlXPathWrapNodeSet: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
||||||
|
ret->type = XPATH_NODESET;
|
||||||
|
ret->nodesetval = val;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlXPathFreeNodeSetList:
|
* xmlXPathFreeNodeSetList:
|
||||||
* @obj: an existing NodeSetList object
|
* @obj: an existing NodeSetList object
|
||||||
@ -813,12 +836,7 @@ xmlXPathNewContext(xmlDocPtr doc) {
|
|||||||
}
|
}
|
||||||
memset(ret, 0 , (size_t) sizeof(xmlXPathContext));
|
memset(ret, 0 , (size_t) sizeof(xmlXPathContext));
|
||||||
ret->doc = doc;
|
ret->doc = doc;
|
||||||
/***********
|
|
||||||
ret->node = (xmlNodePtr) doc;
|
|
||||||
ret->nodelist = xmlXPathNodeSetCreate(ret->node);
|
|
||||||
***********/
|
|
||||||
ret->node = NULL;
|
ret->node = NULL;
|
||||||
ret->nodelist = NULL;
|
|
||||||
|
|
||||||
ret->nb_variables = 0;
|
ret->nb_variables = 0;
|
||||||
ret->max_variables = 0;
|
ret->max_variables = 0;
|
||||||
@ -856,8 +874,6 @@ xmlXPathFreeContext(xmlXPathContextPtr ctxt) {
|
|||||||
if (ctxt->namespaces != NULL)
|
if (ctxt->namespaces != NULL)
|
||||||
xmlFree(ctxt->namespaces);
|
xmlFree(ctxt->namespaces);
|
||||||
|
|
||||||
if (ctxt->nodelist != NULL)
|
|
||||||
xmlXPathFreeNodeSet(ctxt->nodelist);
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
memset(ctxt, 0xB , (size_t) sizeof(xmlXPathContext));
|
memset(ctxt, 0xB , (size_t) sizeof(xmlXPathContext));
|
||||||
#endif
|
#endif
|
||||||
@ -870,14 +886,14 @@ xmlXPathFreeContext(xmlXPathContextPtr ctxt) {
|
|||||||
* *
|
* *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
#define CHECK_CTXT \
|
#define CHECK_CTXT(ctxt) \
|
||||||
if (ctxt == NULL) { \
|
if (ctxt == NULL) { \
|
||||||
fprintf(xmlXPathDebug, "%s:%d Internal error: ctxt == NULL\n", \
|
fprintf(xmlXPathDebug, "%s:%d Internal error: ctxt == NULL\n", \
|
||||||
__FILE__, __LINE__); \
|
__FILE__, __LINE__); \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
|
|
||||||
#define CHECK_CONTEXT \
|
#define CHECK_CONTEXT(ctxt) \
|
||||||
if (ctxt == NULL) { \
|
if (ctxt == NULL) { \
|
||||||
fprintf(xmlXPathDebug, "%s:%d Internal error: no context\n", \
|
fprintf(xmlXPathDebug, "%s:%d Internal error: no context\n", \
|
||||||
__FILE__, __LINE__); \
|
__FILE__, __LINE__); \
|
||||||
@ -1136,6 +1152,9 @@ xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
|
|||||||
case XPATH_STRING:
|
case XPATH_STRING:
|
||||||
ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval);
|
ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval);
|
||||||
break;
|
break;
|
||||||
|
case XPATH_USERS:
|
||||||
|
TODO
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XPATH_BOOLEAN:
|
case XPATH_BOOLEAN:
|
||||||
@ -1170,6 +1189,9 @@ xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
|
|||||||
ret = 1;
|
ret = 1;
|
||||||
ret = (arg1->boolval == ret);
|
ret = (arg1->boolval == ret);
|
||||||
break;
|
break;
|
||||||
|
case XPATH_USERS:
|
||||||
|
TODO
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XPATH_NUMBER:
|
case XPATH_NUMBER:
|
||||||
@ -1195,6 +1217,9 @@ xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
|
|||||||
case XPATH_NUMBER:
|
case XPATH_NUMBER:
|
||||||
ret = (arg1->floatval == arg2->floatval);
|
ret = (arg1->floatval == arg2->floatval);
|
||||||
break;
|
break;
|
||||||
|
case XPATH_USERS:
|
||||||
|
TODO
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XPATH_STRING:
|
case XPATH_STRING:
|
||||||
@ -1223,8 +1248,14 @@ xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
|
|||||||
arg1 = valuePop(ctxt);
|
arg1 = valuePop(ctxt);
|
||||||
ret = (arg1->floatval == arg2->floatval);
|
ret = (arg1->floatval == arg2->floatval);
|
||||||
break;
|
break;
|
||||||
|
case XPATH_USERS:
|
||||||
|
TODO
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case XPATH_USERS:
|
||||||
|
TODO
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
xmlXPathFreeObject(arg1);
|
xmlXPathFreeObject(arg1);
|
||||||
xmlXPathFreeObject(arg2);
|
xmlXPathFreeObject(arg2);
|
||||||
@ -1443,19 +1474,21 @@ xmlXPathModValues(xmlXPathParserContextPtr ctxt) {
|
|||||||
* *
|
* *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
#define AXIS_ANCESTOR 1
|
typedef enum {
|
||||||
#define AXIS_ANCESTOR_OR_SELF 2
|
AXIS_ANCESTOR = 1,
|
||||||
#define AXIS_ATTRIBUTE 3
|
AXIS_ANCESTOR_OR_SELF,
|
||||||
#define AXIS_CHILD 4
|
AXIS_ATTRIBUTE,
|
||||||
#define AXIS_DESCENDANT 5
|
AXIS_CHILD,
|
||||||
#define AXIS_DESCENDANT_OR_SELF 6
|
AXIS_DESCENDANT,
|
||||||
#define AXIS_FOLLOWING 7
|
AXIS_DESCENDANT_OR_SELF,
|
||||||
#define AXIS_FOLLOWING_SIBLING 8
|
AXIS_FOLLOWING,
|
||||||
#define AXIS_NAMESPACE 9
|
AXIS_FOLLOWING_SIBLING,
|
||||||
#define AXIS_PARENT 10
|
AXIS_NAMESPACE,
|
||||||
#define AXIS_PRECEDING 11
|
AXIS_PARENT,
|
||||||
#define AXIS_PRECEDING_SIBLING 12
|
AXIS_PRECEDING,
|
||||||
#define AXIS_SELF 13
|
AXIS_PRECEDING_SIBLING,
|
||||||
|
AXIS_SELF
|
||||||
|
} xmlXPathAxisVal;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A traversal function enumerates nodes along an axis.
|
* A traversal function enumerates nodes along an axis.
|
||||||
@ -1802,6 +1835,84 @@ xmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
return(cur->prev);
|
return(cur->prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathNextFollowing:
|
||||||
|
* @ctxt: the XPath Parser context
|
||||||
|
* @cur: the current node in the traversal
|
||||||
|
*
|
||||||
|
* Traversal function for the "following" direction
|
||||||
|
* The following axis contains all nodes in the same document as the context
|
||||||
|
* node that are after the context node in document order, excluding any
|
||||||
|
* descendants and excluding attribute nodes and namespace nodes; the nodes
|
||||||
|
* are ordered in document order
|
||||||
|
*
|
||||||
|
* Returns the next element following that axis
|
||||||
|
*/
|
||||||
|
xmlNodePtr
|
||||||
|
xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
||||||
|
if (cur != NULL && cur->children != NULL)
|
||||||
|
return cur->children ;
|
||||||
|
if (cur == NULL)
|
||||||
|
if ((cur = ctxt->context->node) == NULL) return(NULL) ;
|
||||||
|
do {
|
||||||
|
cur = cur->parent;
|
||||||
|
if (cur == NULL) return(NULL);
|
||||||
|
if (cur == ctxt->context->doc->children) return(NULL);
|
||||||
|
if (cur->next != NULL) {
|
||||||
|
cur = cur->next;
|
||||||
|
return(cur);
|
||||||
|
}
|
||||||
|
} while (cur != NULL);
|
||||||
|
return(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* returns 1 if @ancestor is a @node's ancestor, 0 otherwise.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
isAncestor(xmlNodePtr ancestor, xmlNodePtr node) {
|
||||||
|
xmlNodePtr tmp ;
|
||||||
|
if (ancestor == NULL || node == NULL) return 0 ;
|
||||||
|
for (tmp = node ; tmp->parent != NULL ; tmp = tmp->parent) {
|
||||||
|
if (tmp->parent == ancestor)
|
||||||
|
return 1 ;
|
||||||
|
}
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathNextPreceding:
|
||||||
|
* @ctxt: the XPath Parser context
|
||||||
|
* @cur: the current node in the traversal
|
||||||
|
*
|
||||||
|
* Traversal function for the "preceding" direction
|
||||||
|
* the preceding axis contains all nodes in the same document as the context
|
||||||
|
* node that are before the context node in document order, excluding any
|
||||||
|
* ancestors and excluding attribute nodes and namespace nodes; the nodes are
|
||||||
|
* ordered in reverse document order
|
||||||
|
*
|
||||||
|
* Returns the next element following that axis
|
||||||
|
*/
|
||||||
|
xmlNodePtr
|
||||||
|
xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
||||||
|
if (cur == NULL)
|
||||||
|
cur = ctxt->context->node ;
|
||||||
|
do {
|
||||||
|
if (cur->prev != NULL) {
|
||||||
|
for (cur = cur->prev ; cur->last != NULL ; cur = cur->last)
|
||||||
|
;
|
||||||
|
return(cur) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = cur->parent;
|
||||||
|
if (cur == NULL) return(NULL);
|
||||||
|
if (cur == ctxt->context->doc->children) return(NULL);
|
||||||
|
} while (isAncestor(cur, ctxt->context->node));
|
||||||
|
return(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* OLD VERSION, I was told they were broken ! */
|
||||||
/**
|
/**
|
||||||
* xmlXPathNextFollowing:
|
* xmlXPathNextFollowing:
|
||||||
* @ctxt: the XPath Parser context
|
* @ctxt: the XPath Parser context
|
||||||
@ -1869,6 +1980,7 @@ xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
} while (cur != NULL);
|
} while (cur != NULL);
|
||||||
return(cur);
|
return(cur);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlXPathNextNamespace:
|
* xmlXPathNextNamespace:
|
||||||
@ -1921,24 +2033,32 @@ xmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlAttrPtr cur) {
|
|||||||
* *
|
* *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
#define NODE_TEST_NONE 0
|
typedef enum {
|
||||||
#define NODE_TEST_TYPE 1
|
NODE_TEST_NONE = 0,
|
||||||
#define NODE_TEST_PI 2
|
NODE_TEST_TYPE = 1,
|
||||||
#define NODE_TEST_ALL 3
|
NODE_TEST_PI = 2,
|
||||||
#define NODE_TEST_NS 4
|
NODE_TEST_ALL = 3,
|
||||||
#define NODE_TEST_NAME 5
|
NODE_TEST_NS = 4,
|
||||||
|
NODE_TEST_NAME = 5
|
||||||
|
} xmlXPathTestVal;
|
||||||
|
|
||||||
#define NODE_TYPE_COMMENT 50
|
typedef enum {
|
||||||
#define NODE_TYPE_TEXT 51
|
NODE_TYPE_COMMENT = 50,
|
||||||
#define NODE_TYPE_PI 52
|
NODE_TYPE_TEXT = 51,
|
||||||
#define NODE_TYPE_NODE 53
|
NODE_TYPE_PI = 52,
|
||||||
|
NODE_TYPE_NODE = 53
|
||||||
|
} xmlXPathTypeVal;
|
||||||
|
|
||||||
#define IS_FUNCTION 200
|
#define IS_FUNCTION 200
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlXPathNodeCollectAndTest:
|
* xmlXPathNodeCollectAndTest:
|
||||||
* @ctxt: the XPath Parser context
|
* @ctxt: the XPath Parser context
|
||||||
* @cur: the current node to test
|
* @axis: the XPath axis
|
||||||
|
* @test: the XPath test
|
||||||
|
* @type: the XPath type
|
||||||
|
* @prefix: the namesapce prefix if any
|
||||||
|
* @name: the name used in the search if any
|
||||||
*
|
*
|
||||||
* This is the function implementing a step: based on the current list
|
* This is the function implementing a step: based on the current list
|
||||||
* of nodes, it builds up a new list, looking at all nodes under that
|
* of nodes, it builds up a new list, looking at all nodes under that
|
||||||
@ -1946,9 +2066,10 @@ xmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlAttrPtr cur) {
|
|||||||
*
|
*
|
||||||
* Returns the new NodeSet resulting from the search.
|
* Returns the new NodeSet resulting from the search.
|
||||||
*/
|
*/
|
||||||
xmlNodeSetPtr
|
void
|
||||||
xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, int axis,
|
xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
|
||||||
int test, int type, const xmlChar *prefix, const xmlChar *name) {
|
xmlXPathTestVal test, xmlXPathTypeVal type,
|
||||||
|
const xmlChar *prefix, const xmlChar *name) {
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
int n = 0, t = 0;
|
int n = 0, t = 0;
|
||||||
#endif
|
#endif
|
||||||
@ -1956,17 +2077,12 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, int axis,
|
|||||||
xmlNodeSetPtr ret;
|
xmlNodeSetPtr ret;
|
||||||
xmlXPathTraversalFunction next = NULL;
|
xmlXPathTraversalFunction next = NULL;
|
||||||
xmlNodePtr cur = NULL;
|
xmlNodePtr cur = NULL;
|
||||||
|
xmlXPathObjectPtr obj;
|
||||||
|
xmlNodeSetPtr nodelist;
|
||||||
|
|
||||||
|
CHECK_TYPE(XPATH_NODESET);
|
||||||
|
obj = valuePop(ctxt);
|
||||||
|
|
||||||
if (ctxt->context->nodelist == NULL) {
|
|
||||||
if (ctxt->context->node == NULL) {
|
|
||||||
fprintf(xmlXPathDebug,
|
|
||||||
"xmlXPathNodeCollectAndTest %s:%d : nodelist and node are NULL\n",
|
|
||||||
__FILE__, __LINE__);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
STRANGE
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
fprintf(xmlXPathDebug, "new step : ");
|
fprintf(xmlXPathDebug, "new step : ");
|
||||||
#endif
|
#endif
|
||||||
@ -2039,11 +2155,14 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, int axis,
|
|||||||
#endif
|
#endif
|
||||||
next = xmlXPathNextSelf; break;
|
next = xmlXPathNextSelf; break;
|
||||||
}
|
}
|
||||||
if (next == NULL) return(NULL);
|
if (next == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nodelist = obj->nodesetval;
|
||||||
ret = xmlXPathNodeSetCreate(NULL);
|
ret = xmlXPathNodeSetCreate(NULL);
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
fprintf(xmlXPathDebug, " context contains %d nodes\n",
|
fprintf(xmlXPathDebug, " context contains %d nodes\n",
|
||||||
ctxt->context->nodelist->nodeNr);
|
nodelist->nodeNr);
|
||||||
switch (test) {
|
switch (test) {
|
||||||
case NODE_TEST_NONE:
|
case NODE_TEST_NONE:
|
||||||
fprintf(xmlXPathDebug, " searching for none !!!\n");
|
fprintf(xmlXPathDebug, " searching for none !!!\n");
|
||||||
@ -2070,8 +2189,8 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, int axis,
|
|||||||
}
|
}
|
||||||
fprintf(xmlXPathDebug, "Testing : ");
|
fprintf(xmlXPathDebug, "Testing : ");
|
||||||
#endif
|
#endif
|
||||||
for (i = 0;i < ctxt->context->nodelist->nodeNr; i++) {
|
for (i = 0;i < nodelist->nodeNr; i++) {
|
||||||
ctxt->context->node = ctxt->context->nodelist->nodeTab[i];
|
ctxt->context->node = nodelist->nodeTab[i];
|
||||||
|
|
||||||
cur = NULL;
|
cur = NULL;
|
||||||
do {
|
do {
|
||||||
@ -2084,7 +2203,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, int axis,
|
|||||||
switch (test) {
|
switch (test) {
|
||||||
case NODE_TEST_NONE:
|
case NODE_TEST_NONE:
|
||||||
STRANGE
|
STRANGE
|
||||||
return(NULL);
|
return;
|
||||||
case NODE_TEST_TYPE:
|
case NODE_TEST_TYPE:
|
||||||
if ((cur->type == type) ||
|
if ((cur->type == type) ||
|
||||||
((type == XML_ELEMENT_NODE) &&
|
((type == XML_ELEMENT_NODE) &&
|
||||||
@ -2129,7 +2248,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, int axis,
|
|||||||
((cur->ns != NULL) &&
|
((cur->ns != NULL) &&
|
||||||
(xmlStrEqual(prefix, cur->ns->href)))))) {
|
(xmlStrEqual(prefix, cur->ns->href)))))) {
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
n++;
|
n++;
|
||||||
#endif
|
#endif
|
||||||
xmlXPathNodeSetAdd(ret, cur);
|
xmlXPathNodeSetAdd(ret, cur);
|
||||||
}
|
}
|
||||||
@ -2138,7 +2257,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, int axis,
|
|||||||
xmlAttrPtr attr = (xmlAttrPtr) cur;
|
xmlAttrPtr attr = (xmlAttrPtr) cur;
|
||||||
if (xmlStrEqual(name, attr->name)) {
|
if (xmlStrEqual(name, attr->name)) {
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
n++;
|
n++;
|
||||||
#endif
|
#endif
|
||||||
xmlXPathNodeSetAdd(ret, cur);
|
xmlXPathNodeSetAdd(ret, cur);
|
||||||
}
|
}
|
||||||
@ -2148,7 +2267,6 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, int axis,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
} while (cur != NULL);
|
} while (cur != NULL);
|
||||||
}
|
}
|
||||||
@ -2156,7 +2274,8 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, int axis,
|
|||||||
fprintf(xmlXPathDebug,
|
fprintf(xmlXPathDebug,
|
||||||
"\nExamined %d nodes, found %d nodes at that step\n", t, n);
|
"\nExamined %d nodes, found %d nodes at that step\n", t, n);
|
||||||
#endif
|
#endif
|
||||||
return(ret);
|
xmlXPathFreeObject(obj);
|
||||||
|
valuePush(ctxt, xmlXPathWrapNodeSet(ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2174,10 +2293,15 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, int axis,
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
xmlXPathRoot(xmlXPathParserContextPtr ctxt) {
|
xmlXPathRoot(xmlXPathParserContextPtr ctxt) {
|
||||||
if (ctxt->context->nodelist != NULL)
|
xmlXPathObjectPtr obj;
|
||||||
xmlXPathFreeNodeSet(ctxt->context->nodelist);
|
|
||||||
|
CHECK_TYPE(XPATH_NODESET);
|
||||||
|
obj = valuePop(ctxt);
|
||||||
|
|
||||||
ctxt->context->node = (xmlNodePtr) ctxt->context->doc;
|
ctxt->context->node = (xmlNodePtr) ctxt->context->doc;
|
||||||
ctxt->context->nodelist = xmlXPathNodeSetCreate(ctxt->context->node);
|
|
||||||
|
xmlXPathFreeObject(obj);
|
||||||
|
valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -2487,6 +2611,12 @@ xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
cur = valuePop(ctxt);
|
cur = valuePop(ctxt);
|
||||||
if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
|
if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
|
||||||
switch (cur->type) {
|
switch (cur->type) {
|
||||||
|
case XPATH_UNDEFINED:
|
||||||
|
#ifdef DEBUG_EXPR
|
||||||
|
fprintf(xmlXPathDebug, "String: undefined\n");
|
||||||
|
#endif
|
||||||
|
valuePush(ctxt, xmlXPathNewCString(""));
|
||||||
|
break;
|
||||||
case XPATH_NODESET:
|
case XPATH_NODESET:
|
||||||
if (cur->nodesetval->nodeNr == 0) {
|
if (cur->nodesetval->nodeNr == 0) {
|
||||||
valuePush(ctxt, xmlXPathNewCString(""));
|
valuePush(ctxt, xmlXPathNewCString(""));
|
||||||
@ -2522,6 +2652,10 @@ xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
xmlXPathFreeObject(cur);
|
xmlXPathFreeObject(cur);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
case XPATH_USERS:
|
||||||
|
TODO
|
||||||
|
valuePush(ctxt, xmlXPathNewCString(""));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
STRANGE
|
STRANGE
|
||||||
}
|
}
|
||||||
@ -3084,6 +3218,12 @@ xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
CHECK_ARITY(1);
|
CHECK_ARITY(1);
|
||||||
cur = valuePop(ctxt);
|
cur = valuePop(ctxt);
|
||||||
switch (cur->type) {
|
switch (cur->type) {
|
||||||
|
case XPATH_UNDEFINED:
|
||||||
|
#ifdef DEBUG_EXPR
|
||||||
|
fprintf(xmlXPathDebug, "NUMBER: undefined\n");
|
||||||
|
#endif
|
||||||
|
valuePush(ctxt, xmlXPathNewFloat(0.0));
|
||||||
|
break;
|
||||||
case XPATH_NODESET:
|
case XPATH_NODESET:
|
||||||
valuePush(ctxt, cur);
|
valuePush(ctxt, cur);
|
||||||
xmlXPathStringFunction(ctxt, 1);
|
xmlXPathStringFunction(ctxt, 1);
|
||||||
@ -3101,6 +3241,10 @@ xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
case XPATH_NUMBER:
|
case XPATH_NUMBER:
|
||||||
valuePush(ctxt, cur);
|
valuePush(ctxt, cur);
|
||||||
return;
|
return;
|
||||||
|
case XPATH_USERS:
|
||||||
|
TODO
|
||||||
|
valuePush(ctxt, xmlXPathNewFloat(0.0));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
STRANGE
|
STRANGE
|
||||||
}
|
}
|
||||||
@ -3800,8 +3944,6 @@ xmlXPathScanName(xmlXPathParserContextPtr ctxt) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
xmlXPathEvalPathExpr(xmlXPathParserContextPtr ctxt) {
|
xmlXPathEvalPathExpr(xmlXPathParserContextPtr ctxt) {
|
||||||
xmlNodeSetPtr newset = NULL;
|
|
||||||
|
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
if ((CUR == '$') || (CUR == '(') || (IS_DIGIT(CUR)) ||
|
if ((CUR == '$') || (CUR == '(') || (IS_DIGIT(CUR)) ||
|
||||||
(CUR == '\'') || (CUR == '"')) {
|
(CUR == '\'') || (CUR == '"')) {
|
||||||
@ -3810,15 +3952,8 @@ xmlXPathEvalPathExpr(xmlXPathParserContextPtr ctxt) {
|
|||||||
if ((CUR == '/') && (NXT(1) == '/')) {
|
if ((CUR == '/') && (NXT(1) == '/')) {
|
||||||
SKIP(2);
|
SKIP(2);
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
if (ctxt->context->nodelist == NULL) {
|
xmlXPathNodeCollectAndTest(ctxt, AXIS_DESCENDANT_OR_SELF,
|
||||||
STRANGE
|
|
||||||
xmlXPathRoot(ctxt);
|
|
||||||
}
|
|
||||||
newset = xmlXPathNodeCollectAndTest(ctxt, AXIS_DESCENDANT_OR_SELF,
|
|
||||||
NODE_TEST_TYPE, XML_ELEMENT_NODE, NULL, NULL);
|
NODE_TEST_TYPE, XML_ELEMENT_NODE, NULL, NULL);
|
||||||
if (ctxt->context->nodelist != NULL)
|
|
||||||
xmlXPathFreeNodeSet(ctxt->context->nodelist);
|
|
||||||
ctxt->context->nodelist = newset;
|
|
||||||
ctxt->context->node = NULL;
|
ctxt->context->node = NULL;
|
||||||
xmlXPathEvalRelativeLocationPath(ctxt);
|
xmlXPathEvalRelativeLocationPath(ctxt);
|
||||||
} else if (CUR == '/') {
|
} else if (CUR == '/') {
|
||||||
@ -3836,8 +3971,11 @@ xmlXPathEvalPathExpr(xmlXPathParserContextPtr ctxt) {
|
|||||||
if (name != NULL)
|
if (name != NULL)
|
||||||
xmlFree(name);
|
xmlFree(name);
|
||||||
|
|
||||||
if (ctxt->context->nodelist != NULL)
|
#if 0
|
||||||
valuePush(ctxt, xmlXPathNewNodeSetList(ctxt->context->nodelist));
|
/* DV 1234 !!!!!!! */
|
||||||
|
if (ctxt->context->nodelist != NULL)
|
||||||
|
valuePush(ctxt, xmlXPathNewNodeSetList(ctxt->context->nodelist));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3857,19 +3995,21 @@ xmlXPathEvalUnionExpr(xmlXPathParserContextPtr ctxt) {
|
|||||||
CHECK_ERROR;
|
CHECK_ERROR;
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
if (CUR == '|') {
|
if (CUR == '|') {
|
||||||
xmlNodeSetPtr old = ctxt->context->nodelist;
|
xmlXPathObjectPtr obj1,obj2;
|
||||||
|
|
||||||
|
CHECK_TYPE(XPATH_NODESET);
|
||||||
|
obj1 = valuePop(ctxt);
|
||||||
|
valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
|
||||||
|
|
||||||
NEXT;
|
NEXT;
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
xmlXPathEvalPathExpr(ctxt);
|
xmlXPathEvalPathExpr(ctxt);
|
||||||
|
|
||||||
if (ctxt->context->nodelist == NULL)
|
CHECK_TYPE(XPATH_NODESET);
|
||||||
ctxt->context->nodelist = old;
|
obj2 = valuePop(ctxt);
|
||||||
else {
|
obj1->nodesetval = xmlXPathNodeSetMerge(obj1->nodesetval,
|
||||||
ctxt->context->nodelist =
|
obj2->nodesetval);
|
||||||
xmlXPathNodeSetMerge(ctxt->context->nodelist, old);
|
xmlXPathFreeObject(obj2);
|
||||||
xmlXPathFreeNodeSet(old);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4182,6 +4322,7 @@ void
|
|||||||
xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt) {
|
xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt) {
|
||||||
const xmlChar *cur;
|
const xmlChar *cur;
|
||||||
xmlXPathObjectPtr res;
|
xmlXPathObjectPtr res;
|
||||||
|
xmlXPathObjectPtr obj, tmp;
|
||||||
xmlNodeSetPtr newset = NULL;
|
xmlNodeSetPtr newset = NULL;
|
||||||
xmlNodeSetPtr oldset;
|
xmlNodeSetPtr oldset;
|
||||||
int i;
|
int i;
|
||||||
@ -4198,8 +4339,9 @@ xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt) {
|
|||||||
* expression for all the element in the set. use it to grow
|
* expression for all the element in the set. use it to grow
|
||||||
* up a new set.
|
* up a new set.
|
||||||
*/
|
*/
|
||||||
oldset = ctxt->context->nodelist;
|
CHECK_TYPE(XPATH_NODESET);
|
||||||
ctxt->context->nodelist = NULL;
|
obj = valuePop(ctxt);
|
||||||
|
oldset = obj->nodesetval;
|
||||||
ctxt->context->node = NULL;
|
ctxt->context->node = NULL;
|
||||||
|
|
||||||
if ((oldset == NULL) || (oldset->nodeNr == 0)) {
|
if ((oldset == NULL) || (oldset->nodeNr == 0)) {
|
||||||
@ -4210,6 +4352,7 @@ xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt) {
|
|||||||
res = valuePop(ctxt);
|
res = valuePop(ctxt);
|
||||||
if (res != NULL)
|
if (res != NULL)
|
||||||
xmlXPathFreeObject(res);
|
xmlXPathFreeObject(res);
|
||||||
|
valuePush(ctxt, obj);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Save the expression pointer since we will have to evaluate
|
* Save the expression pointer since we will have to evaluate
|
||||||
@ -4226,7 +4369,8 @@ xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt) {
|
|||||||
* in the nodeset.
|
* in the nodeset.
|
||||||
*/
|
*/
|
||||||
ctxt->context->node = oldset->nodeTab[i];
|
ctxt->context->node = oldset->nodeTab[i];
|
||||||
ctxt->context->nodelist = NULL;
|
tmp = xmlXPathNewNodeSet(ctxt->context->node);
|
||||||
|
valuePush(ctxt, tmp);
|
||||||
ctxt->context->contextSize = oldset->nodeNr;
|
ctxt->context->contextSize = oldset->nodeNr;
|
||||||
ctxt->context->proximityPosition = i + 1;
|
ctxt->context->proximityPosition = i + 1;
|
||||||
|
|
||||||
@ -4241,8 +4385,16 @@ xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt) {
|
|||||||
if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
|
if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
|
||||||
xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
|
xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cleanup
|
||||||
|
*/
|
||||||
if (res != NULL)
|
if (res != NULL)
|
||||||
xmlXPathFreeObject(res);
|
xmlXPathFreeObject(res);
|
||||||
|
if (ctxt->value == tmp) {
|
||||||
|
res = valuePop(ctxt);
|
||||||
|
xmlXPathFreeObject(res);
|
||||||
|
}
|
||||||
|
|
||||||
ctxt->context->node = NULL;
|
ctxt->context->node = NULL;
|
||||||
}
|
}
|
||||||
@ -4250,22 +4402,21 @@ xmlXPathEvalPredicate(xmlXPathParserContextPtr ctxt) {
|
|||||||
/*
|
/*
|
||||||
* The result is used as the new evaluation set.
|
* The result is used as the new evaluation set.
|
||||||
*/
|
*/
|
||||||
ctxt->context->nodelist = newset;
|
xmlXPathFreeObject(obj);
|
||||||
ctxt->context->node = NULL;
|
ctxt->context->node = NULL;
|
||||||
ctxt->context->contextSize = -1;
|
ctxt->context->contextSize = -1;
|
||||||
ctxt->context->proximityPosition = -1;
|
ctxt->context->proximityPosition = -1;
|
||||||
|
valuePush(ctxt, xmlXPathWrapNodeSet(newset));
|
||||||
}
|
}
|
||||||
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
|
||||||
fprintf(xmlXPathDebug, "After predicate : ");
|
fprintf(xmlXPathDebug, "After predicate : ");
|
||||||
xmlXPathDebugNodeSet(xmlXPathDebug, ctxt->context->nodelist);
|
xmlXPathDebugNodeSet(xmlXPathDebug, ctxt->context->value->nodesetval);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4290,11 +4441,10 @@ void
|
|||||||
xmlXPathEvalBasis(xmlXPathParserContextPtr ctxt) {
|
xmlXPathEvalBasis(xmlXPathParserContextPtr ctxt) {
|
||||||
xmlChar *name = NULL;
|
xmlChar *name = NULL;
|
||||||
xmlChar *prefix = NULL;
|
xmlChar *prefix = NULL;
|
||||||
int type = 0;
|
xmlXPathTypeVal type = 0;
|
||||||
int axis = AXIS_CHILD; /* the default on abbreviated syntax */
|
xmlXPathAxisVal axis = AXIS_CHILD; /* the default on abbreviated syntax */
|
||||||
int nodetest = NODE_TEST_NONE;
|
xmlXPathTestVal nodetest = NODE_TEST_NONE;
|
||||||
int nodetype = 0;
|
xmlElementType nodetype = 0;
|
||||||
xmlNodeSetPtr newset = NULL;
|
|
||||||
|
|
||||||
if (CUR == '@') {
|
if (CUR == '@') {
|
||||||
NEXT;
|
NEXT;
|
||||||
@ -4344,17 +4494,6 @@ xmlXPathEvalBasis(xmlXPathParserContextPtr ctxt) {
|
|||||||
NEXT;
|
NEXT;
|
||||||
xmlFree(name);
|
xmlFree(name);
|
||||||
func(ctxt, nbargs);
|
func(ctxt, nbargs);
|
||||||
if ((ctxt->value != top) &&
|
|
||||||
(ctxt->value != NULL) &&
|
|
||||||
(ctxt->value->type == XPATH_NODESET)) {
|
|
||||||
xmlXPathObjectPtr cur;
|
|
||||||
|
|
||||||
cur = valuePop(ctxt);
|
|
||||||
ctxt->context->nodelist = cur->nodesetval;
|
|
||||||
ctxt->context->node = NULL;
|
|
||||||
cur->nodesetval = NULL;
|
|
||||||
xmlXPathFreeObject(cur);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -4522,15 +4661,11 @@ search_nodes:
|
|||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
fprintf(xmlXPathDebug, "Basis : computing new set\n");
|
fprintf(xmlXPathDebug, "Basis : computing new set\n");
|
||||||
#endif
|
#endif
|
||||||
newset = xmlXPathNodeCollectAndTest(ctxt, axis, nodetest, nodetype,
|
xmlXPathNodeCollectAndTest(ctxt, axis, nodetest, nodetype,
|
||||||
prefix, name);
|
prefix, name);
|
||||||
if (ctxt->context->nodelist != NULL)
|
|
||||||
xmlXPathFreeNodeSet(ctxt->context->nodelist);
|
|
||||||
ctxt->context->nodelist = newset;
|
|
||||||
ctxt->context->node = NULL;
|
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
fprintf(xmlXPathDebug, "Basis : ");
|
fprintf(xmlXPathDebug, "Basis : ");
|
||||||
xmlXPathDebugNodeSet(stdout, ctxt->context->nodelist);
|
xmlXPathDebugNodeSet(stdout, ctxt->context->value->nodesetval);
|
||||||
#endif
|
#endif
|
||||||
if (name != NULL) xmlFree(name);
|
if (name != NULL) xmlFree(name);
|
||||||
if (prefix != NULL) xmlFree(prefix);
|
if (prefix != NULL) xmlFree(prefix);
|
||||||
@ -4559,22 +4694,12 @@ search_nodes:
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
xmlXPathEvalStep(xmlXPathParserContextPtr ctxt) {
|
xmlXPathEvalStep(xmlXPathParserContextPtr ctxt) {
|
||||||
xmlNodeSetPtr newset = NULL;
|
|
||||||
|
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
if ((CUR == '.') && (NXT(1) == '.')) {
|
if ((CUR == '.') && (NXT(1) == '.')) {
|
||||||
SKIP(2);
|
SKIP(2);
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
if (ctxt->context->nodelist == NULL) {
|
xmlXPathNodeCollectAndTest(ctxt, AXIS_PARENT,
|
||||||
STRANGE
|
|
||||||
xmlXPathRoot(ctxt);
|
|
||||||
}
|
|
||||||
newset = xmlXPathNodeCollectAndTest(ctxt, AXIS_PARENT,
|
|
||||||
NODE_TEST_TYPE, XML_ELEMENT_NODE, NULL, NULL);
|
NODE_TEST_TYPE, XML_ELEMENT_NODE, NULL, NULL);
|
||||||
if (ctxt->context->nodelist != NULL)
|
|
||||||
xmlXPathFreeNodeSet(ctxt->context->nodelist);
|
|
||||||
ctxt->context->nodelist = newset;
|
|
||||||
ctxt->context->node = NULL;
|
|
||||||
} else if (CUR == '.') {
|
} else if (CUR == '.') {
|
||||||
NEXT;
|
NEXT;
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
@ -4608,8 +4733,6 @@ xmlXPathEvalStep(xmlXPathParserContextPtr ctxt) {
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
xmlXPathEvalRelativeLocationPath(xmlXPathParserContextPtr ctxt) {
|
xmlXPathEvalRelativeLocationPath(xmlXPathParserContextPtr ctxt) {
|
||||||
xmlNodeSetPtr newset = NULL;
|
|
||||||
|
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
xmlXPathEvalStep(ctxt);
|
xmlXPathEvalStep(ctxt);
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
@ -4617,16 +4740,8 @@ xmlXPathEvalRelativeLocationPath(xmlXPathParserContextPtr ctxt) {
|
|||||||
if ((CUR == '/') && (NXT(1) == '/')) {
|
if ((CUR == '/') && (NXT(1) == '/')) {
|
||||||
SKIP(2);
|
SKIP(2);
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
if (ctxt->context->nodelist == NULL) {
|
xmlXPathNodeCollectAndTest(ctxt, AXIS_DESCENDANT_OR_SELF,
|
||||||
STRANGE
|
|
||||||
xmlXPathRoot(ctxt);
|
|
||||||
}
|
|
||||||
newset = xmlXPathNodeCollectAndTest(ctxt, AXIS_DESCENDANT_OR_SELF,
|
|
||||||
NODE_TEST_TYPE, XML_ELEMENT_NODE, NULL, NULL);
|
NODE_TEST_TYPE, XML_ELEMENT_NODE, NULL, NULL);
|
||||||
if (ctxt->context->nodelist != NULL)
|
|
||||||
xmlXPathFreeNodeSet(ctxt->context->nodelist);
|
|
||||||
ctxt->context->nodelist = newset;
|
|
||||||
ctxt->context->node = NULL;
|
|
||||||
xmlXPathEvalStep(ctxt);
|
xmlXPathEvalStep(ctxt);
|
||||||
} else if (CUR == '/') {
|
} else if (CUR == '/') {
|
||||||
NEXT;
|
NEXT;
|
||||||
@ -4658,8 +4773,6 @@ xmlXPathEvalRelativeLocationPath(xmlXPathParserContextPtr ctxt) {
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
xmlXPathEvalLocationPath(xmlXPathParserContextPtr ctxt) {
|
xmlXPathEvalLocationPath(xmlXPathParserContextPtr ctxt) {
|
||||||
xmlNodeSetPtr newset = NULL;
|
|
||||||
|
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
if (CUR != '/') {
|
if (CUR != '/') {
|
||||||
xmlXPathEvalRelativeLocationPath(ctxt);
|
xmlXPathEvalRelativeLocationPath(ctxt);
|
||||||
@ -4668,15 +4781,9 @@ xmlXPathEvalLocationPath(xmlXPathParserContextPtr ctxt) {
|
|||||||
if ((CUR == '/') && (NXT(1) == '/')) {
|
if ((CUR == '/') && (NXT(1) == '/')) {
|
||||||
SKIP(2);
|
SKIP(2);
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
if (ctxt->context->nodelist == NULL)
|
xmlXPathNodeCollectAndTest(ctxt,
|
||||||
xmlXPathRoot(ctxt);
|
|
||||||
newset = xmlXPathNodeCollectAndTest(ctxt,
|
|
||||||
AXIS_DESCENDANT_OR_SELF, NODE_TEST_TYPE,
|
AXIS_DESCENDANT_OR_SELF, NODE_TEST_TYPE,
|
||||||
XML_ELEMENT_NODE, NULL, NULL);
|
XML_ELEMENT_NODE, NULL, NULL);
|
||||||
if (ctxt->context->nodelist != NULL)
|
|
||||||
xmlXPathFreeNodeSet(ctxt->context->nodelist);
|
|
||||||
ctxt->context->nodelist = newset;
|
|
||||||
ctxt->context->node = NULL;
|
|
||||||
xmlXPathEvalRelativeLocationPath(ctxt);
|
xmlXPathEvalRelativeLocationPath(ctxt);
|
||||||
} else if (CUR == '/') {
|
} else if (CUR == '/') {
|
||||||
NEXT;
|
NEXT;
|
||||||
@ -4694,7 +4801,7 @@ xmlXPathEvalLocationPath(xmlXPathParserContextPtr ctxt) {
|
|||||||
/**
|
/**
|
||||||
* xmlXPathEval:
|
* xmlXPathEval:
|
||||||
* @str: the XPath expression
|
* @str: the XPath expression
|
||||||
* @ctxt: the XPath context
|
* @ctx: the XPath context
|
||||||
*
|
*
|
||||||
* Evaluate the XPath Location Path in the given context.
|
* Evaluate the XPath Location Path in the given context.
|
||||||
*
|
*
|
||||||
@ -4702,25 +4809,32 @@ xmlXPathEvalLocationPath(xmlXPathParserContextPtr ctxt) {
|
|||||||
* the caller has to free the object.
|
* the caller has to free the object.
|
||||||
*/
|
*/
|
||||||
xmlXPathObjectPtr
|
xmlXPathObjectPtr
|
||||||
xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctxt) {
|
xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) {
|
||||||
xmlXPathParserContextPtr pctxt;
|
xmlXPathParserContextPtr ctxt;
|
||||||
xmlXPathObjectPtr res = NULL, tmp;
|
xmlXPathObjectPtr res = NULL, tmp;
|
||||||
int stack = 0;
|
int stack = 0;
|
||||||
|
|
||||||
xmlXPathInit();
|
xmlXPathInit();
|
||||||
|
|
||||||
CHECK_CONTEXT
|
CHECK_CONTEXT(ctx)
|
||||||
|
|
||||||
if (xmlXPathDebug == NULL)
|
if (xmlXPathDebug == NULL)
|
||||||
xmlXPathDebug = stderr;
|
xmlXPathDebug = stderr;
|
||||||
pctxt = xmlXPathNewParserContext(str, ctxt);
|
ctxt = xmlXPathNewParserContext(str, ctx);
|
||||||
|
valuePush(ctxt, xmlXPathNewNodeSet(ctx->node));
|
||||||
if (str[0] == '/')
|
if (str[0] == '/')
|
||||||
xmlXPathRoot(pctxt);
|
xmlXPathRoot(ctxt);
|
||||||
xmlXPathEvalLocationPath(pctxt);
|
xmlXPathEvalLocationPath(ctxt);
|
||||||
|
|
||||||
|
if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) {
|
||||||
|
fprintf(xmlXPathDebug,
|
||||||
|
"xmlXPathEval: evaluation failed to return a node set\n");
|
||||||
|
} else {
|
||||||
|
res = valuePop(ctxt);
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: cleanup nodelist, res = valuePop(pctxt); */
|
|
||||||
do {
|
do {
|
||||||
tmp = valuePop(pctxt);
|
tmp = valuePop(ctxt);
|
||||||
if (tmp != NULL) {
|
if (tmp != NULL) {
|
||||||
xmlXPathFreeObject(tmp);
|
xmlXPathFreeObject(tmp);
|
||||||
stack++;
|
stack++;
|
||||||
@ -4730,12 +4844,12 @@ xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctxt) {
|
|||||||
fprintf(xmlXPathDebug, "xmlXPathEval: %d object left on the stack\n",
|
fprintf(xmlXPathDebug, "xmlXPathEval: %d object left on the stack\n",
|
||||||
stack);
|
stack);
|
||||||
}
|
}
|
||||||
if (pctxt->error == XPATH_EXPRESSION_OK)
|
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
||||||
res = xmlXPathNewNodeSetList(pctxt->context->nodelist);
|
xmlXPathFreeObject(res);
|
||||||
else
|
res = NULL;
|
||||||
res = NULL;
|
}
|
||||||
|
|
||||||
xmlXPathFreeParserContext(pctxt);
|
xmlXPathFreeParserContext(ctxt);
|
||||||
return(res);
|
return(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4757,7 +4871,7 @@ xmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt) {
|
|||||||
|
|
||||||
xmlXPathInit();
|
xmlXPathInit();
|
||||||
|
|
||||||
CHECK_CONTEXT
|
CHECK_CONTEXT(ctxt)
|
||||||
|
|
||||||
if (xmlXPathDebug == NULL)
|
if (xmlXPathDebug == NULL)
|
||||||
xmlXPathDebug = stderr;
|
xmlXPathDebug = stderr;
|
||||||
|
1
xpath.h
1
xpath.h
@ -143,7 +143,6 @@ struct _xmlXPathAxis {
|
|||||||
struct _xmlXPathContext {
|
struct _xmlXPathContext {
|
||||||
xmlDocPtr doc; /* The current document */
|
xmlDocPtr doc; /* The current document */
|
||||||
xmlNodePtr node; /* The current node */
|
xmlNodePtr node; /* The current node */
|
||||||
xmlNodeSetPtr nodelist; /* The current node list */
|
|
||||||
|
|
||||||
int nb_variables; /* number of defined variables */
|
int nb_variables; /* number of defined variables */
|
||||||
int max_variables; /* max number of variables */
|
int max_variables; /* max number of variables */
|
||||||
|
Reference in New Issue
Block a user