parse4.c revision 87640d5f14e7ce8b9844b886c765af0c56de5ca5
1/**
2 * section: Parsing
3 * synopsis: Parse an XML document chunk by chunk to a tree and free it
4 * purpose: Demonstrate the use of xmlCreatePushParserCtxt() and
5 *          xmlParseChunk() to read an XML file progressively
6 *          into a tree and and xmlFreeDoc() to free the resulting tree
7 * usage: parse4 test3.xml
8 * test: parse4 test3.xml
9 * author: Daniel Veillard
10 * copy: see Copyright for the status of this software.
11 */
12
13#include <stdio.h>
14#include <libxml/parser.h>
15#include <libxml/tree.h>
16
17static FILE *desc;
18
19/**
20 * readPacket:
21 * @mem: array to store the packet
22 * @size: the packet size
23 *
24 * read at most @size bytes from the document and store it in @mem
25 *
26 * Returns the number of bytes read
27 */
28static int
29readPacket(char *mem, int size) {
30    int res;
31
32    res = fread(mem, 1, size, desc);
33    return(res);
34}
35
36/**
37 * example4Func:
38 * @filename: a filename or an URL
39 *
40 * Parse the resource and free the resulting tree
41 */
42static void
43example4Func(const char *filename) {
44    xmlParserCtxtPtr ctxt;
45    char chars[4];
46    xmlDocPtr doc; /* the resulting document tree */
47    int res;
48
49    /*
50     * Read a few first byte to check the input used for the
51     * encoding detection at the parser level.
52     */
53    res = readPacket(chars, 4);
54    if (res <= 0) {
55        fprintf(stderr, "Failed to parse %s\n", filename);
56	return;
57    }
58
59    /*
60     * Create a progressive parsing context, the 2 first arguments
61     * are not used since we want to build a tree and not use a SAX
62     * parsing interface. We also pass the first bytes of the document
63     * to allow encoding detection when creating the parser but this
64     * is optional.
65     */
66    ctxt = xmlCreatePushParserCtxt(NULL, NULL,
67                                   chars, res, filename);
68    if (ctxt == NULL) {
69        fprintf(stderr, "Failed to create parser context !\n");
70	return;
71    }
72
73    /*
74     * loop on the input getting the document data, of course 4 bytes
75     * at a time is not realistic but allows to verify testing on small
76     * documents.
77     */
78    while ((res = readPacket(chars, 4)) > 0) {
79        xmlParseChunk(ctxt, chars, res, 0);
80    }
81
82    /*
83     * there is no more input, indicate the parsing is finished.
84     */
85    xmlParseChunk(ctxt, chars, 0, 1);
86
87    /*
88     * collect the document back and if it was wellformed
89     * and destroy the parser context.
90     */
91    doc = ctxt->myDoc;
92    res = ctxt->wellFormed;
93    xmlFreeParserCtxt(ctxt);
94
95    if (!res) {
96        fprintf(stderr, "Failed to parse %s\n", filename);
97    }
98
99    /*
100     * since we don't use the document, destroy it now.
101     */
102    xmlFreeDoc(doc);
103}
104
105int main(int argc, char **argv) {
106    if (argc != 2)
107        return(1);
108
109    /*
110     * this initialize the library and check potential ABI mismatches
111     * between the version it was compiled for and the actual shared
112     * library used.
113     */
114    LIBXML_TEST_VERSION
115
116    /*
117     * simulate a progressive parsing using the input file.
118     */
119    desc = fopen(argv[1], "rb");
120    if (desc != NULL) {
121	example4Func(argv[1]);
122	fclose(desc);
123    } else {
124        fprintf(stderr, "Failed to parse %s\n", argv[1]);
125    }
126
127    /*
128     * Cleanup function for the XML library.
129     */
130    xmlCleanupParser();
131    /*
132     * this is to debug memory for regression tests
133     */
134    xmlMemoryDump();
135    return(0);
136}
137