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 $(srcdir)/reader4.res
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
19static 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
53int 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
118int main(void) {
119    fprintf(stderr, "xmlReader support not compiled in\n");
120    exit(1);
121}
122#endif
123