/** * section: Parsing * synopsis: Parse an XML document chunk by chunk to a tree and free it * purpose: Demonstrate the use of xmlCreatePushParserCtxt() and * xmlParseChunk() to read an XML file progressively * into a tree and and xmlFreeDoc() to free the resulting tree * usage: parse4 test3.xml * test: parse4 test3.xml * author: Daniel Veillard * copy: see Copyright for the status of this software. */#include <stdio.h>#include <libxml/parser.h>#include <libxml/tree.h>#ifdef LIBXML_PUSH_ENABLEDstatic FILE *desc;/** * readPacket: * @mem: array to store the packet * @size: the packet size * * read at most @size bytes from the document and store it in @mem * * Returns the number of bytes read */static intreadPacket(char *mem, int size) { int res; res = fread(mem, 1, size, desc); return(res);}/** * example4Func: * @filename: a filename or an URL * * Parse the resource and free the resulting tree */static voidexample4Func(const char *filename) { xmlParserCtxtPtr ctxt; char chars[4]; xmlDocPtr doc; /* the resulting document tree */ int res; /* * Read a few first byte to check the input used for the * encoding detection at the parser level. */ res = readPacket(chars, 4); if (res <= 0) { fprintf(stderr, "Failed to parse %s\n", filename); return; } /* * Create a progressive parsing context, the 2 first arguments * are not used since we want to build a tree and not use a SAX * parsing interface. We also pass the first bytes of the document * to allow encoding detection when creating the parser but this * is optional. */ ctxt = xmlCreatePushParserCtxt(NULL, NULL, chars, res, filename); if (ctxt == NULL) { fprintf(stderr, "Failed to create parser context !\n"); return; } /* * loop on the input getting the document data, of course 4 bytes * at a time is not realistic but allows to verify testing on small * documents. */ while ((res = readPacket(chars, 4)) > 0) { xmlParseChunk(ctxt, chars, res, 0); } /* * there is no more input, indicate the parsing is finished. */ xmlParseChunk(ctxt, chars, 0, 1); /* * collect the document back and if it was wellformed * and destroy the parser context. */ doc = ctxt->myDoc; res = ctxt->wellFormed; xmlFreeParserCtxt(ctxt); if (!res) { fprintf(stderr, "Failed to parse %s\n", filename); } /* * since we don't use the document, destroy it now. */ xmlFreeDoc(doc);}int main(int argc, char **argv) { if (argc != 2) return(1); /* * this initialize the library and check potential ABI mismatches * between the version it was compiled for and the actual shared * library used. */ LIBXML_TEST_VERSION /* * simulate a progressive parsing using the input file. */ desc = fopen(argv[1], "rb"); if (desc != NULL) { example4Func(argv[1]); fclose(desc); } else { fprintf(stderr, "Failed to parse %s\n", argv[1]); } /* * Cleanup function for the XML library. */ xmlCleanupParser(); /* * this is to debug memory for regression tests */ xmlMemoryDump(); return(0);}#else /* ! LIBXML_PUSH_ENABLED */int main(int argc, char **argv) { fprintf(stderr, "Library not compiled with push parser support\n"); return(1);}#endif
/**
* section: Parsing
* synopsis: Parse an XML document chunk by chunk to a tree and free it
* purpose: Demonstrate the use of xmlCreatePushParserCtxt() and
* xmlParseChunk() to read an XML file progressively
* into a tree and and xmlFreeDoc() to free the resulting tree
* usage: parse4 test3.xml
* test: parse4 test3.xml
* author: Daniel Veillard
* copy: see Copyright for the status of this software.
*/
#include <stdio.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#ifdef LIBXML_PUSH_ENABLED
static FILE *desc;
/**
* readPacket:
* @mem: array to store the packet
* @size: the packet size
*
* read at most @size bytes from the document and store it in @mem
*
* Returns the number of bytes read
*/
static int
readPacket(char *mem, int size) {
int res;
res = fread(mem, 1, size, desc);
return(res);
}
/**
* example4Func:
* @filename: a filename or an URL
*
* Parse the resource and free the resulting tree
*/
static void
example4Func(const char *filename) {
xmlParserCtxtPtr ctxt;
char chars[4];
xmlDocPtr doc; /* the resulting document tree */
int res;
/*
* Read a few first byte to check the input used for the
* encoding detection at the parser level.
*/
res = readPacket(chars, 4);
if (res <= 0) {
fprintf(stderr, "Failed to parse %s\n", filename);
return;
}
/*
* Create a progressive parsing context, the 2 first arguments
* are not used since we want to build a tree and not use a SAX
* parsing interface. We also pass the first bytes of the document
* to allow encoding detection when creating the parser but this
* is optional.
*/
ctxt = xmlCreatePushParserCtxt(NULL, NULL,
chars, res, filename);
if (ctxt == NULL) {
fprintf(stderr, "Failed to create parser context !\n");
return;
}
/*
* loop on the input getting the document data, of course 4 bytes
* at a time is not realistic but allows to verify testing on small
* documents.
*/
while ((res = readPacket(chars, 4)) > 0) {
xmlParseChunk(ctxt, chars, res, 0);
}
/*
* there is no more input, indicate the parsing is finished.
*/
xmlParseChunk(ctxt, chars, 0, 1);
/*
* collect the document back and if it was wellformed
* and destroy the parser context.
*/
doc = ctxt->myDoc;
res = ctxt->wellFormed;
xmlFreeParserCtxt(ctxt);
if (!res) {
fprintf(stderr, "Failed to parse %s\n", filename);
}
/*
* since we don't use the document, destroy it now.
*/
xmlFreeDoc(doc);
}
int main(int argc, char **argv) {
if (argc != 2)
return(1);
/*
* this initialize the library and check potential ABI mismatches
* between the version it was compiled for and the actual shared
* library used.
*/
LIBXML_TEST_VERSION
/*
* simulate a progressive parsing using the input file.
*/
desc = fopen(argv[1], "rb");
if (desc != NULL) {
example4Func(argv[1]);
fclose(desc);
} else {
fprintf(stderr, "Failed to parse %s\n", argv[1]);
}
/*
* Cleanup function for the XML library.
*/
xmlCleanupParser();
/*
* this is to debug memory for regression tests
*/
xmlMemoryDump();
return(0);
}
#else /* ! LIBXML_PUSH_ENABLED */
int main(int argc, char **argv) {
fprintf(stderr, "Library not compiled with push parser support\n");
return(1);
}
#endif