1241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard/**
2241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * section: 	XPath
3241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * synopsis: 	Evaluate XPath expression and prints result node set.
4241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * purpose: 	Shows how to evaluate XPath expression and register
5241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard *          	known namespaces in XPath context.
6241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * usage:	xpath1 <xml-file> <xpath-expr> [<known-ns-list>]
76842ee810e8ab60fa71d1569bbc91cc392d12a7cDaniel Richard G * test:	xpath1 test3.xml '//child2' > xpath1.tmp && diff xpath1.tmp $(srcdir)/xpath1.res
8241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * author: 	Aleksey Sanin
9241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * copy: 	see Copyright for the status of this software.
10241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard */
11241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard#include <stdlib.h>
12241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard#include <stdio.h>
13241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard#include <string.h>
14241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard#include <assert.h>
15241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
16241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard#include <libxml/tree.h>
17241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard#include <libxml/parser.h>
18241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard#include <libxml/xpath.h>
19241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard#include <libxml/xpathInternals.h>
20241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
2121e4ef20f64ebd740ebac0ead5d85a5631d2db5eWilliam M. Brack#if defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_SAX1_ENABLED)
222156d4387bf23c9b927341da58bd394bb4946017Daniel Veillard
232156d4387bf23c9b927341da58bd394bb4946017Daniel Veillard
24ff4c1852e9066cf1014784560b04fca18f8fb624Daniel Veillardstatic void usage(const char *name);
25241e19d4afea87d71e761803877ba9371d70d816Daniel Veillardint  execute_xpath_expression(const char* filename, const xmlChar* xpathExpr, const xmlChar* nsList);
26241e19d4afea87d71e761803877ba9371d70d816Daniel Veillardint  register_namespaces(xmlXPathContextPtr xpathCtx, const xmlChar* nsList);
27241e19d4afea87d71e761803877ba9371d70d816Daniel Veillardvoid print_xpath_nodes(xmlNodeSetPtr nodes, FILE* output);
28241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
29241e19d4afea87d71e761803877ba9371d70d816Daniel Veillardint
30241e19d4afea87d71e761803877ba9371d70d816Daniel Veillardmain(int argc, char **argv) {
31241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    /* Parse command line and process file */
32241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    if((argc < 3) || (argc > 4)) {
33241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	fprintf(stderr, "Error: wrong number of arguments.\n");
34241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	usage(argv[0]);
35241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	return(-1);
36241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    }
37241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
38241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    /* Init libxml */
39241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    xmlInitParser();
40241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    LIBXML_TEST_VERSION
41241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
42241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    /* Do the main job */
43241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    if(execute_xpath_expression(argv[1], BAD_CAST argv[2], (argc > 3) ? BAD_CAST argv[3] : NULL) < 0) {
44241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	usage(argv[0]);
45241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	return(-1);
46241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    }
47241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
48241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    /* Shutdown libxml */
49241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    xmlCleanupParser();
50241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
514773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    /*
524773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard     * this is to debug memory for regression tests
534773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard     */
544773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    xmlMemoryDump();
55241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    return 0;
56241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard}
57241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
58241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard/**
59241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * usage:
60241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * @name:		the program name.
61241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard *
62241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * Prints usage information.
63241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard */
64ff4c1852e9066cf1014784560b04fca18f8fb624Daniel Veillardstatic void
65241e19d4afea87d71e761803877ba9371d70d816Daniel Veillardusage(const char *name) {
66241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    assert(name);
67241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
68241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    fprintf(stderr, "Usage: %s <xml-file> <xpath-expr> [<known-ns-list>]\n", name);
69241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    fprintf(stderr, "where <known-ns-list> is a list of known namespaces\n");
70241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    fprintf(stderr, "in \"<prefix1>=<href1> <prefix2>=href2> ...\" format\n");
71241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard}
72241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
73241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard/**
74241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * execute_xpath_expression:
75241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * @filename:		the input XML filename.
76241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * @xpathExpr:		the xpath expression for evaluation.
77241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * @nsList:		the optional list of known namespaces in
78241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard *			"<prefix1>=<href1> <prefix2>=href2> ..." format.
79241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard *
80241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * Parses input XML file, evaluates XPath expression and prints results.
81241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard *
82241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * Returns 0 on success and a negative value otherwise.
83241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard */
84241e19d4afea87d71e761803877ba9371d70d816Daniel Veillardint
85241e19d4afea87d71e761803877ba9371d70d816Daniel Veillardexecute_xpath_expression(const char* filename, const xmlChar* xpathExpr, const xmlChar* nsList) {
86241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    xmlDocPtr doc;
87241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    xmlXPathContextPtr xpathCtx;
88241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    xmlXPathObjectPtr xpathObj;
89241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
90241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    assert(filename);
91241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    assert(xpathExpr);
92241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
93241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    /* Load XML document */
94241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    doc = xmlParseFile(filename);
95241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    if (doc == NULL) {
96241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	fprintf(stderr, "Error: unable to parse file \"%s\"\n", filename);
97241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	return(-1);
98241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    }
99241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
100241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    /* Create xpath evaluation context */
101241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    xpathCtx = xmlXPathNewContext(doc);
102241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    if(xpathCtx == NULL) {
103241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard        fprintf(stderr,"Error: unable to create new XPath context\n");
104241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard        xmlFreeDoc(doc);
105241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard        return(-1);
106241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    }
107241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
108241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    /* Register namespaces from list (if any) */
109241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    if((nsList != NULL) && (register_namespaces(xpathCtx, nsList) < 0)) {
110241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard        fprintf(stderr,"Error: failed to register namespaces list \"%s\"\n", nsList);
111241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard        xmlXPathFreeContext(xpathCtx);
112241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard        xmlFreeDoc(doc);
113241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard        return(-1);
114241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    }
115241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
116241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    /* Evaluate xpath expression */
117241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
118241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    if(xpathObj == NULL) {
119241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard        fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", xpathExpr);
120241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard        xmlXPathFreeContext(xpathCtx);
121241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard        xmlFreeDoc(doc);
122241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard        return(-1);
123241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    }
124241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
125241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    /* Print results */
126241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    print_xpath_nodes(xpathObj->nodesetval, stdout);
127241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
128241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    /* Cleanup */
129241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    xmlXPathFreeObject(xpathObj);
130241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    xmlXPathFreeContext(xpathCtx);
131241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    xmlFreeDoc(doc);
132241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
133241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    return(0);
134241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard}
135241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
136241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard/**
137241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * register_namespaces:
138241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * @xpathCtx:		the pointer to an XPath context.
139241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * @nsList:		the list of known namespaces in
140241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard *			"<prefix1>=<href1> <prefix2>=href2> ..." format.
141241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard *
142241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * Registers namespaces from @nsList in @xpathCtx.
143241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard *
144241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * Returns 0 on success and a negative value otherwise.
145241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard */
146241e19d4afea87d71e761803877ba9371d70d816Daniel Veillardint
147241e19d4afea87d71e761803877ba9371d70d816Daniel Veillardregister_namespaces(xmlXPathContextPtr xpathCtx, const xmlChar* nsList) {
148241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    xmlChar* nsListDup;
149241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    xmlChar* prefix;
150241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    xmlChar* href;
151241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    xmlChar* next;
152241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
153241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    assert(xpathCtx);
154241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    assert(nsList);
155241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
156241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    nsListDup = xmlStrdup(nsList);
157241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    if(nsListDup == NULL) {
158241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	fprintf(stderr, "Error: unable to strdup namespaces list\n");
159241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	return(-1);
160241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    }
161241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
162241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    next = nsListDup;
163241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    while(next != NULL) {
164241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	/* skip spaces */
165241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	while((*next) == ' ') next++;
166241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	if((*next) == '\0') break;
167241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
168241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	/* find prefix */
169241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	prefix = next;
170241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	next = (xmlChar*)xmlStrchr(next, '=');
171241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	if(next == NULL) {
172241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    fprintf(stderr,"Error: invalid namespaces list format\n");
17387247e87408561aee625b2e800ea3c13211af897Daniel Veillard	    xmlFree(nsListDup);
174241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    return(-1);
175241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	}
176241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	*(next++) = '\0';
177241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
178241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	/* find href */
179241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	href = next;
180241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	next = (xmlChar*)xmlStrchr(next, ' ');
181241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	if(next != NULL) {
182241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    *(next++) = '\0';
183241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	}
184241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
185241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	/* do register namespace */
186241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	if(xmlXPathRegisterNs(xpathCtx, prefix, href) != 0) {
187241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    fprintf(stderr,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", prefix, href);
18887247e87408561aee625b2e800ea3c13211af897Daniel Veillard	    xmlFree(nsListDup);
189241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    return(-1);
190241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	}
191241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    }
192241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
19387247e87408561aee625b2e800ea3c13211af897Daniel Veillard    xmlFree(nsListDup);
194241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    return(0);
195241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard}
196241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
197241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard/**
198241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * print_xpath_nodes:
199241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * @nodes:		the nodes set.
200241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * @output:		the output file handle.
201241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard *
202241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard * Prints the @nodes content to @output.
203241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard */
204241e19d4afea87d71e761803877ba9371d70d816Daniel Veillardvoid
205241e19d4afea87d71e761803877ba9371d70d816Daniel Veillardprint_xpath_nodes(xmlNodeSetPtr nodes, FILE* output) {
206241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    xmlNodePtr cur;
207241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    int size;
208241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    int i;
209241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
210241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    assert(output);
211241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    size = (nodes) ? nodes->nodeNr : 0;
212241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
213241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    fprintf(output, "Result (%d nodes):\n", size);
214241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    for(i = 0; i < size; ++i) {
215241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	assert(nodes->nodeTab[i]);
216241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
217241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	if(nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) {
218241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    xmlNsPtr ns;
219241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
220241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    ns = (xmlNsPtr)nodes->nodeTab[i];
221241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    cur = (xmlNodePtr)ns->next;
222241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    if(cur->ns) {
223241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	        fprintf(output, "= namespace \"%s\"=\"%s\" for node %s:%s\n",
224241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard		    ns->prefix, ns->href, cur->ns->href, cur->name);
225241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    } else {
226241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	        fprintf(output, "= namespace \"%s\"=\"%s\" for node %s\n",
227241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard		    ns->prefix, ns->href, cur->name);
228241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    }
229241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	} else if(nodes->nodeTab[i]->type == XML_ELEMENT_NODE) {
230241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    cur = nodes->nodeTab[i];
231241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    if(cur->ns) {
232241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    	        fprintf(output, "= element node \"%s:%s\"\n",
233241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard		    cur->ns->href, cur->name);
234241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    } else {
235241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    	        fprintf(output, "= element node \"%s\"\n",
236241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard		    cur->name);
237241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    }
238241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	} else {
239241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    cur = nodes->nodeTab[i];
240241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	    fprintf(output, "= node \"%s\": type %d\n", cur->name, cur->type);
241241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard	}
242241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard    }
243241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard}
244241e19d4afea87d71e761803877ba9371d70d816Daniel Veillard
2452156d4387bf23c9b927341da58bd394bb4946017Daniel Veillard#else
2462156d4387bf23c9b927341da58bd394bb4946017Daniel Veillardint main(void) {
2472156d4387bf23c9b927341da58bd394bb4946017Daniel Veillard    fprintf(stderr, "XPath support not compiled in\n");
2482156d4387bf23c9b927341da58bd394bb4946017Daniel Veillard    exit(1);
2492156d4387bf23c9b927341da58bd394bb4946017Daniel Veillard}
2502156d4387bf23c9b927341da58bd394bb4946017Daniel Veillard#endif
251