Home | History | Annotate | Download | only in examples
      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 
     17 #ifdef LIBXML_PUSH_ENABLED
     18 static 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  */
     29 static int
     30 readPacket(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  */
     43 static void
     44 example4Func(const char *filename) {
     45     xmlParserCtxtPtr ctxt;
     46     char chars[4];
     47     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 
    106 int 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 }
    138 #else /* ! LIBXML_PUSH_ENABLED */
    139 int main(int argc, char **argv) {
    140     fprintf(stderr, "Library not compiled with push parser support\n");
    141     return(1);
    142 }
    143 #endif
    144