11e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard/**
21e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard * section: xmlReader
31e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard * synopsis: Show how to extract subdocuments with xmlReader
41e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard * purpose: Demonstrate the use of xmlTextReaderPreservePattern()
51e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard *          to parse an XML file with the xmlReader while collecting
6f2497c16b223b8be56d0496fc0bce84ed2ce3b6eJohn Fleck *          only some subparts of the document.
7f2497c16b223b8be56d0496fc0bce84ed2ce3b6eJohn Fleck *          (Note that the XMLReader functions require libxml2 version later
8f2497c16b223b8be56d0496fc0bce84ed2ce3b6eJohn Fleck *          than 2.6.)
91e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard * usage: reader3
106842ee810e8ab60fa71d1569bbc91cc392d12a7cDaniel Richard G * test: reader3 > reader3.tmp && diff reader3.tmp $(srcdir)/reader3.res
111e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard * author: Daniel Veillard
121e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard * copy: see Copyright for the status of this software.
131e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard */
141e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard
151e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard#include <stdio.h>
161e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard#include <libxml/xmlreader.h>
171e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard
184cc67bb77eda0a4ced8b477477dc62c8c1096db9Daniel Veillard#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
194cc67bb77eda0a4ced8b477477dc62c8c1096db9Daniel Veillard
202156d4387bf23c9b927341da58bd394bb4946017Daniel Veillard
211e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard/**
221e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard * streamFile:
231e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard * @filename: the file name to parse
241e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard *
251e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard * Parse and print information about an XML file.
261e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard *
271e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard * Returns the resulting doc with just the elements preserved.
281e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard */
291e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillardstatic xmlDocPtr
301e90661bb817402f85103c3b9d3ce6ebab570f38Daniel VeillardextractFile(const char *filename, const xmlChar *pattern) {
311e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    xmlDocPtr doc;
321e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    xmlTextReaderPtr reader;
331e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    int ret;
341e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard
351e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    /*
361e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard     * build an xmlReader for that file
371e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard     */
381e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    reader = xmlReaderForFile(filename, NULL, 0);
391e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    if (reader != NULL) {
401e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard        /*
411e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	 * add the pattern to preserve
421e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	 */
43ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard        if (xmlTextReaderPreservePattern(reader, pattern, NULL) < 0) {
441e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard            fprintf(stderr, "%s : failed add preserve pattern %s\n",
451e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	            filename, (const char *) pattern);
461e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	}
471e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	/*
481e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	 * Parse and traverse the tree, collecting the nodes in the process
491e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	 */
501e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard        ret = xmlTextReaderRead(reader);
511e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard        while (ret == 1) {
521e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard            ret = xmlTextReaderRead(reader);
531e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard        }
541e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard        if (ret != 0) {
551e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard            fprintf(stderr, "%s : failed to parse\n", filename);
561e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	    xmlFreeTextReader(reader);
571e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	    return(NULL);
581e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard        }
591e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	/*
601e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	 * get the resulting nodes
611e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	 */
621e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	doc = xmlTextReaderCurrentDoc(reader);
631e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	/*
641e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	 * Free up the reader
651e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	 */
661e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard        xmlFreeTextReader(reader);
671e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    } else {
681e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard        fprintf(stderr, "Unable to open %s\n", filename);
691e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	return(NULL);
701e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    }
711e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    return(doc);
721e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard}
731e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard
741e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillardint main(int argc, char **argv) {
751e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    const char *filename = "test3.xml";
761e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    const char *pattern = "preserved";
771e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    xmlDocPtr doc;
781e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard
791e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    if (argc == 3) {
801e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard        filename = argv[1];
811e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	pattern = argv[2];
821e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    }
831e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard
841e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    /*
851e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard     * this initialize the library and check potential ABI mismatches
861e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard     * between the version it was compiled for and the actual shared
871e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard     * library used.
881e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard     */
891e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    LIBXML_TEST_VERSION
901e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard
911e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    doc = extractFile(filename, (const xmlChar *) pattern);
921e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    if (doc != NULL) {
931e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard        /*
941e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	 * ouptut the result.
951e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	 */
961e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard        xmlDocDump(stdout, doc);
971e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	/*
981e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	 * don't forget to free up the doc
991e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	 */
1001e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard	xmlFreeDoc(doc);
1011e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    }
1021e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard
1031e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard
1041e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    /*
1051e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard     * Cleanup function for the XML library.
1061e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard     */
1071e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    xmlCleanupParser();
1084773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    /*
1094773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard     * this is to debug memory for regression tests
1104773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard     */
1114773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    xmlMemoryDump();
1121e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard    return(0);
1131e90661bb817402f85103c3b9d3ce6ebab570f38Daniel Veillard}
1142156d4387bf23c9b927341da58bd394bb4946017Daniel Veillard
1152156d4387bf23c9b927341da58bd394bb4946017Daniel Veillard#else
1162156d4387bf23c9b927341da58bd394bb4946017Daniel Veillardint main(void) {
1174cc67bb77eda0a4ced8b477477dc62c8c1096db9Daniel Veillard    fprintf(stderr, "Reader, Pattern or output support not compiled in\n");
1182156d4387bf23c9b927341da58bd394bb4946017Daniel Veillard    exit(1);
1192156d4387bf23c9b927341da58bd394bb4946017Daniel Veillard}
1202156d4387bf23c9b927341da58bd394bb4946017Daniel Veillard#endif
121