mirror of
https://gitlab.gnome.org/GNOME/libxml2
synced 2025-03-28 21:33:13 +00:00

xmlCleanupParser is dangerous and shouldn't be called in most cases. Being part of the examples led many people to use it incorrectly. xmlMemoryDump is an obsolete way to test for memory leaks.
136 lines
3.3 KiB
C
136 lines
3.3 KiB
C
/**
|
|
* 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 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]);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
#else /* ! LIBXML_PUSH_ENABLED */
|
|
int main(void) {
|
|
fprintf(stderr, "Library not compiled with push parser support\n");
|
|
return(0);
|
|
}
|
|
#endif
|