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