mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-07-29 11:41:22 +03:00
More work and fixes on XPath:
- debugXML.c testXPath.c xpath.[ch]: More work on XPath/Xpointer, incorporated "(TOM)" <ptittom@free.fr> patches rebuilt the XPath examples with the extra test Daniel
This commit is contained in:
@ -1,3 +1,9 @@
|
|||||||
|
Wed Oct 4 15:25:53 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
|
||||||
|
|
||||||
|
* debugXML.c testXPath.c xpath.[ch]: More work on XPath/Xpointer,
|
||||||
|
incorporated "(TOM)" <ptittom@free.fr> patches rebuilt the XPath
|
||||||
|
examples with the extra test
|
||||||
|
|
||||||
Wed Oct 4 14:39:01 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
|
Wed Oct 4 14:39:01 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
|
||||||
|
|
||||||
* parser.c xmlIO.c xmlIO.h: fixed bug 26650, and improved
|
* parser.c xmlIO.c xmlIO.h: fixed bug 26650, and improved
|
||||||
|
38
debugXML.c
38
debugXML.c
@ -584,6 +584,8 @@ void xmlDebugDumpOneNode(FILE *output, xmlNodePtr node, int depth) {
|
|||||||
xmlDebugDumpAttrList(output, node->properties, depth + 1);
|
xmlDebugDumpAttrList(output, node->properties, depth + 1);
|
||||||
if (node->type != XML_ENTITY_REF_NODE) {
|
if (node->type != XML_ENTITY_REF_NODE) {
|
||||||
if (node->content != NULL) {
|
if (node->content != NULL) {
|
||||||
|
shift[2 * i] = shift[2 * i + 1] = ' ' ;
|
||||||
|
shift[2 * i + 2] = shift[2 * i + 3] = 0 ;
|
||||||
fprintf(output, shift);
|
fprintf(output, shift);
|
||||||
fprintf(output, "content=");
|
fprintf(output, "content=");
|
||||||
#ifndef XML_USE_BUFFER_CONTENT
|
#ifndef XML_USE_BUFFER_CONTENT
|
||||||
@ -1681,6 +1683,18 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
|
|||||||
case XPATH_STRING:
|
case XPATH_STRING:
|
||||||
fprintf(stderr, "%s is a string\n", arg);
|
fprintf(stderr, "%s is a string\n", arg);
|
||||||
break;
|
break;
|
||||||
|
case XPATH_POINT:
|
||||||
|
fprintf(stderr, "%s is a point\n", arg);
|
||||||
|
break;
|
||||||
|
case XPATH_RANGE:
|
||||||
|
fprintf(stderr, "%s is a range\n", arg);
|
||||||
|
break;
|
||||||
|
case XPATH_LOCATIONSET:
|
||||||
|
fprintf(stderr, "%s is a range\n", arg);
|
||||||
|
break;
|
||||||
|
case XPATH_USERS:
|
||||||
|
fprintf(stderr, "%s is user-defined\n", arg);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
xmlXPathFreeNodeSetList(list);
|
xmlXPathFreeNodeSetList(list);
|
||||||
} else {
|
} else {
|
||||||
@ -1719,6 +1733,18 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
|
|||||||
case XPATH_STRING:
|
case XPATH_STRING:
|
||||||
fprintf(stderr, "%s is a string\n", arg);
|
fprintf(stderr, "%s is a string\n", arg);
|
||||||
break;
|
break;
|
||||||
|
case XPATH_POINT:
|
||||||
|
fprintf(stderr, "%s is a point\n", arg);
|
||||||
|
break;
|
||||||
|
case XPATH_RANGE:
|
||||||
|
fprintf(stderr, "%s is a range\n", arg);
|
||||||
|
break;
|
||||||
|
case XPATH_LOCATIONSET:
|
||||||
|
fprintf(stderr, "%s is a range\n", arg);
|
||||||
|
break;
|
||||||
|
case XPATH_USERS:
|
||||||
|
fprintf(stderr, "%s is user-defined\n", arg);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
xmlXPathFreeNodeSetList(list);
|
xmlXPathFreeNodeSetList(list);
|
||||||
} else {
|
} else {
|
||||||
@ -1761,6 +1787,18 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
|
|||||||
case XPATH_STRING:
|
case XPATH_STRING:
|
||||||
fprintf(stderr, "%s is a string\n", arg);
|
fprintf(stderr, "%s is a string\n", arg);
|
||||||
break;
|
break;
|
||||||
|
case XPATH_POINT:
|
||||||
|
fprintf(stderr, "%s is a point\n", arg);
|
||||||
|
break;
|
||||||
|
case XPATH_RANGE:
|
||||||
|
fprintf(stderr, "%s is a range\n", arg);
|
||||||
|
break;
|
||||||
|
case XPATH_LOCATIONSET:
|
||||||
|
fprintf(stderr, "%s is a range\n", arg);
|
||||||
|
break;
|
||||||
|
case XPATH_USERS:
|
||||||
|
fprintf(stderr, "%s is user-defined\n", arg);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
xmlXPathFreeNodeSetList(list);
|
xmlXPathFreeNodeSetList(list);
|
||||||
} else {
|
} else {
|
||||||
|
@ -51,7 +51,10 @@ typedef enum {
|
|||||||
XPATH_BOOLEAN = 2,
|
XPATH_BOOLEAN = 2,
|
||||||
XPATH_NUMBER = 3,
|
XPATH_NUMBER = 3,
|
||||||
XPATH_STRING = 4,
|
XPATH_STRING = 4,
|
||||||
XPATH_USERS = 5
|
XPATH_POINT = 5,
|
||||||
|
XPATH_RANGE = 6,
|
||||||
|
XPATH_LOCATIONSET = 7,
|
||||||
|
XPATH_USERS = 8
|
||||||
} xmlXPathObjectType;
|
} xmlXPathObjectType;
|
||||||
|
|
||||||
typedef struct _xmlXPathObject xmlXPathObject;
|
typedef struct _xmlXPathObject xmlXPathObject;
|
||||||
@ -63,6 +66,9 @@ struct _xmlXPathObject {
|
|||||||
double floatval;
|
double floatval;
|
||||||
xmlChar *stringval;
|
xmlChar *stringval;
|
||||||
void *user;
|
void *user;
|
||||||
|
int index;
|
||||||
|
void *user2;
|
||||||
|
int index2;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -168,6 +174,11 @@ struct _xmlXPathContext {
|
|||||||
/* extra variables */
|
/* extra variables */
|
||||||
int contextSize; /* the context size */
|
int contextSize; /* the context size */
|
||||||
int proximityPosition; /* the proximity position */
|
int proximityPosition; /* the proximity position */
|
||||||
|
|
||||||
|
/* extra stuff for XPointer */
|
||||||
|
int xptr; /* it this an XPointer context */
|
||||||
|
xmlNodePtr here; /* for here() */
|
||||||
|
xmlNodePtr origin; /* for origin() */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -220,10 +231,13 @@ typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
|
|||||||
/**
|
/**
|
||||||
* Evaluation functions.
|
* Evaluation functions.
|
||||||
*/
|
*/
|
||||||
|
void xmlXPathInit (void);
|
||||||
xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc);
|
xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc);
|
||||||
void xmlXPathFreeContext (xmlXPathContextPtr ctxt);
|
void xmlXPathFreeContext (xmlXPathContextPtr ctxt);
|
||||||
xmlXPathObjectPtr xmlXPathEval (const xmlChar *str,
|
xmlXPathObjectPtr xmlXPathEval (const xmlChar *str,
|
||||||
xmlXPathContextPtr ctxt);
|
xmlXPathContextPtr ctxt);
|
||||||
|
xmlXPathObjectPtr xmlXPathEvalXPtrExpr (const xmlChar *str,
|
||||||
|
xmlXPathContextPtr ctxt);
|
||||||
void xmlXPathFreeObject (xmlXPathObjectPtr obj);
|
void xmlXPathFreeObject (xmlXPathObjectPtr obj);
|
||||||
xmlXPathObjectPtr xmlXPathEvalExpression (const xmlChar *str,
|
xmlXPathObjectPtr xmlXPathEvalExpression (const xmlChar *str,
|
||||||
xmlXPathContextPtr ctxt);
|
xmlXPathContextPtr ctxt);
|
||||||
|
@ -1,5 +1,20 @@
|
|||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1
|
||||||
Object is a number : 1
|
Object is a number : 1
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1+2
|
||||||
Object is a number : 3
|
Object is a number : 3
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 2*3
|
||||||
Object is a number : 6
|
Object is a number : 6
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1+2*3+4
|
||||||
Object is a number : 11
|
Object is a number : 11
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: (1+2)*(3+4)
|
||||||
Object is a number : 21
|
Object is a number : 21
|
||||||
|
@ -1,24 +1,96 @@
|
|||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 0<1
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 0<=1
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 0>1
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 0>=1
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1<0
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1<=0
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1>0
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1>=0
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1<1
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1<=1
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1>1
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1>=1
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: '0'<1
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: '0'<=1
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: '0'>1
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: '0'>=1
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 0<'1.2'
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 0<='1.2'
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 0>'1.2'
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 0>='1.2'
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: false()<1
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: false()<=1
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 0>true()
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 0>=true()
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
@ -1,24 +1,96 @@
|
|||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1=1
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1!=1
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1=0
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1!=0
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: true()=true()
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: true()!=true()
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: true()=false()
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: false()!=true()
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 'test'='test'
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 'test'!='test'
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 'test2'='test'
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 'test2'!='test'
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: false()=0
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: false()!=0
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: false()=1
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: false()!=1
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 0=true()
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 0!=true()
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1=true()
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 1!=true()
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: true()='test'
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: false()='test'
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 'test'!=true()
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: 'test'!=false()
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
@ -1,5 +1,20 @@
|
|||||||
|
|
||||||
|
========================
|
||||||
|
Expression: true()
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: false()
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: number("1.5")
|
||||||
Object is a number : 1.5
|
Object is a number : 1.5
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: concat("titi",'toto')
|
||||||
Object is a string : tititoto
|
Object is a string : tititoto
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: concat("titi",'toto',"tata","last")
|
||||||
Object is a string : tititototatalast
|
Object is a string : tititototatalast
|
||||||
|
@ -1,19 +1,76 @@
|
|||||||
|
|
||||||
|
========================
|
||||||
|
Expression: string(5)
|
||||||
Object is a string : 5
|
Object is a string : 5
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: string(0.5)
|
||||||
Object is a string : 0.5
|
Object is a string : 0.5
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: string(-0.5)
|
||||||
Object is a string : -0.5
|
Object is a string : -0.5
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: string(true())
|
||||||
Object is a string : true
|
Object is a string : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: string(false())
|
||||||
Object is a string : false
|
Object is a string : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: concat("titi","toto")
|
||||||
Object is a string : tititoto
|
Object is a string : tititoto
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: concat("titi","toto","tata")
|
||||||
Object is a string : tititototata
|
Object is a string : tititototata
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: starts-with("tititoto","titi")
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: starts-with("tititoto","to")
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: contains("tititototata","titi")
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: contains("tititototata","toto")
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: contains("tititototata","tata")
|
||||||
Object is a Boolean : true
|
Object is a Boolean : true
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: contains("tititototata","tita")
|
||||||
Object is a Boolean : false
|
Object is a Boolean : false
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: substring("12345",2,3)
|
||||||
Object is a string : 234
|
Object is a string : 234
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: substring("12345",2)
|
||||||
Object is a string : 2345
|
Object is a string : 2345
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: substring("12345",1.5,2.6)
|
||||||
Object is a string : 234
|
Object is a string : 234
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: substring("12345",0,3)
|
||||||
Object is a string : 12
|
Object is a string : 12
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: string-length("")
|
||||||
Object is a number : 0
|
Object is a number : 0
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: string-length("titi")
|
||||||
Object is a number : 4
|
Object is a number : 4
|
||||||
|
@ -1,24 +1,36 @@
|
|||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT EXAMPLE
|
1 ELEMENT EXAMPLE
|
||||||
ATTRIBUTE prop1
|
ATTRIBUTE prop1
|
||||||
TEXT
|
TEXT
|
||||||
content=gnome is great
|
content=gnome is great
|
||||||
ATTRIBUTE prop2
|
ATTRIBUTE prop2
|
||||||
TEXT
|
TEXT
|
||||||
content=& linux too
|
content=& linux too
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::*
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT EXAMPLE
|
1 ELEMENT EXAMPLE
|
||||||
ATTRIBUTE prop1
|
ATTRIBUTE prop1
|
||||||
TEXT
|
TEXT
|
||||||
content=gnome is great
|
content=gnome is great
|
||||||
ATTRIBUTE prop2
|
ATTRIBUTE prop2
|
||||||
TEXT
|
TEXT
|
||||||
content=& linux too
|
content=& linux too
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/child::head
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT head
|
1 ELEMENT head
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/child::*
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 6 nodes:
|
Set contains 6 nodes:
|
||||||
1 ELEMENT head
|
1 ELEMENT head
|
||||||
@ -27,16 +39,28 @@ Set contains 6 nodes:
|
|||||||
4 ELEMENT chapter
|
4 ELEMENT chapter
|
||||||
5 ELEMENT chapter
|
5 ELEMENT chapter
|
||||||
6 ELEMENT chapter
|
6 ELEMENT chapter
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/child::head/child::title
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT title
|
1 ELEMENT title
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/child::head/child::title/child::text()
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 TEXT
|
1 TEXT
|
||||||
content=Welcome to Gnome
|
content=Welcome to Gnome
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/child::head/node()
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT title
|
1 ELEMENT title
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /descendant::title
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 6 nodes:
|
Set contains 6 nodes:
|
||||||
1 ELEMENT title
|
1 ELEMENT title
|
||||||
@ -45,6 +69,9 @@ Set contains 6 nodes:
|
|||||||
4 ELEMENT title
|
4 ELEMENT title
|
||||||
5 ELEMENT title
|
5 ELEMENT title
|
||||||
6 ELEMENT title
|
6 ELEMENT title
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /descendant::p/ancestor::chapter
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 5 nodes:
|
Set contains 5 nodes:
|
||||||
1 ELEMENT chapter
|
1 ELEMENT chapter
|
||||||
|
76
result/XPath/tests/chaptersprefol
Normal file
76
result/XPath/tests/chaptersprefol
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /following::*
|
||||||
|
Object is a Node Set :
|
||||||
|
Set contains 0 nodes:
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /preceding::*
|
||||||
|
Object is a Node Set :
|
||||||
|
Set contains 0 nodes:
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/preceding::*
|
||||||
|
Object is a Node Set :
|
||||||
|
Set contains 0 nodes:
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/following::*
|
||||||
|
Object is a Node Set :
|
||||||
|
Set contains 0 nodes:
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/child::chapter[3]/preceding::*
|
||||||
|
Object is a Node Set :
|
||||||
|
Set contains 10 nodes:
|
||||||
|
1 ELEMENT p
|
||||||
|
2 ELEMENT title
|
||||||
|
3 ELEMENT chapter
|
||||||
|
4 ELEMENT p
|
||||||
|
5 ELEMENT image
|
||||||
|
ATTRIBUTE href
|
||||||
|
TEXT
|
||||||
|
content=linus.gif
|
||||||
|
6 ELEMENT p
|
||||||
|
7 ELEMENT title
|
||||||
|
8 ELEMENT chapter
|
||||||
|
9 ELEMENT title
|
||||||
|
10 ELEMENT head
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/child::chapter[3]/following::*
|
||||||
|
Object is a Node Set :
|
||||||
|
Set contains 6 nodes:
|
||||||
|
1 ELEMENT chapter
|
||||||
|
2 ELEMENT title
|
||||||
|
3 ELEMENT p
|
||||||
|
4 ELEMENT chapter
|
||||||
|
5 ELEMENT title
|
||||||
|
6 ELEMENT p
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/child::chapter[1]/image/preceding::*
|
||||||
|
Object is a Node Set :
|
||||||
|
Set contains 4 nodes:
|
||||||
|
1 ELEMENT p
|
||||||
|
2 ELEMENT title
|
||||||
|
3 ELEMENT title
|
||||||
|
4 ELEMENT head
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/child::chapter[1]/image/following::*
|
||||||
|
Object is a Node Set :
|
||||||
|
Set contains 13 nodes:
|
||||||
|
1 ELEMENT p
|
||||||
|
2 ELEMENT chapter
|
||||||
|
3 ELEMENT title
|
||||||
|
4 ELEMENT p
|
||||||
|
5 ELEMENT chapter
|
||||||
|
6 ELEMENT title
|
||||||
|
7 ELEMENT p
|
||||||
|
8 ELEMENT chapter
|
||||||
|
9 ELEMENT title
|
||||||
|
10 ELEMENT p
|
||||||
|
11 ELEMENT chapter
|
||||||
|
12 ELEMENT title
|
||||||
|
13 ELEMENT p
|
@ -1,24 +1,33 @@
|
|||||||
|
|
||||||
|
========================
|
||||||
|
Expression: //*[@id="root"]
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT EXAMPLE
|
1 ELEMENT EXAMPLE
|
||||||
ATTRIBUTE id
|
ATTRIBUTE id
|
||||||
TEXT
|
TEXT
|
||||||
content=root
|
content=root
|
||||||
ATTRIBUTE prop1
|
ATTRIBUTE prop1
|
||||||
TEXT
|
TEXT
|
||||||
content=gnome is great
|
content=gnome is great
|
||||||
ATTRIBUTE prop2
|
ATTRIBUTE prop2
|
||||||
TEXT
|
TEXT
|
||||||
content=& linux too
|
content=& linux too
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: //*[@id="chapter2"]
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT chapter
|
1 ELEMENT chapter
|
||||||
ATTRIBUTE id
|
ATTRIBUTE id
|
||||||
TEXT
|
TEXT
|
||||||
content=chapter2
|
content=chapter2
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: //*[@id="chapter5"]
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT chapter
|
1 ELEMENT chapter
|
||||||
ATTRIBUTE id
|
ATTRIBUTE id
|
||||||
TEXT
|
TEXT
|
||||||
content=chapter5
|
content=chapter5
|
||||||
|
@ -1,39 +1,63 @@
|
|||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /EXAMPLE
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT EXAMPLE
|
1 ELEMENT EXAMPLE
|
||||||
ATTRIBUTE prop1
|
ATTRIBUTE prop1
|
||||||
TEXT
|
TEXT
|
||||||
content=gnome is great
|
content=gnome is great
|
||||||
ATTRIBUTE prop2
|
ATTRIBUTE prop2
|
||||||
TEXT
|
TEXT
|
||||||
content=& linux too
|
content=& linux too
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /EXAMPLE/head
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT head
|
1 ELEMENT head
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /EXAMPLE/chapter[1]
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT chapter
|
1 ELEMENT chapter
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: //p
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 2 nodes:
|
Set contains 2 nodes:
|
||||||
1 ELEMENT p
|
1 ELEMENT p
|
||||||
2 ELEMENT p
|
2 ELEMENT p
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: //chapter/image
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT image
|
1 ELEMENT image
|
||||||
ATTRIBUTE href
|
ATTRIBUTE href
|
||||||
TEXT
|
TEXT
|
||||||
content=linus.gif
|
content=linus.gif
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: //p/text()
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 2 nodes:
|
Set contains 2 nodes:
|
||||||
1 TEXT
|
1 TEXT
|
||||||
content=bla bla bla ...
|
content=bla bla bla ...
|
||||||
2 TEXT
|
2 TEXT
|
||||||
content=...
|
content=...
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: //p/text()[position()=1]
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 TEXT
|
1 TEXT
|
||||||
content=bla bla bla ...
|
content=bla bla bla ...
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: //p/text()[position()=last()]
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 TEXT
|
1 TEXT
|
||||||
content=...
|
content=...
|
||||||
|
@ -1,42 +1,69 @@
|
|||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::*
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT EXAMPLE
|
1 ELEMENT EXAMPLE
|
||||||
ATTRIBUTE prop1
|
ATTRIBUTE prop1
|
||||||
TEXT
|
TEXT
|
||||||
content=gnome is great
|
content=gnome is great
|
||||||
ATTRIBUTE prop2
|
ATTRIBUTE prop2
|
||||||
TEXT
|
TEXT
|
||||||
content=& linux too
|
content=& linux too
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT EXAMPLE
|
1 ELEMENT EXAMPLE
|
||||||
ATTRIBUTE prop1
|
ATTRIBUTE prop1
|
||||||
TEXT
|
TEXT
|
||||||
content=gnome is great
|
content=gnome is great
|
||||||
ATTRIBUTE prop2
|
ATTRIBUTE prop2
|
||||||
TEXT
|
TEXT
|
||||||
content=& linux too
|
content=& linux too
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/child::head
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT head
|
1 ELEMENT head
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/child::*
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 2 nodes:
|
Set contains 2 nodes:
|
||||||
1 ELEMENT head
|
1 ELEMENT head
|
||||||
2 ELEMENT chapter
|
2 ELEMENT chapter
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/child::head/child::title
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT title
|
1 ELEMENT title
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/child::head/child::title/child::text()
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 TEXT
|
1 TEXT
|
||||||
content=Welcome to Gnome
|
content=Welcome to Gnome
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /child::EXAMPLE/child::head/node()
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT title
|
1 ELEMENT title
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /descendant::title
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 2 nodes:
|
Set contains 2 nodes:
|
||||||
1 ELEMENT title
|
1 ELEMENT title
|
||||||
2 ELEMENT title
|
2 ELEMENT title
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: /descendant::p/ancestor::chapter
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT chapter
|
1 ELEMENT chapter
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
|
|
||||||
|
========================
|
||||||
|
Expression: //ITEM[1]
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 ELEMENT ITEM
|
1 ELEMENT ITEM
|
||||||
ATTRIBUTE monto
|
ATTRIBUTE monto
|
||||||
TEXT
|
TEXT
|
||||||
content=50.12
|
content=50.12
|
||||||
ATTRIBUTE divisa
|
ATTRIBUTE divisa
|
||||||
TEXT
|
TEXT
|
||||||
content=DOL
|
content=DOL
|
||||||
|
1
test/XPath/tests/chaptersprefol
Normal file
1
test/XPath/tests/chaptersprefol
Normal file
@ -0,0 +1 @@
|
|||||||
|
/following::* /preceding::* /child::EXAMPLE/preceding::* /child::EXAMPLE/following::* /child::EXAMPLE/child::chapter[3]/preceding::* /child::EXAMPLE/child::chapter[3]/following::* /child::EXAMPLE/child::chapter[1]/image/preceding::* /child::EXAMPLE/child::chapter[1]/image/following::*
|
29
testXPath.c
29
testXPath.c
@ -41,7 +41,10 @@
|
|||||||
#include <libxml/debugXML.h>
|
#include <libxml/debugXML.h>
|
||||||
#include <libxml/xmlmemory.h>
|
#include <libxml/xmlmemory.h>
|
||||||
#include <libxml/parserInternals.h>
|
#include <libxml/parserInternals.h>
|
||||||
|
#if defined(LIBXML_XPTR_ENABLED)
|
||||||
|
#include <libxml/xpointer.h>
|
||||||
|
static int xptr = 0;
|
||||||
|
#endif
|
||||||
static int debug = 0;
|
static int debug = 0;
|
||||||
static int valid = 0;
|
static int valid = 0;
|
||||||
static int expr = 0;
|
static int expr = 0;
|
||||||
@ -138,11 +141,20 @@ void testXPath(const char *str) {
|
|||||||
xmlXPathObjectPtr res;
|
xmlXPathObjectPtr res;
|
||||||
xmlXPathContextPtr ctxt;
|
xmlXPathContextPtr ctxt;
|
||||||
|
|
||||||
ctxt = xmlXPathNewContext(document);
|
#if defined(LIBXML_XPTR_ENABLED)
|
||||||
if (expr)
|
if (xptr) {
|
||||||
res = xmlXPathEvalExpression(BAD_CAST str, ctxt);
|
ctxt = xmlXPtrNewContext(document, NULL, NULL);
|
||||||
else
|
res = xmlXPtrEval(BAD_CAST str, ctxt);
|
||||||
res = xmlXPathEval(BAD_CAST str, ctxt);
|
} else {
|
||||||
|
#endif
|
||||||
|
ctxt = xmlXPathNewContext(document);
|
||||||
|
if (expr)
|
||||||
|
res = xmlXPathEvalExpression(BAD_CAST str, ctxt);
|
||||||
|
else
|
||||||
|
res = xmlXPathEval(BAD_CAST str, ctxt);
|
||||||
|
#if defined(LIBXML_XPTR_ENABLED)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
xmlXPAthDebugDumpObject(stdout, res);
|
xmlXPAthDebugDumpObject(stdout, res);
|
||||||
xmlXPathFreeObject(res);
|
xmlXPathFreeObject(res);
|
||||||
xmlXPathFreeContext(ctxt);
|
xmlXPathFreeContext(ctxt);
|
||||||
@ -158,6 +170,7 @@ void testXPathFile(const char *filename) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (fscanf(input, "%s", expr) != EOF) {
|
while (fscanf(input, "%s", expr) != EOF) {
|
||||||
|
printf("\n========================\nExpression: %s\n", expr) ;
|
||||||
testXPath(expr);
|
testXPath(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,6 +184,10 @@ int main(int argc, char **argv) {
|
|||||||
char *filename = NULL;
|
char *filename = NULL;
|
||||||
|
|
||||||
for (i = 1; i < argc ; i++) {
|
for (i = 1; i < argc ; i++) {
|
||||||
|
#if defined(LIBXML_XPTR_ENABLED)
|
||||||
|
if ((!strcmp(argv[i], "-xptr")) || (!strcmp(argv[i], "--xptr")))
|
||||||
|
xptr++;
|
||||||
|
#endif
|
||||||
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")))
|
if ((!strcmp(argv[i], "-valid")) || (!strcmp(argv[i], "--valid")))
|
||||||
|
796
xpath.c
796
xpath.c
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* xpath.c: XML Path Language implementation
|
* xpath.c: XML Path Language implementation
|
||||||
* XPath is a language for addressing parts of an XML document,
|
* XPath is a language for addressing parts of an XML document,
|
||||||
* designed to be used by both XSLT and XPointer.
|
* designed to be used by both XSLT and XPtr.
|
||||||
*
|
*
|
||||||
* Reference: W3C Working Draft internal 5 July 1999
|
* Reference: W3C Working Draft internal 5 July 1999
|
||||||
* http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html
|
* http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html
|
||||||
@ -49,6 +49,9 @@
|
|||||||
#include <libxml/valid.h>
|
#include <libxml/valid.h>
|
||||||
#include <libxml/xpath.h>
|
#include <libxml/xpath.h>
|
||||||
#include <libxml/parserInternals.h>
|
#include <libxml/parserInternals.h>
|
||||||
|
#ifdef LIBXML_XPTR_ENABLED
|
||||||
|
#include <libxml/xpointer.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* #define DEBUG */
|
/* #define DEBUG */
|
||||||
/* #define DEBUG_STEP */
|
/* #define DEBUG_STEP */
|
||||||
@ -792,6 +795,507 @@ xmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) {
|
|||||||
xmlFree(obj);
|
xmlFree(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LIBXML_XPTR_ENABLED
|
||||||
|
/**
|
||||||
|
* xmlXPathNewPoint:
|
||||||
|
* @node: the xmlNodePtr
|
||||||
|
* @index: the index within the node
|
||||||
|
*
|
||||||
|
* Create a new xmlXPathObjectPtr of type point
|
||||||
|
*
|
||||||
|
* Returns the newly created object.
|
||||||
|
*/
|
||||||
|
xmlXPathObjectPtr
|
||||||
|
xmlXPathNewPoint(xmlNodePtr node, int index) {
|
||||||
|
xmlXPathObjectPtr ret;
|
||||||
|
|
||||||
|
if (node == NULL)
|
||||||
|
return(NULL);
|
||||||
|
if (index < 0)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
||||||
|
if (ret == NULL) {
|
||||||
|
fprintf(xmlXPathDebug, "xmlXPathNewPoint: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
||||||
|
ret->type = XPATH_POINT;
|
||||||
|
ret->user = (void *) node;
|
||||||
|
ret->index = index;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathNewRangePoints:
|
||||||
|
* @start: the starting point
|
||||||
|
* @end: the ending point
|
||||||
|
*
|
||||||
|
* Create a new xmlXPathObjectPtr of type range using 2 Points
|
||||||
|
*
|
||||||
|
* Returns the newly created object.
|
||||||
|
*/
|
||||||
|
xmlXPathObjectPtr
|
||||||
|
xmlXPathNewRangePoints(xmlXPathObjectPtr start, xmlXPathObjectPtr end) {
|
||||||
|
xmlXPathObjectPtr ret;
|
||||||
|
|
||||||
|
if (start == NULL)
|
||||||
|
return(NULL);
|
||||||
|
if (end == NULL)
|
||||||
|
return(NULL);
|
||||||
|
if (start->type != XPATH_POINT)
|
||||||
|
return(NULL);
|
||||||
|
if (end->type != XPATH_POINT)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
||||||
|
if (ret == NULL) {
|
||||||
|
fprintf(xmlXPathDebug, "xmlXPathNewRangePoints: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
||||||
|
ret->type = XPATH_RANGE;
|
||||||
|
ret->user = start->user;
|
||||||
|
ret->index = start->index;
|
||||||
|
ret->user2 = end->user;
|
||||||
|
ret->index2 = end->index;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathNewRangePointNode:
|
||||||
|
* @start: the starting point
|
||||||
|
* @end: the ending node
|
||||||
|
*
|
||||||
|
* Create a new xmlXPathObjectPtr of type range from a point to a node
|
||||||
|
*
|
||||||
|
* Returns the newly created object.
|
||||||
|
*/
|
||||||
|
xmlXPathObjectPtr
|
||||||
|
xmlXPathNewRangePointNode(xmlXPathObjectPtr start, xmlNodePtr end) {
|
||||||
|
xmlXPathObjectPtr ret;
|
||||||
|
|
||||||
|
if (start == NULL)
|
||||||
|
return(NULL);
|
||||||
|
if (end == NULL)
|
||||||
|
return(NULL);
|
||||||
|
if (start->type != XPATH_POINT)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
||||||
|
if (ret == NULL) {
|
||||||
|
fprintf(xmlXPathDebug, "xmlXPathNewRangePointNode: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
||||||
|
ret->type = XPATH_RANGE;
|
||||||
|
ret->user = start->user;
|
||||||
|
ret->index = start->index;
|
||||||
|
ret->user2 = end;
|
||||||
|
ret->index2 = -1;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathNewRangeNodePoint:
|
||||||
|
* @start: the starting node
|
||||||
|
* @end: the ending point
|
||||||
|
*
|
||||||
|
* Create a new xmlXPathObjectPtr of type range from a node to a point
|
||||||
|
*
|
||||||
|
* Returns the newly created object.
|
||||||
|
*/
|
||||||
|
xmlXPathObjectPtr
|
||||||
|
xmlXPathNewRangeNodePoint(xmlNodePtr start, xmlXPathObjectPtr end) {
|
||||||
|
xmlXPathObjectPtr ret;
|
||||||
|
|
||||||
|
if (start == NULL)
|
||||||
|
return(NULL);
|
||||||
|
if (end == NULL)
|
||||||
|
return(NULL);
|
||||||
|
if (start->type != XPATH_POINT)
|
||||||
|
return(NULL);
|
||||||
|
if (end->type != XPATH_POINT)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
||||||
|
if (ret == NULL) {
|
||||||
|
fprintf(xmlXPathDebug, "xmlXPathNewRangeNodePoint: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
||||||
|
ret->type = XPATH_RANGE;
|
||||||
|
ret->user = start;
|
||||||
|
ret->index = -1;
|
||||||
|
ret->user2 = end->user;
|
||||||
|
ret->index2 = end->index;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathNewRangeNodes:
|
||||||
|
* @start: the starting node
|
||||||
|
* @end: the ending node
|
||||||
|
*
|
||||||
|
* Create a new xmlXPathObjectPtr of type range using 2 nodes
|
||||||
|
*
|
||||||
|
* Returns the newly created object.
|
||||||
|
*/
|
||||||
|
xmlXPathObjectPtr
|
||||||
|
xmlXPathNewRangeNodes(xmlNodePtr start, xmlNodePtr end) {
|
||||||
|
xmlXPathObjectPtr ret;
|
||||||
|
|
||||||
|
if (start == NULL)
|
||||||
|
return(NULL);
|
||||||
|
if (end == NULL)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
||||||
|
if (ret == NULL) {
|
||||||
|
fprintf(xmlXPathDebug, "xmlXPathNewRangeNodes: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
||||||
|
ret->type = XPATH_RANGE;
|
||||||
|
ret->user = start;
|
||||||
|
ret->index = -1;
|
||||||
|
ret->user2 = end;
|
||||||
|
ret->index2 = -1;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathNewRangeNodeObject:
|
||||||
|
* @start: the starting node
|
||||||
|
* @end: the ending object
|
||||||
|
*
|
||||||
|
* Create a new xmlXPathObjectPtr of type range from a not to an object
|
||||||
|
*
|
||||||
|
* Returns the newly created object.
|
||||||
|
*/
|
||||||
|
xmlXPathObjectPtr
|
||||||
|
xmlXPathNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
|
||||||
|
xmlXPathObjectPtr ret;
|
||||||
|
|
||||||
|
if (start == NULL)
|
||||||
|
return(NULL);
|
||||||
|
if (end == NULL)
|
||||||
|
return(NULL);
|
||||||
|
switch (end->type) {
|
||||||
|
case XPATH_POINT:
|
||||||
|
break;
|
||||||
|
case XPATH_NODESET:
|
||||||
|
/*
|
||||||
|
* Empty set ...
|
||||||
|
*/
|
||||||
|
if (end->nodesetval->nodeNr <= 0)
|
||||||
|
return(NULL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TODO
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
||||||
|
if (ret == NULL) {
|
||||||
|
fprintf(xmlXPathDebug, "xmlXPathNewRangeNodeObject: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
||||||
|
ret->type = XPATH_RANGE;
|
||||||
|
ret->user = start;
|
||||||
|
ret->index = -1;
|
||||||
|
switch (end->type) {
|
||||||
|
case XPATH_POINT:
|
||||||
|
ret->user2 = end->user;
|
||||||
|
ret->index2 = end->index;
|
||||||
|
case XPATH_NODESET: {
|
||||||
|
ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - -1];
|
||||||
|
ret->index2 = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
STRANGE
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
ret->user2 = end;
|
||||||
|
ret->index2 = -1;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define XML_RANGESET_DEFAULT 10
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathRangeSetCreate:
|
||||||
|
* @val: an initial xmlXPathObjectPtr, or NULL
|
||||||
|
*
|
||||||
|
* Create a new xmlRangeSetPtr of type double and of value @val
|
||||||
|
*
|
||||||
|
* Returns the newly created object.
|
||||||
|
*/
|
||||||
|
xmlRangeSetPtr
|
||||||
|
xmlXPathRangeSetCreate(xmlXPathObjectPtr val) {
|
||||||
|
xmlRangeSetPtr ret;
|
||||||
|
|
||||||
|
ret = (xmlRangeSetPtr) xmlMalloc(sizeof(xmlRangeSet));
|
||||||
|
if (ret == NULL) {
|
||||||
|
fprintf(xmlXPathDebug, "xmlXPathNewRangeSet: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
memset(ret, 0 , (size_t) sizeof(xmlRangeSet));
|
||||||
|
if (val != NULL) {
|
||||||
|
ret->rangeTab = (xmlXPathObjectPtr *) xmlMalloc(XML_RANGESET_DEFAULT *
|
||||||
|
sizeof(xmlXPathObjectPtr));
|
||||||
|
if (ret->rangeTab == NULL) {
|
||||||
|
fprintf(xmlXPathDebug, "xmlXPathNewRangeSet: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
memset(ret->rangeTab, 0 ,
|
||||||
|
XML_RANGESET_DEFAULT * (size_t) sizeof(xmlXPathObjectPtr));
|
||||||
|
ret->rangeMax = XML_RANGESET_DEFAULT;
|
||||||
|
ret->rangeTab[ret->rangeNr++] = val;
|
||||||
|
}
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathRangeSetAdd:
|
||||||
|
* @cur: the initial range set
|
||||||
|
* @val: a new xmlXPathObjectPtr
|
||||||
|
*
|
||||||
|
* add a new xmlXPathObjectPtr ot an existing RangeSet
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xmlXPathRangeSetAdd(xmlRangeSetPtr cur, xmlXPathObjectPtr val) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (val == NULL) return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check against doublons
|
||||||
|
*/
|
||||||
|
for (i = 0;i < cur->rangeNr;i++)
|
||||||
|
if (cur->rangeTab[i] == val) return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* grow the rangeTab if needed
|
||||||
|
*/
|
||||||
|
if (cur->rangeMax == 0) {
|
||||||
|
cur->rangeTab = (xmlXPathObjectPtr *) xmlMalloc(XML_RANGESET_DEFAULT *
|
||||||
|
sizeof(xmlXPathObjectPtr));
|
||||||
|
if (cur->rangeTab == NULL) {
|
||||||
|
fprintf(xmlXPathDebug, "xmlXPathRangeSetAdd: out of memory\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memset(cur->rangeTab, 0 ,
|
||||||
|
XML_RANGESET_DEFAULT * (size_t) sizeof(xmlXPathObjectPtr));
|
||||||
|
cur->rangeMax = XML_RANGESET_DEFAULT;
|
||||||
|
} else if (cur->rangeNr == cur->rangeMax) {
|
||||||
|
xmlXPathObjectPtr *temp;
|
||||||
|
|
||||||
|
cur->rangeMax *= 2;
|
||||||
|
temp = (xmlXPathObjectPtr *) xmlRealloc(cur->rangeTab, cur->rangeMax *
|
||||||
|
sizeof(xmlXPathObjectPtr));
|
||||||
|
if (temp == NULL) {
|
||||||
|
fprintf(xmlXPathDebug, "xmlXPathRangeSetAdd: out of memory\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cur->rangeTab = temp;
|
||||||
|
}
|
||||||
|
cur->rangeTab[cur->rangeNr++] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathRangeSetMerge:
|
||||||
|
* @val1: the first RangeSet
|
||||||
|
* @val2: the second RangeSet
|
||||||
|
*
|
||||||
|
* Merges two rangesets, all ranges from @val2 are added to @val1
|
||||||
|
*
|
||||||
|
* Returns val1 once extended or NULL in case of error.
|
||||||
|
*/
|
||||||
|
xmlRangeSetPtr
|
||||||
|
xmlXPathRangeSetMerge(xmlRangeSetPtr val1, xmlRangeSetPtr val2) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (val1 == NULL) return(NULL);
|
||||||
|
if (val2 == NULL) return(val1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* !!!!! this can be optimized a lot, knowing that both
|
||||||
|
* val1 and val2 already have unicity of their values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (i = 0;i < val2->rangeNr;i++)
|
||||||
|
xmlXPathRangeSetAdd(val1, val2->rangeTab[i]);
|
||||||
|
|
||||||
|
return(val1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathRangeSetDel:
|
||||||
|
* @cur: the initial range set
|
||||||
|
* @val: an xmlXPathObjectPtr
|
||||||
|
*
|
||||||
|
* Removes an xmlXPathObjectPtr from an existing RangeSet
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xmlXPathRangeSetDel(xmlRangeSetPtr cur, xmlXPathObjectPtr val) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (cur == NULL) return;
|
||||||
|
if (val == NULL) return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check against doublons
|
||||||
|
*/
|
||||||
|
for (i = 0;i < cur->rangeNr;i++)
|
||||||
|
if (cur->rangeTab[i] == val) break;
|
||||||
|
|
||||||
|
if (i >= cur->rangeNr) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(xmlXPathDebug,
|
||||||
|
"xmlXPathRangeSetDel: Range %s wasn't found in RangeList\n",
|
||||||
|
val->name);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cur->rangeNr--;
|
||||||
|
for (;i < cur->rangeNr;i++)
|
||||||
|
cur->rangeTab[i] = cur->rangeTab[i + 1];
|
||||||
|
cur->rangeTab[cur->rangeNr] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathRangeSetRemove:
|
||||||
|
* @cur: the initial range set
|
||||||
|
* @val: the index to remove
|
||||||
|
*
|
||||||
|
* Removes an entry from an existing RangeSet list.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xmlXPathRangeSetRemove(xmlRangeSetPtr cur, int val) {
|
||||||
|
if (cur == NULL) return;
|
||||||
|
if (val >= cur->rangeNr) return;
|
||||||
|
cur->rangeNr--;
|
||||||
|
for (;val < cur->rangeNr;val++)
|
||||||
|
cur->rangeTab[val] = cur->rangeTab[val + 1];
|
||||||
|
cur->rangeTab[cur->rangeNr] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathFreeRangeSet:
|
||||||
|
* @obj: the xmlRangeSetPtr to free
|
||||||
|
*
|
||||||
|
* Free the RangeSet compound (not the actual ranges !).
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xmlXPathFreeRangeSet(xmlRangeSetPtr obj) {
|
||||||
|
if (obj == NULL) return;
|
||||||
|
if (obj->rangeTab != NULL) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
memset(obj->rangeTab, 0xB ,
|
||||||
|
(size_t) sizeof(xmlXPathObjectPtr) * obj->rangeMax);
|
||||||
|
#endif
|
||||||
|
xmlFree(obj->rangeTab);
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
memset(obj, 0xB , (size_t) sizeof(xmlRangeSet));
|
||||||
|
#endif
|
||||||
|
xmlFree(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(DEBUG) || defined(DEBUG_STEP)
|
||||||
|
/**
|
||||||
|
* xmlXPathDebugRangeSet:
|
||||||
|
* @output: a FILE * for the output
|
||||||
|
* @obj: the xmlRangeSetPtr to free
|
||||||
|
*
|
||||||
|
* Quick display of a RangeSet
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xmlXPathDebugRangeSet(FILE *output, xmlRangeSetPtr obj) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (output == NULL) output = xmlXPathDebug;
|
||||||
|
if (obj == NULL) {
|
||||||
|
fprintf(output, "RangeSet == NULL !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (obj->rangeNr == 0) {
|
||||||
|
fprintf(output, "RangeSet is empty\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (obj->rangeTab == NULL) {
|
||||||
|
fprintf(output, " rangeTab == NULL !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (i = 0; i < obj->rangeNr; i++) {
|
||||||
|
if (obj->rangeTab[i] == NULL) {
|
||||||
|
fprintf(output, " NULL !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((obj->rangeTab[i]->type == XML_DOCUMENT_NODE) ||
|
||||||
|
(obj->rangeTab[i]->type == XML_HTML_DOCUMENT_NODE))
|
||||||
|
fprintf(output, " /");
|
||||||
|
else if (obj->rangeTab[i]->name == NULL)
|
||||||
|
fprintf(output, " noname!");
|
||||||
|
else fprintf(output, " %s", obj->rangeTab[i]->name);
|
||||||
|
}
|
||||||
|
fprintf(output, "\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathNewRangeSetNodes:
|
||||||
|
* @start: the NodePtr value
|
||||||
|
* @end: the NodePtr value
|
||||||
|
*
|
||||||
|
* Create a new xmlXPathObjectPtr of type RangeSet and initialize
|
||||||
|
* it with the single range made of the two nodes @start and @end
|
||||||
|
*
|
||||||
|
* Returns the newly created object.
|
||||||
|
*/
|
||||||
|
xmlXPathObjectPtr
|
||||||
|
xmlXPathNewRangeSetNodes(xmlNodePtr start, xmlNodePtr end) {
|
||||||
|
xmlXPathObjectPtr ret;
|
||||||
|
|
||||||
|
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
||||||
|
if (ret == NULL) {
|
||||||
|
fprintf(xmlXPathDebug, "xmlXPathNewRangeSet: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
||||||
|
ret->type = XPATH_LOCATIONSET;
|
||||||
|
ret->user = xmlXPathRangeSetCreate(xmlXPathNewRangeNodes(start, end));
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathWrapRangeSet:
|
||||||
|
* @val: the RangeSet value
|
||||||
|
*
|
||||||
|
* Wrap the RangeSet @val in a new xmlXPathObjectPtr
|
||||||
|
*
|
||||||
|
* Returns the newly created object.
|
||||||
|
*/
|
||||||
|
xmlXPathObjectPtr
|
||||||
|
xmlXPathWrapRangeSet(xmlRangeSetPtr val) {
|
||||||
|
xmlXPathObjectPtr ret;
|
||||||
|
|
||||||
|
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
|
||||||
|
if (ret == NULL) {
|
||||||
|
fprintf(xmlXPathDebug, "xmlXPathWrapRangeSet: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
|
||||||
|
ret->type = XPATH_LOCATIONSET;
|
||||||
|
ret->user = (void *) val;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LIBXML_XPTR_ENABLED */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlXPathFreeObject:
|
* xmlXPathFreeObject:
|
||||||
* @obj: the object to free
|
* @obj: the object to free
|
||||||
@ -801,10 +1305,14 @@ xmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) {
|
|||||||
void
|
void
|
||||||
xmlXPathFreeObject(xmlXPathObjectPtr obj) {
|
xmlXPathFreeObject(xmlXPathObjectPtr obj) {
|
||||||
if (obj == NULL) return;
|
if (obj == NULL) return;
|
||||||
if (obj->nodesetval != NULL)
|
if (obj->type == XPATH_NODESET) {
|
||||||
xmlXPathFreeNodeSet(obj->nodesetval);
|
if (obj->nodesetval != NULL)
|
||||||
if (obj->stringval != NULL)
|
xmlXPathFreeNodeSet(obj->nodesetval);
|
||||||
xmlFree(obj->stringval);
|
} else if (obj->type == XPATH_STRING) {
|
||||||
|
if (obj->stringval != NULL)
|
||||||
|
xmlFree(obj->stringval);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
memset(obj, 0xB , (size_t) sizeof(xmlXPathObject));
|
memset(obj, 0xB , (size_t) sizeof(xmlXPathObject));
|
||||||
#endif
|
#endif
|
||||||
@ -1153,6 +1661,9 @@ xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
|
|||||||
ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval);
|
ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval);
|
||||||
break;
|
break;
|
||||||
case XPATH_USERS:
|
case XPATH_USERS:
|
||||||
|
case XPATH_POINT:
|
||||||
|
case XPATH_RANGE:
|
||||||
|
case XPATH_LOCATIONSET:
|
||||||
TODO
|
TODO
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1190,6 +1701,9 @@ xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
|
|||||||
ret = (arg1->boolval == ret);
|
ret = (arg1->boolval == ret);
|
||||||
break;
|
break;
|
||||||
case XPATH_USERS:
|
case XPATH_USERS:
|
||||||
|
case XPATH_POINT:
|
||||||
|
case XPATH_RANGE:
|
||||||
|
case XPATH_LOCATIONSET:
|
||||||
TODO
|
TODO
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1218,6 +1732,9 @@ xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
|
|||||||
ret = (arg1->floatval == arg2->floatval);
|
ret = (arg1->floatval == arg2->floatval);
|
||||||
break;
|
break;
|
||||||
case XPATH_USERS:
|
case XPATH_USERS:
|
||||||
|
case XPATH_POINT:
|
||||||
|
case XPATH_RANGE:
|
||||||
|
case XPATH_LOCATIONSET:
|
||||||
TODO
|
TODO
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1249,11 +1766,17 @@ xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
|
|||||||
ret = (arg1->floatval == arg2->floatval);
|
ret = (arg1->floatval == arg2->floatval);
|
||||||
break;
|
break;
|
||||||
case XPATH_USERS:
|
case XPATH_USERS:
|
||||||
|
case XPATH_POINT:
|
||||||
|
case XPATH_RANGE:
|
||||||
|
case XPATH_LOCATIONSET:
|
||||||
TODO
|
TODO
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XPATH_USERS:
|
case XPATH_USERS:
|
||||||
|
case XPATH_POINT:
|
||||||
|
case XPATH_RANGE:
|
||||||
|
case XPATH_LOCATIONSET:
|
||||||
TODO
|
TODO
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1852,25 +2375,29 @@ xmlNodePtr
|
|||||||
xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
||||||
if (cur != NULL && cur->children != NULL)
|
if (cur != NULL && cur->children != NULL)
|
||||||
return cur->children ;
|
return cur->children ;
|
||||||
if (cur == NULL)
|
if (cur == NULL) cur = ctxt->context->node;
|
||||||
if ((cur = ctxt->context->node) == NULL) return(NULL) ;
|
if (cur == NULL) return(NULL) ; /* ERROR */
|
||||||
|
if (cur->next != NULL) return(cur->next) ;
|
||||||
do {
|
do {
|
||||||
cur = cur->parent;
|
cur = cur->parent;
|
||||||
if (cur == NULL) return(NULL);
|
if (cur == NULL) return(NULL);
|
||||||
if (cur == ctxt->context->doc->children) return(NULL);
|
if (cur == ctxt->context->doc->children) return(NULL); /* !!!!!?!? */
|
||||||
if (cur->next != NULL) {
|
if (cur->next != NULL) return(cur->next);
|
||||||
cur = cur->next;
|
|
||||||
return(cur);
|
|
||||||
}
|
|
||||||
} while (cur != NULL);
|
} while (cur != NULL);
|
||||||
return(cur);
|
return(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* xmlXPathIsAncestor:
|
||||||
|
* @ancestor: the ancestor node
|
||||||
|
* @node: the current node
|
||||||
|
*
|
||||||
|
* Check that @ancestor is a @node's ancestor
|
||||||
|
*
|
||||||
* returns 1 if @ancestor is a @node's ancestor, 0 otherwise.
|
* returns 1 if @ancestor is a @node's ancestor, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
isAncestor(xmlNodePtr ancestor, xmlNodePtr node) {
|
xmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) {
|
||||||
xmlNodePtr tmp ;
|
xmlNodePtr tmp ;
|
||||||
if (ancestor == NULL || node == NULL) return 0 ;
|
if (ancestor == NULL || node == NULL) return 0 ;
|
||||||
for (tmp = node ; tmp->parent != NULL ; tmp = tmp->parent) {
|
for (tmp = node ; tmp->parent != NULL ; tmp = tmp->parent) {
|
||||||
@ -1907,81 +2434,10 @@ xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
cur = cur->parent;
|
cur = cur->parent;
|
||||||
if (cur == NULL) return(NULL);
|
if (cur == NULL) return(NULL);
|
||||||
if (cur == ctxt->context->doc->children) return(NULL);
|
if (cur == ctxt->context->doc->children) return(NULL);
|
||||||
} while (isAncestor(cur, ctxt->context->node));
|
} while (xmlXPathIsAncestor(cur, ctxt->context->node));
|
||||||
return(cur);
|
return(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* OLD VERSION, I was told they were broken ! */
|
|
||||||
/**
|
|
||||||
* 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 == (xmlNodePtr) ctxt->context->doc)
|
|
||||||
return(NULL);
|
|
||||||
if (cur == NULL)
|
|
||||||
return(ctxt->context->node->next);; /* !!!!!!!!! */
|
|
||||||
if (cur->children != NULL) return(cur->children);
|
|
||||||
if (cur->next != NULL) return(cur->next);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 == (xmlNodePtr) ctxt->context->doc)
|
|
||||||
return(NULL);
|
|
||||||
if (cur == NULL)
|
|
||||||
return(ctxt->context->node->prev); /* !!!!!!!!! */
|
|
||||||
if (cur->last != NULL) return(cur->last);
|
|
||||||
if (cur->prev != NULL) return(cur->prev);
|
|
||||||
|
|
||||||
do {
|
|
||||||
cur = cur->parent;
|
|
||||||
if (cur == NULL) return(NULL);
|
|
||||||
if (cur == ctxt->context->doc->children) return(NULL);
|
|
||||||
if (cur->prev != NULL) {
|
|
||||||
cur = cur->prev;
|
|
||||||
return(cur);
|
|
||||||
}
|
|
||||||
} while (cur != NULL);
|
|
||||||
return(cur);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlXPathNextNamespace:
|
* xmlXPathNextNamespace:
|
||||||
* @ctxt: the XPath Parser context
|
* @ctxt: the XPath Parser context
|
||||||
@ -2653,6 +3109,9 @@ xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case XPATH_USERS:
|
case XPATH_USERS:
|
||||||
|
case XPATH_POINT:
|
||||||
|
case XPATH_RANGE:
|
||||||
|
case XPATH_LOCATIONSET:
|
||||||
TODO
|
TODO
|
||||||
valuePush(ctxt, xmlXPathNewCString(""));
|
valuePush(ctxt, xmlXPathNewCString(""));
|
||||||
break;
|
break;
|
||||||
@ -3242,6 +3701,9 @@ xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
valuePush(ctxt, cur);
|
valuePush(ctxt, cur);
|
||||||
return;
|
return;
|
||||||
case XPATH_USERS:
|
case XPATH_USERS:
|
||||||
|
case XPATH_POINT:
|
||||||
|
case XPATH_RANGE:
|
||||||
|
case XPATH_LOCATIONSET:
|
||||||
TODO
|
TODO
|
||||||
valuePush(ctxt, xmlXPathNewFloat(0.0));
|
valuePush(ctxt, xmlXPathNewFloat(0.0));
|
||||||
break;
|
break;
|
||||||
@ -4675,10 +5137,17 @@ search_nodes:
|
|||||||
* xmlXPathEvalStep:
|
* xmlXPathEvalStep:
|
||||||
* @ctxt: the XPath Parser context
|
* @ctxt: the XPath Parser context
|
||||||
*
|
*
|
||||||
* [4] Step ::= Basis Predicate*
|
* TODO [4] was changed between the WD and the REC
|
||||||
|
*
|
||||||
|
* [4] Step ::= AxisSpecifier NodeTest Predicate*
|
||||||
* | AbbreviatedStep
|
* | AbbreviatedStep
|
||||||
* [12] AbbreviatedStep ::= '.'
|
* [12] AbbreviatedStep ::= '.' | '..'
|
||||||
* | '..'
|
*
|
||||||
|
* Modified for XPtr range support as:
|
||||||
|
*
|
||||||
|
* [4xptr] Step ::= AxisSpecifier NodeTest Predicate*
|
||||||
|
* | AbbreviatedStep
|
||||||
|
* | 'range-to' '(' Expr ')' Predicate*
|
||||||
*
|
*
|
||||||
* Evaluate one step in a Location Path
|
* Evaluate one step in a Location Path
|
||||||
* A location step of . is short for self::node(). This is
|
* A location step of . is short for self::node(). This is
|
||||||
@ -4704,7 +5173,99 @@ xmlXPathEvalStep(xmlXPathParserContextPtr ctxt) {
|
|||||||
NEXT;
|
NEXT;
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
} else {
|
} else {
|
||||||
xmlXPathEvalBasis(ctxt);
|
#ifdef LIBXML_XPTR_ENABLED
|
||||||
|
if ((CUR == 'r') && (NXT(1) == 'a') && (NXT(2) == 'n') &&
|
||||||
|
(NXT(3) == 'g') && (NXT(4) == 'e') && (NXT(5) == '-') &&
|
||||||
|
(NXT(6) == 't') && (NXT(7) == 'o')) {
|
||||||
|
xmlXPathObjectPtr range;
|
||||||
|
const xmlChar *cur;
|
||||||
|
xmlXPathObjectPtr res, obj;
|
||||||
|
xmlXPathObjectPtr tmp;
|
||||||
|
xmlRangeSetPtr newset = NULL;
|
||||||
|
xmlNodeSetPtr oldset;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
CHECK_TYPE(XPATH_NODESET);
|
||||||
|
obj = valuePop(ctxt);
|
||||||
|
oldset = obj->nodesetval;
|
||||||
|
ctxt->context->node = NULL;
|
||||||
|
|
||||||
|
SKIP(8);
|
||||||
|
SKIP_BLANKS;
|
||||||
|
if (CUR != '(') {
|
||||||
|
XP_ERROR(XPATH_EXPR_ERROR);
|
||||||
|
}
|
||||||
|
NEXT;
|
||||||
|
SKIP_BLANKS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save the expression pointer since we will have to evaluate
|
||||||
|
* it multiple times. Initialize the new set.
|
||||||
|
*/
|
||||||
|
cur = ctxt->cur;
|
||||||
|
newset = xmlXPathRangeSetCreate(NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < oldset->nodeNr; i++) {
|
||||||
|
ctxt->cur = cur;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Run the evaluation with a node list made of a single item
|
||||||
|
* in the nodeset.
|
||||||
|
*/
|
||||||
|
ctxt->context->node = oldset->nodeTab[i];
|
||||||
|
tmp = xmlXPathNewNodeSet(ctxt->context->node);
|
||||||
|
valuePush(ctxt, tmp);
|
||||||
|
|
||||||
|
xmlXPathEvalExpr(ctxt);
|
||||||
|
CHECK_ERROR;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The result of the evaluation need to be tested to
|
||||||
|
* decided whether the filter succeeded or not
|
||||||
|
*/
|
||||||
|
res = valuePop(ctxt);
|
||||||
|
range = xmlXPathNewRangeNodeObject(oldset->nodeTab[0], res);
|
||||||
|
if (range != NULL) {
|
||||||
|
xmlXPathRangeSetAdd(newset, range);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cleanup
|
||||||
|
*/
|
||||||
|
if (res != NULL)
|
||||||
|
xmlXPathFreeObject(res);
|
||||||
|
if (ctxt->value == tmp) {
|
||||||
|
res = valuePop(ctxt);
|
||||||
|
xmlXPathFreeObject(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxt->context->node = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The result is used as the new evaluation set.
|
||||||
|
*/
|
||||||
|
xmlXPathFreeObject(obj);
|
||||||
|
ctxt->context->node = NULL;
|
||||||
|
ctxt->context->contextSize = -1;
|
||||||
|
ctxt->context->proximityPosition = -1;
|
||||||
|
valuePush(ctxt, xmlXPathWrapRangeSet(newset));
|
||||||
|
|
||||||
|
SKIP_BLANKS;
|
||||||
|
if (CUR != ')') {
|
||||||
|
XP_ERROR(XPATH_EXPR_ERROR);
|
||||||
|
}
|
||||||
|
NEXT;
|
||||||
|
SKIP_BLANKS;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* TODO cleanup productions/procedures
|
||||||
|
* Basis is no more an XPath production !
|
||||||
|
*/
|
||||||
|
xmlXPathEvalBasis(ctxt);
|
||||||
|
}
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
while (CUR == '[') {
|
while (CUR == '[') {
|
||||||
xmlXPathEvalPredicate(ctxt);
|
xmlXPathEvalPredicate(ctxt);
|
||||||
@ -4853,6 +5414,63 @@ xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) {
|
|||||||
return(res);
|
return(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathEvalXPtrExpr:
|
||||||
|
* @str: the XPointer XPtrExpr expression
|
||||||
|
* @ctx: the XPointer context
|
||||||
|
*
|
||||||
|
* Evaluate the location set corresponding to this expression.
|
||||||
|
*
|
||||||
|
* Returns the xmlXPathObjectPtr resulting from the eveluation or NULL.
|
||||||
|
* the caller has to free the object.
|
||||||
|
*/
|
||||||
|
xmlXPathObjectPtr
|
||||||
|
xmlXPathEvalXPtrExpr(const xmlChar *str, xmlXPathContextPtr ctx) {
|
||||||
|
xmlXPathParserContextPtr ctxt;
|
||||||
|
xmlXPathObjectPtr res = NULL, tmp;
|
||||||
|
int stack = 0;
|
||||||
|
|
||||||
|
xmlXPathInit();
|
||||||
|
|
||||||
|
CHECK_CONTEXT(ctx)
|
||||||
|
|
||||||
|
if (xmlXPathDebug == NULL)
|
||||||
|
xmlXPathDebug = stderr;
|
||||||
|
ctxt = xmlXPathNewParserContext(str, ctx);
|
||||||
|
valuePush(ctxt, xmlXPathNewNodeSet(ctx->node));
|
||||||
|
if (str[0] == '/')
|
||||||
|
xmlXPathRoot(ctxt);
|
||||||
|
xmlXPathEvalExpr(ctxt);
|
||||||
|
|
||||||
|
if ((ctxt->value == NULL) ||
|
||||||
|
((ctxt->value->type != XPATH_NODESET) &&
|
||||||
|
(ctxt->value->type != XPATH_LOCATIONSET))) {
|
||||||
|
fprintf(xmlXPathDebug,
|
||||||
|
"xmlXPathEval: evaluation failed to return a node set\n");
|
||||||
|
} else {
|
||||||
|
res = valuePop(ctxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
tmp = valuePop(ctxt);
|
||||||
|
if (tmp != NULL) {
|
||||||
|
xmlXPathFreeObject(tmp);
|
||||||
|
stack++;
|
||||||
|
}
|
||||||
|
} while (tmp != NULL);
|
||||||
|
if (stack != 0) {
|
||||||
|
fprintf(xmlXPathDebug, "xmlXPathEval: %d object left on the stack\n",
|
||||||
|
stack);
|
||||||
|
}
|
||||||
|
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
||||||
|
xmlXPathFreeObject(res);
|
||||||
|
res = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlXPathFreeParserContext(ctxt);
|
||||||
|
return(res);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlXPathEvalExpression:
|
* xmlXPathEvalExpression:
|
||||||
* @str: the XPath expression
|
* @str: the XPath expression
|
||||||
|
16
xpath.h
16
xpath.h
@ -51,7 +51,10 @@ typedef enum {
|
|||||||
XPATH_BOOLEAN = 2,
|
XPATH_BOOLEAN = 2,
|
||||||
XPATH_NUMBER = 3,
|
XPATH_NUMBER = 3,
|
||||||
XPATH_STRING = 4,
|
XPATH_STRING = 4,
|
||||||
XPATH_USERS = 5
|
XPATH_POINT = 5,
|
||||||
|
XPATH_RANGE = 6,
|
||||||
|
XPATH_LOCATIONSET = 7,
|
||||||
|
XPATH_USERS = 8
|
||||||
} xmlXPathObjectType;
|
} xmlXPathObjectType;
|
||||||
|
|
||||||
typedef struct _xmlXPathObject xmlXPathObject;
|
typedef struct _xmlXPathObject xmlXPathObject;
|
||||||
@ -63,6 +66,9 @@ struct _xmlXPathObject {
|
|||||||
double floatval;
|
double floatval;
|
||||||
xmlChar *stringval;
|
xmlChar *stringval;
|
||||||
void *user;
|
void *user;
|
||||||
|
int index;
|
||||||
|
void *user2;
|
||||||
|
int index2;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -168,6 +174,11 @@ struct _xmlXPathContext {
|
|||||||
/* extra variables */
|
/* extra variables */
|
||||||
int contextSize; /* the context size */
|
int contextSize; /* the context size */
|
||||||
int proximityPosition; /* the proximity position */
|
int proximityPosition; /* the proximity position */
|
||||||
|
|
||||||
|
/* extra stuff for XPointer */
|
||||||
|
int xptr; /* it this an XPointer context */
|
||||||
|
xmlNodePtr here; /* for here() */
|
||||||
|
xmlNodePtr origin; /* for origin() */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -220,10 +231,13 @@ typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
|
|||||||
/**
|
/**
|
||||||
* Evaluation functions.
|
* Evaluation functions.
|
||||||
*/
|
*/
|
||||||
|
void xmlXPathInit (void);
|
||||||
xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc);
|
xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc);
|
||||||
void xmlXPathFreeContext (xmlXPathContextPtr ctxt);
|
void xmlXPathFreeContext (xmlXPathContextPtr ctxt);
|
||||||
xmlXPathObjectPtr xmlXPathEval (const xmlChar *str,
|
xmlXPathObjectPtr xmlXPathEval (const xmlChar *str,
|
||||||
xmlXPathContextPtr ctxt);
|
xmlXPathContextPtr ctxt);
|
||||||
|
xmlXPathObjectPtr xmlXPathEvalXPtrExpr (const xmlChar *str,
|
||||||
|
xmlXPathContextPtr ctxt);
|
||||||
void xmlXPathFreeObject (xmlXPathObjectPtr obj);
|
void xmlXPathFreeObject (xmlXPathObjectPtr obj);
|
||||||
xmlXPathObjectPtr xmlXPathEvalExpression (const xmlChar *str,
|
xmlXPathObjectPtr xmlXPathEvalExpression (const xmlChar *str,
|
||||||
xmlXPathContextPtr ctxt);
|
xmlXPathContextPtr ctxt);
|
||||||
|
Reference in New Issue
Block a user