mirror of
				https://gitlab.gnome.org/GNOME/libxml2.git
				synced 2025-10-30 10:45:36 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			144 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
		
			3.4 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]);
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Cleanup function for the XML library.
 | |
|      */
 | |
|     xmlCleanupParser();
 | |
|     /*
 | |
|      * this is to debug memory for regression tests
 | |
|      */
 | |
|     xmlMemoryDump();
 | |
|     return(0);
 | |
| }
 | |
| #else /* ! LIBXML_PUSH_ENABLED */
 | |
| int main(void) {
 | |
|     fprintf(stderr, "Library not compiled with push parser support\n");
 | |
|     return(0);
 | |
| }
 | |
| #endif
 |