1 /**
2  * section: xmlReader
3  * synopsis: Parse multiple XML files reusing an xmlReader
4  * purpose: Demonstrate the use of xmlReaderForFile() and
5  * xmlReaderNewFile to parse XML files while reusing the reader object
6  * and parser context.  (Note that the XMLReader functions require
7  * libxml2 version later than 2.6.)
8  * usage: reader4 <filename> [ filename ... ]
9  * test: reader4 test1.xml test2.xml test3.xml > reader4.tmp ; diff reader4.tmp reader4.res ; rm reader4.tmp
10  * author: Graham Bennett
11  * copy: see Copyright for the status of this software.
12  */
13 
14 #include <stdio.h>
15 #include <libxml/xmlreader.h>
16 
17 #ifdef LIBXML_READER_ENABLED
18 
processDoc(xmlTextReaderPtr readerPtr)19 static void processDoc(xmlTextReaderPtr readerPtr) {
20     int ret;
21     xmlDocPtr docPtr;
22     const xmlChar *URL;
23 
24     ret = xmlTextReaderRead(readerPtr);
25     while (ret == 1) {
26       ret = xmlTextReaderRead(readerPtr);
27     }
28 
29     /*
30      * One can obtain the document pointer to get insteresting
31      * information about the document like the URL, but one must also
32      * be sure to clean it up at the end (see below).
33      */
34     docPtr = xmlTextReaderCurrentDoc(readerPtr);
35     if (NULL == docPtr) {
36       fprintf(stderr, "failed to obtain document\n");
37       return;
38     }
39 
40     URL = docPtr->URL;
41     if (NULL == URL) {
42       fprintf(stderr, "Failed to obtain URL\n");
43     }
44 
45     if (ret != 0) {
46       fprintf(stderr, "%s: Failed to parse\n", URL);
47       return;
48     }
49 
50     printf("%s: Processed ok\n", (const char *)URL);
51 }
52 
main(int argc,char ** argv)53 int main(int argc, char **argv) {
54     xmlTextReaderPtr readerPtr;
55     int i;
56     xmlDocPtr docPtr;
57 
58     if (argc < 2)
59         return(1);
60 
61     /*
62      * this initialises the library and check potential ABI mismatches
63      * between the version it was compiled for and the actual shared
64      * library used.
65      */
66     LIBXML_TEST_VERSION
67 
68     /*
69      * Create a new reader for the first file and process the
70      * document.
71      */
72     readerPtr = xmlReaderForFile(argv[1], NULL, 0);
73     if (NULL == readerPtr) {
74       fprintf(stderr, "%s: failed to create reader\n", argv[1]);
75       return(1);
76     }
77     processDoc(readerPtr);
78 
79     /*
80      * The reader can be reused for subsequent files.
81      */
82     for (i=2; i < argc; ++i) {
83       	xmlReaderNewFile(readerPtr, argv[i], NULL, 0);
84 	if (NULL == readerPtr) {
85 	  fprintf(stderr, "%s: failed to create reader\n", argv[i]);
86 	  return(1);
87 	}
88         processDoc(readerPtr);
89     }
90 
91     /*
92      * Since we've called xmlTextReaderCurrentDoc, we now have to
93      * clean up after ourselves.  We only have to do this the last
94      * time, because xmlReaderNewFile calls xmlCtxtReset which takes
95      * care of it.
96      */
97     docPtr = xmlTextReaderCurrentDoc(readerPtr);
98     if (docPtr != NULL)
99       xmlFreeDoc(docPtr);
100 
101     /*
102      * Clean up the reader.
103      */
104     xmlFreeTextReader(readerPtr);
105 
106     /*
107      * Cleanup function for the XML library.
108      */
109     xmlCleanupParser();
110     /*
111      * this is to debug memory for regression tests
112      */
113     xmlMemoryDump();
114     return(0);
115 }
116 
117 #else
main(void)118 int main(void) {
119     fprintf(stderr, "xmlReader support not compiled in\n");
120     exit(1);
121 }
122 #endif
123