Annotation of XML/testXPath.c, revision 1.20
1.1 daniel 1: /*
2: * testXPath.c : a small tester program for XPath.
3: *
4: * See Copyright for the status of this software.
5: *
6: * Daniel.Veillard@w3.org
7: */
8:
9: #ifdef WIN32
1.16 daniel 10: #include "win32config.h"
1.1 daniel 11: #else
1.12 daniel 12: #include "config.h"
1.1 daniel 13: #endif
1.11 daniel 14:
1.17 daniel 15: #include "xmlversion.h"
16: #if defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_DEBUG_ENABLED)
17:
1.11 daniel 18: #include <stdio.h>
19: #include <string.h>
20:
21: #ifdef HAVE_SYS_TYPES_H
1.1 daniel 22: #include <sys/types.h>
1.11 daniel 23: #endif
1.1 daniel 24: #ifdef HAVE_SYS_STAT_H
25: #include <sys/stat.h>
26: #endif
27: #ifdef HAVE_FCNTL_H
28: #include <fcntl.h>
29: #endif
30: #ifdef HAVE_UNISTD_H
31: #include <unistd.h>
32: #endif
1.11 daniel 33: #ifdef HAVE_STDLIB_H
1.1 daniel 34: #include <stdlib.h>
1.11 daniel 35: #endif
36:
1.1 daniel 37:
1.17 daniel 38: #include <libxml/xpath.h>
39: #include <libxml/tree.h>
40: #include <libxml/parser.h>
41: #include <libxml/debugXML.h>
42: #include <libxml/xmlmemory.h>
1.18 veillard 43: #include <libxml/parserInternals.h>
1.19 veillard 44: #if defined(LIBXML_XPTR_ENABLED)
45: #include <libxml/xpointer.h>
46: static int xptr = 0;
47: #endif
1.1 daniel 48: static int debug = 0;
1.18 veillard 49: static int valid = 0;
1.5 daniel 50: static int expr = 0;
1.2 daniel 51: static xmlDocPtr document = NULL;
52:
53: /*
54: * Default document
55: */
1.13 daniel 56: static xmlChar buffer[] =
1.2 daniel 57: "<?xml version=\"1.0\"?>\n\
58: <EXAMPLE prop1=\"gnome is great\" prop2=\"& linux too\">\n\
59: <head>\n\
60: <title>Welcome to Gnome</title>\n\
61: </head>\n\
62: <chapter>\n\
63: <title>The Linux adventure</title>\n\
64: <p>bla bla bla ...</p>\n\
65: <image href=\"linus.gif\"/>\n\
66: <p>...</p>\n\
67: </chapter>\n\
1.5 daniel 68: <chapter>\n\
69: <title>Chapter 2</title>\n\
70: <p>this is chapter 2 ...</p>\n\
71: </chapter>\n\
72: <chapter>\n\
73: <title>Chapter 3</title>\n\
74: <p>this is chapter 3 ...</p>\n\
75: </chapter>\n\
76: <chapter>\n\
77: <title>Chapter 4</title>\n\
78: <p>this is chapter 4 ...</p>\n\
79: </chapter>\n\
80: <chapter>\n\
81: <title>Chapter 5</title>\n\
82: <p>this is chapter 5 ...</p>\n\
83: </chapter>\n\
1.2 daniel 84: </EXAMPLE>\n\
85: ";
1.1 daniel 86:
1.20 ! veillard 87: void xmlXPAthDebugDumpNode(FILE *output, xmlNodePtr cur) {
! 88: if (cur == NULL) {
! 89: fprintf(output, "Node is NULL !\n");
! 90: return;
! 91:
! 92: }
! 93:
! 94: if (cur == NULL)
! 95: fprintf(output, " NULL\n");
! 96: else if ((cur->type == XML_DOCUMENT_NODE) ||
! 97: (cur->type == XML_HTML_DOCUMENT_NODE))
! 98: fprintf(output, " /\n");
! 99: else if (cur->type == XML_ATTRIBUTE_NODE)
! 100: xmlDebugDumpAttr(output, (xmlAttrPtr)cur, 2);
! 101: else
! 102: xmlDebugDumpOneNode(output, cur, 2);
! 103: }
! 104:
1.1 daniel 105: void xmlXPAthDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur) {
1.2 daniel 106: int i;
107:
1.4 daniel 108: if (cur == NULL) {
109: fprintf(output, "NodeSet is NULL !\n");
110: return;
111:
112: }
1.2 daniel 113:
114: fprintf(output, "Set contains %d nodes:\n", cur->nodeNr);
115: for (i = 0;i < cur->nodeNr;i++) {
116: fprintf(output, "%d", i + 1);
1.20 ! veillard 117: xmlXPAthDebugDumpNode(output, cur->nodeTab[i]);
! 118: }
! 119: }
! 120:
! 121: void xmlXPAthDebugDumpObject(FILE *output, xmlXPathObjectPtr cur);
! 122: void xmlXPAthDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur) {
! 123: int i;
! 124:
! 125: if (cur == NULL) {
! 126: fprintf(output, "LocationSet is NULL !\n");
! 127: return;
! 128:
! 129: }
! 130:
! 131: fprintf(output, "Set contains %d ranges:\n", cur->locNr);
! 132: for (i = 0;i < cur->locNr;i++) {
! 133: fprintf(output, "%d", i + 1);
! 134: xmlXPAthDebugDumpObject(output, cur->locTab[i]);
1.2 daniel 135: }
1.1 daniel 136: }
137:
138: void xmlXPAthDebugDumpObject(FILE *output, xmlXPathObjectPtr cur) {
139: if (cur == NULL) {
140: fprintf(output, "Object is empty (NULL)\n");
141: return;
142: }
143: switch(cur->type) {
144: case XPATH_UNDEFINED:
145: fprintf(output, "Object is uninitialized\n");
146: break;
147: case XPATH_NODESET:
148: fprintf(output, "Object is a Node Set :\n");
149: xmlXPAthDebugDumpNodeSet(output, cur->nodesetval);
150: break;
151: case XPATH_BOOLEAN:
152: fprintf(output, "Object is a Boolean : ");
153: if (cur->boolval) fprintf(output, "true\n");
154: else fprintf(output, "false\n");
155: break;
156: case XPATH_NUMBER:
1.5 daniel 157: fprintf(output, "Object is a number : %0g\n", cur->floatval);
1.1 daniel 158: break;
159: case XPATH_STRING:
160: fprintf(output, "Object is a string : ");
161: xmlDebugDumpString(output, cur->stringval);
1.5 daniel 162: fprintf(output, "\n");
1.1 daniel 163: break;
1.20 ! veillard 164: case XPATH_POINT:
! 165: fprintf(output, "Object is a point : index %d in node", cur->index);
! 166: xmlXPAthDebugDumpNode(output, (xmlNodePtr) cur->user);
! 167: fprintf(output, "\n");
! 168: break;
! 169: case XPATH_RANGE:
! 170: fprintf(output, "Object is a range : from");
! 171: if (cur->index >= 0)
! 172: fprintf(output, "index %d in ", cur->index);
! 173: fprintf(output, "node");
! 174: xmlXPAthDebugDumpNode(output, (xmlNodePtr) cur->user);
! 175: fprintf(output, " to ");
! 176: if (cur->index2 >= 0)
! 177: fprintf(output, "index %d in ", cur->index2);
! 178: fprintf(output, "node");
! 179: xmlXPAthDebugDumpNode(output, (xmlNodePtr) cur->user2);
! 180: fprintf(output, "\n");
! 181: case XPATH_LOCATIONSET:
! 182: fprintf(output, "Object is a location set containing :");
! 183: xmlXPAthDebugDumpLocationSet(output, (xmlLocationSetPtr) cur->user);
! 184: case XPATH_USERS:
! 185: fprintf(output, "Object is user defined\n");
1.1 daniel 186: }
187: }
188:
189: void testXPath(const char *str) {
190: xmlXPathObjectPtr res;
191: xmlXPathContextPtr ctxt;
192:
1.19 veillard 193: #if defined(LIBXML_XPTR_ENABLED)
194: if (xptr) {
195: ctxt = xmlXPtrNewContext(document, NULL, NULL);
196: res = xmlXPtrEval(BAD_CAST str, ctxt);
197: } else {
198: #endif
199: ctxt = xmlXPathNewContext(document);
200: if (expr)
201: res = xmlXPathEvalExpression(BAD_CAST str, ctxt);
202: else
203: res = xmlXPathEval(BAD_CAST str, ctxt);
204: #if defined(LIBXML_XPTR_ENABLED)
205: }
206: #endif
1.1 daniel 207: xmlXPAthDebugDumpObject(stdout, res);
208: xmlXPathFreeObject(res);
1.6 veillard 209: xmlXPathFreeContext(ctxt);
1.1 daniel 210: }
211:
1.5 daniel 212: void testXPathFile(const char *filename) {
213: FILE *input;
214: char expr[5000];
215:
216: input = fopen(filename, "r");
217: if (input == NULL) {
218: fprintf(stderr, "Cannot open %s for reading\n", filename);
219: return;
220: }
221: while (fscanf(input, "%s", expr) != EOF) {
1.19 veillard 222: printf("\n========================\nExpression: %s\n", expr) ;
1.5 daniel 223: testXPath(expr);
224: }
225:
226: fclose(input);
227: }
228:
1.1 daniel 229: int main(int argc, char **argv) {
230: int i;
231: int strings = 0;
1.5 daniel 232: int usefile = 0;
233: char *filename = NULL;
1.1 daniel 234:
235: for (i = 1; i < argc ; i++) {
1.19 veillard 236: #if defined(LIBXML_XPTR_ENABLED)
237: if ((!strcmp(argv[i], "-xptr")) || (!strcmp(argv[i], "--xptr")))
238: xptr++;
239: #endif
1.1 daniel 240: if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
241: debug++;
1.18 veillard 242: if ((!strcmp(argv[i], "-valid")) || (!strcmp(argv[i], "--valid")))
243: valid++;
1.5 daniel 244: if ((!strcmp(argv[i], "-expr")) || (!strcmp(argv[i], "--expr")))
245: expr++;
246: if ((!strcmp(argv[i], "-i")) || (!strcmp(argv[i], "--input")))
247: filename = argv[++i];
248: if ((!strcmp(argv[i], "-f")) || (!strcmp(argv[i], "--file")))
249: usefile++;
250: }
1.18 veillard 251: if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
1.5 daniel 252: if (document == NULL) {
253: if (filename == NULL)
254: document = xmlParseDoc(buffer);
255: else
256: document = xmlParseFile(filename);
1.1 daniel 257: }
258: for (i = 1; i < argc ; i++) {
1.5 daniel 259: if ((!strcmp(argv[i], "-i")) || (!strcmp(argv[i], "--input"))) {
260: i++; continue;
261: }
1.1 daniel 262: if (argv[i][0] != '-') {
1.5 daniel 263: if (usefile)
264: testXPathFile(argv[i]);
265: else
266: testXPath(argv[i]);
1.1 daniel 267: strings ++;
268: }
269: }
270: if (strings == 0) {
1.5 daniel 271: printf("Usage : %s [--debug] [--copy] stringsorfiles ...\n",
1.1 daniel 272: argv[0]);
273: printf("\tParse the XPath strings and output the result of the parsing\n");
274: printf("\t--debug : dump a debug version of the result\n");
1.18 veillard 275: printf("\t--valid : switch on DTD support in the parser\n");
1.5 daniel 276: printf("\t--expr : debug XPath expressions only\n");
277: printf("\t--input filename : or\n");
278: printf("\t-i filename : read the document from filename\n");
279: printf("\t--file : or\n");
280: printf("\t-f : read queries from files, args\n");
1.1 daniel 281: }
1.15 daniel 282: if (document != NULL)
283: xmlFreeDoc(document);
284: xmlCleanupParser();
285: xmlMemoryDump();
1.1 daniel 286:
287: return(0);
288: }
1.17 daniel 289: #else
290: #include <stdio.h>
291: int main(int argc, char **argv) {
292: printf("%s : XPath/Debug support not compiled in\n", argv[0]);
293: return(0);
294: }
295: #endif /* LIBXML_XPATH_ENABLED */
Webmaster