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