| /** | |
| * section: xmlWriter | |
| * synopsis: use various APIs for the xmlWriter | |
| * purpose: tests a number of APIs for the xmlWriter, especially | |
| * the various methods to write to a filename, to a memory | |
| * buffer, to a new document, or to a subtree. It shows how to | |
| * do encoding string conversions too. The resulting | |
| * documents are then serialized. | |
| * usage: testWriter | |
| * test: testWriter && for i in 1 2 3 4 ; do diff $(srcdir)/writer.xml writer$$i.tmp || break ; done | |
| * author: Alfred Mickautsch | |
| * copy: see Copyright for the status of this software. | |
| */ | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include <libxml/encoding.h> | |
| #include <libxml/xmlwriter.h> | |
| #if defined(LIBXML_WRITER_ENABLED) && defined(LIBXML_OUTPUT_ENABLED) | |
| #define MY_ENCODING "ISO-8859-1" | |
| void testXmlwriterFilename(const char *uri); | |
| void testXmlwriterMemory(const char *file); | |
| void testXmlwriterDoc(const char *file); | |
| void testXmlwriterTree(const char *file); | |
| xmlChar *ConvertInput(const char *in, const char *encoding); | |
| int | |
| main(void) | |
| { | |
| /* | |
| * 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 | |
| /* first, the file version */ | |
| testXmlwriterFilename("writer1.tmp"); | |
| /* next, the memory version */ | |
| testXmlwriterMemory("writer2.tmp"); | |
| /* next, the DOM version */ | |
| testXmlwriterDoc("writer3.tmp"); | |
| /* next, the tree version */ | |
| testXmlwriterTree("writer4.tmp"); | |
| /* | |
| * Cleanup function for the XML library. | |
| */ | |
| xmlCleanupParser(); | |
| /* | |
| * this is to debug memory for regression tests | |
| */ | |
| xmlMemoryDump(); | |
| return 0; | |
| } | |
| /** | |
| * testXmlwriterFilename: | |
| * @uri: the output URI | |
| * | |
| * test the xmlWriter interface when writing to a new file | |
| */ | |
| void | |
| testXmlwriterFilename(const char *uri) | |
| { | |
| int rc; | |
| xmlTextWriterPtr writer; | |
| xmlChar *tmp; | |
| /* Create a new XmlWriter for uri, with no compression. */ | |
| writer = xmlNewTextWriterFilename(uri, 0); | |
| if (writer == NULL) { | |
| printf("testXmlwriterFilename: Error creating the xml writer\n"); | |
| return; | |
| } | |
| /* Start the document with the xml default for the version, | |
| * encoding ISO 8859-1 and the default for the standalone | |
| * declaration. */ | |
| rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterStartDocument\n"); | |
| return; | |
| } | |
| /* Start an element named "EXAMPLE". Since this is the first | |
| * element, this will be the root element of the document. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "EXAMPLE"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write a comment as child of EXAMPLE. | |
| * Please observe, that the input to the xmlTextWriter functions | |
| * HAS to be in UTF-8, even if the output XML is encoded | |
| * in iso-8859-1 */ | |
| tmp = ConvertInput("This is a comment with special chars: <\xE4\xF6\xFC>", | |
| MY_ENCODING); | |
| rc = xmlTextWriterWriteComment(writer, tmp); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterWriteComment\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Start an element named "ORDER" as child of EXAMPLE. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ORDER"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Add an attribute with name "version" and value "1.0" to ORDER. */ | |
| rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "version", | |
| BAD_CAST "1.0"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterWriteAttribute\n"); | |
| return; | |
| } | |
| /* Add an attribute with name "xml:lang" and value "de" to ORDER. */ | |
| rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang", | |
| BAD_CAST "de"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterWriteAttribute\n"); | |
| return; | |
| } | |
| /* Write a comment as child of ORDER */ | |
| tmp = ConvertInput("<\xE4\xF6\xFC>", MY_ENCODING); | |
| rc = xmlTextWriterWriteFormatComment(writer, | |
| "This is another comment with special chars: %s", | |
| tmp); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterWriteFormatComment\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Start an element named "HEADER" as child of ORDER. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "HEADER"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "X_ORDER_ID" as child of HEADER. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "X_ORDER_ID", | |
| "%010d", 53535); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Write an element named "CUSTOMER_ID" as child of HEADER. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "CUSTOMER_ID", | |
| "%d", 1010); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Write an element named "NAME_1" as child of HEADER. */ | |
| tmp = ConvertInput("M\xFCller", MY_ENCODING); | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_1", tmp); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Write an element named "NAME_2" as child of HEADER. */ | |
| tmp = ConvertInput("J\xF6rg", MY_ENCODING); | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_2", tmp); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Close the element named HEADER. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Start an element named "ENTRIES" as child of ORDER. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRIES"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Start an element named "ENTRY" as child of ENTRIES. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ARTICLE" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE", | |
| BAD_CAST "<Test>"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ENTRY_NO" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d", | |
| 10); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Close the element named ENTRY. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Start an element named "ENTRY" as child of ENTRIES. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ARTICLE" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE", | |
| BAD_CAST "<Test 2>"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ENTRY_NO" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d", | |
| 20); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Close the element named ENTRY. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Close the element named ENTRIES. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Start an element named "FOOTER" as child of ORDER. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "FOOTER"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "TEXT" as child of FOOTER. */ | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "TEXT", | |
| BAD_CAST "This is a text."); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| /* Close the element named FOOTER. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Here we could close the elements ORDER and EXAMPLE using the | |
| * function xmlTextWriterEndElement, but since we do not want to | |
| * write any other elements, we simply call xmlTextWriterEndDocument, | |
| * which will do all the work. */ | |
| rc = xmlTextWriterEndDocument(writer); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterFilename: Error at xmlTextWriterEndDocument\n"); | |
| return; | |
| } | |
| xmlFreeTextWriter(writer); | |
| } | |
| /** | |
| * testXmlwriterMemory: | |
| * @file: the output file | |
| * | |
| * test the xmlWriter interface when writing to memory | |
| */ | |
| void | |
| testXmlwriterMemory(const char *file) | |
| { | |
| int rc; | |
| xmlTextWriterPtr writer; | |
| xmlBufferPtr buf; | |
| xmlChar *tmp; | |
| FILE *fp; | |
| /* Create a new XML buffer, to which the XML document will be | |
| * written */ | |
| buf = xmlBufferCreate(); | |
| if (buf == NULL) { | |
| printf("testXmlwriterMemory: Error creating the xml buffer\n"); | |
| return; | |
| } | |
| /* Create a new XmlWriter for memory, with no compression. | |
| * Remark: there is no compression for this kind of xmlTextWriter */ | |
| writer = xmlNewTextWriterMemory(buf, 0); | |
| if (writer == NULL) { | |
| printf("testXmlwriterMemory: Error creating the xml writer\n"); | |
| return; | |
| } | |
| /* Start the document with the xml default for the version, | |
| * encoding ISO 8859-1 and the default for the standalone | |
| * declaration. */ | |
| rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterStartDocument\n"); | |
| return; | |
| } | |
| /* Start an element named "EXAMPLE". Since this is the first | |
| * element, this will be the root element of the document. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "EXAMPLE"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write a comment as child of EXAMPLE. | |
| * Please observe, that the input to the xmlTextWriter functions | |
| * HAS to be in UTF-8, even if the output XML is encoded | |
| * in iso-8859-1 */ | |
| tmp = ConvertInput("This is a comment with special chars: <\xE4\xF6\xFC>", | |
| MY_ENCODING); | |
| rc = xmlTextWriterWriteComment(writer, tmp); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterWriteComment\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Start an element named "ORDER" as child of EXAMPLE. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ORDER"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Add an attribute with name "version" and value "1.0" to ORDER. */ | |
| rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "version", | |
| BAD_CAST "1.0"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterWriteAttribute\n"); | |
| return; | |
| } | |
| /* Add an attribute with name "xml:lang" and value "de" to ORDER. */ | |
| rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang", | |
| BAD_CAST "de"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterWriteAttribute\n"); | |
| return; | |
| } | |
| /* Write a comment as child of ORDER */ | |
| tmp = ConvertInput("<\xE4\xF6\xFC>", MY_ENCODING); | |
| rc = xmlTextWriterWriteFormatComment(writer, | |
| "This is another comment with special chars: %s", | |
| tmp); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterWriteFormatComment\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Start an element named "HEADER" as child of ORDER. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "HEADER"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "X_ORDER_ID" as child of HEADER. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "X_ORDER_ID", | |
| "%010d", 53535); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Write an element named "CUSTOMER_ID" as child of HEADER. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "CUSTOMER_ID", | |
| "%d", 1010); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Write an element named "NAME_1" as child of HEADER. */ | |
| tmp = ConvertInput("M\xFCller", MY_ENCODING); | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_1", tmp); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Write an element named "NAME_2" as child of HEADER. */ | |
| tmp = ConvertInput("J\xF6rg", MY_ENCODING); | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_2", tmp); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Close the element named HEADER. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterMemory: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Start an element named "ENTRIES" as child of ORDER. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRIES"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Start an element named "ENTRY" as child of ENTRIES. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ARTICLE" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE", | |
| BAD_CAST "<Test>"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ENTRY_NO" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d", | |
| 10); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Close the element named ENTRY. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterMemory: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Start an element named "ENTRY" as child of ENTRIES. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ARTICLE" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE", | |
| BAD_CAST "<Test 2>"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ENTRY_NO" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d", | |
| 20); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Close the element named ENTRY. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterMemory: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Close the element named ENTRIES. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterMemory: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Start an element named "FOOTER" as child of ORDER. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "FOOTER"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "TEXT" as child of FOOTER. */ | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "TEXT", | |
| BAD_CAST "This is a text."); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterMemory: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| /* Close the element named FOOTER. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterMemory: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Here we could close the elements ORDER and EXAMPLE using the | |
| * function xmlTextWriterEndElement, but since we do not want to | |
| * write any other elements, we simply call xmlTextWriterEndDocument, | |
| * which will do all the work. */ | |
| rc = xmlTextWriterEndDocument(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterMemory: Error at xmlTextWriterEndDocument\n"); | |
| return; | |
| } | |
| xmlFreeTextWriter(writer); | |
| fp = fopen(file, "w"); | |
| if (fp == NULL) { | |
| printf("testXmlwriterMemory: Error at fopen\n"); | |
| return; | |
| } | |
| fprintf(fp, "%s", (const char *) buf->content); | |
| fclose(fp); | |
| xmlBufferFree(buf); | |
| } | |
| /** | |
| * testXmlwriterDoc: | |
| * @file: the output file | |
| * | |
| * test the xmlWriter interface when creating a new document | |
| */ | |
| void | |
| testXmlwriterDoc(const char *file) | |
| { | |
| int rc; | |
| xmlTextWriterPtr writer; | |
| xmlChar *tmp; | |
| xmlDocPtr doc; | |
| /* Create a new XmlWriter for DOM, with no compression. */ | |
| writer = xmlNewTextWriterDoc(&doc, 0); | |
| if (writer == NULL) { | |
| printf("testXmlwriterDoc: Error creating the xml writer\n"); | |
| return; | |
| } | |
| /* Start the document with the xml default for the version, | |
| * encoding ISO 8859-1 and the default for the standalone | |
| * declaration. */ | |
| rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterStartDocument\n"); | |
| return; | |
| } | |
| /* Start an element named "EXAMPLE". Since this is the first | |
| * element, this will be the root element of the document. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "EXAMPLE"); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write a comment as child of EXAMPLE. | |
| * Please observe, that the input to the xmlTextWriter functions | |
| * HAS to be in UTF-8, even if the output XML is encoded | |
| * in iso-8859-1 */ | |
| tmp = ConvertInput("This is a comment with special chars: <\xE4\xF6\xFC>", | |
| MY_ENCODING); | |
| rc = xmlTextWriterWriteComment(writer, tmp); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterWriteComment\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Start an element named "ORDER" as child of EXAMPLE. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ORDER"); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Add an attribute with name "version" and value "1.0" to ORDER. */ | |
| rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "version", | |
| BAD_CAST "1.0"); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterWriteAttribute\n"); | |
| return; | |
| } | |
| /* Add an attribute with name "xml:lang" and value "de" to ORDER. */ | |
| rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang", | |
| BAD_CAST "de"); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterWriteAttribute\n"); | |
| return; | |
| } | |
| /* Write a comment as child of ORDER */ | |
| tmp = ConvertInput("<\xE4\xF6\xFC>", MY_ENCODING); | |
| rc = xmlTextWriterWriteFormatComment(writer, | |
| "This is another comment with special chars: %s", | |
| tmp); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterDoc: Error at xmlTextWriterWriteFormatComment\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Start an element named "HEADER" as child of ORDER. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "HEADER"); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "X_ORDER_ID" as child of HEADER. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "X_ORDER_ID", | |
| "%010d", 53535); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterDoc: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Write an element named "CUSTOMER_ID" as child of HEADER. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "CUSTOMER_ID", | |
| "%d", 1010); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterDoc: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Write an element named "NAME_1" as child of HEADER. */ | |
| tmp = ConvertInput("M\xFCller", MY_ENCODING); | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_1", tmp); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Write an element named "NAME_2" as child of HEADER. */ | |
| tmp = ConvertInput("J\xF6rg", MY_ENCODING); | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_2", tmp); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Close the element named HEADER. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Start an element named "ENTRIES" as child of ORDER. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRIES"); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Start an element named "ENTRY" as child of ENTRIES. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY"); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ARTICLE" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE", | |
| BAD_CAST "<Test>"); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ENTRY_NO" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d", | |
| 10); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterDoc: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Close the element named ENTRY. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Start an element named "ENTRY" as child of ENTRIES. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY"); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ARTICLE" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE", | |
| BAD_CAST "<Test 2>"); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ENTRY_NO" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d", | |
| 20); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterDoc: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Close the element named ENTRY. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Close the element named ENTRIES. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Start an element named "FOOTER" as child of ORDER. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "FOOTER"); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "TEXT" as child of FOOTER. */ | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "TEXT", | |
| BAD_CAST "This is a text."); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| /* Close the element named FOOTER. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Here we could close the elements ORDER and EXAMPLE using the | |
| * function xmlTextWriterEndElement, but since we do not want to | |
| * write any other elements, we simply call xmlTextWriterEndDocument, | |
| * which will do all the work. */ | |
| rc = xmlTextWriterEndDocument(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterDoc: Error at xmlTextWriterEndDocument\n"); | |
| return; | |
| } | |
| xmlFreeTextWriter(writer); | |
| xmlSaveFileEnc(file, doc, MY_ENCODING); | |
| xmlFreeDoc(doc); | |
| } | |
| /** | |
| * testXmlwriterTree: | |
| * @file: the output file | |
| * | |
| * test the xmlWriter interface when writing to a subtree | |
| */ | |
| void | |
| testXmlwriterTree(const char *file) | |
| { | |
| int rc; | |
| xmlTextWriterPtr writer; | |
| xmlDocPtr doc; | |
| xmlNodePtr node; | |
| xmlChar *tmp; | |
| /* Create a new XML DOM tree, to which the XML document will be | |
| * written */ | |
| doc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION); | |
| if (doc == NULL) { | |
| printf | |
| ("testXmlwriterTree: Error creating the xml document tree\n"); | |
| return; | |
| } | |
| /* Create a new XML node, to which the XML document will be | |
| * appended */ | |
| node = xmlNewDocNode(doc, NULL, BAD_CAST "EXAMPLE", NULL); | |
| if (node == NULL) { | |
| printf("testXmlwriterTree: Error creating the xml node\n"); | |
| return; | |
| } | |
| /* Make ELEMENT the root node of the tree */ | |
| xmlDocSetRootElement(doc, node); | |
| /* Create a new XmlWriter for DOM tree, with no compression. */ | |
| writer = xmlNewTextWriterTree(doc, node, 0); | |
| if (writer == NULL) { | |
| printf("testXmlwriterTree: Error creating the xml writer\n"); | |
| return; | |
| } | |
| /* Start the document with the xml default for the version, | |
| * encoding ISO 8859-1 and the default for the standalone | |
| * declaration. */ | |
| rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterStartDocument\n"); | |
| return; | |
| } | |
| /* Write a comment as child of EXAMPLE. | |
| * Please observe, that the input to the xmlTextWriter functions | |
| * HAS to be in UTF-8, even if the output XML is encoded | |
| * in iso-8859-1 */ | |
| tmp = ConvertInput("This is a comment with special chars: <\xE4\xF6\xFC>", | |
| MY_ENCODING); | |
| rc = xmlTextWriterWriteComment(writer, tmp); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterWriteComment\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Start an element named "ORDER" as child of EXAMPLE. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ORDER"); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Add an attribute with name "version" and value "1.0" to ORDER. */ | |
| rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "version", | |
| BAD_CAST "1.0"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterTree: Error at xmlTextWriterWriteAttribute\n"); | |
| return; | |
| } | |
| /* Add an attribute with name "xml:lang" and value "de" to ORDER. */ | |
| rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang", | |
| BAD_CAST "de"); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterTree: Error at xmlTextWriterWriteAttribute\n"); | |
| return; | |
| } | |
| /* Write a comment as child of ORDER */ | |
| tmp = ConvertInput("<\xE4\xF6\xFC>", MY_ENCODING); | |
| rc = xmlTextWriterWriteFormatComment(writer, | |
| "This is another comment with special chars: %s", | |
| tmp); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterTree: Error at xmlTextWriterWriteFormatComment\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Start an element named "HEADER" as child of ORDER. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "HEADER"); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "X_ORDER_ID" as child of HEADER. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "X_ORDER_ID", | |
| "%010d", 53535); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterTree: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Write an element named "CUSTOMER_ID" as child of HEADER. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "CUSTOMER_ID", | |
| "%d", 1010); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterTree: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Write an element named "NAME_1" as child of HEADER. */ | |
| tmp = ConvertInput("M\xFCller", MY_ENCODING); | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_1", tmp); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Write an element named "NAME_2" as child of HEADER. */ | |
| tmp = ConvertInput("J\xF6rg", MY_ENCODING); | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_2", tmp); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| if (tmp != NULL) xmlFree(tmp); | |
| /* Close the element named HEADER. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Start an element named "ENTRIES" as child of ORDER. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRIES"); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Start an element named "ENTRY" as child of ENTRIES. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY"); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ARTICLE" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE", | |
| BAD_CAST "<Test>"); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ENTRY_NO" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d", | |
| 10); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterTree: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Close the element named ENTRY. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Start an element named "ENTRY" as child of ENTRIES. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY"); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ARTICLE" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE", | |
| BAD_CAST "<Test 2>"); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| /* Write an element named "ENTRY_NO" as child of ENTRY. */ | |
| rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d", | |
| 20); | |
| if (rc < 0) { | |
| printf | |
| ("testXmlwriterTree: Error at xmlTextWriterWriteFormatElement\n"); | |
| return; | |
| } | |
| /* Close the element named ENTRY. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Close the element named ENTRIES. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Start an element named "FOOTER" as child of ORDER. */ | |
| rc = xmlTextWriterStartElement(writer, BAD_CAST "FOOTER"); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterStartElement\n"); | |
| return; | |
| } | |
| /* Write an element named "TEXT" as child of FOOTER. */ | |
| rc = xmlTextWriterWriteElement(writer, BAD_CAST "TEXT", | |
| BAD_CAST "This is a text."); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterWriteElement\n"); | |
| return; | |
| } | |
| /* Close the element named FOOTER. */ | |
| rc = xmlTextWriterEndElement(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterEndElement\n"); | |
| return; | |
| } | |
| /* Here we could close the elements ORDER and EXAMPLE using the | |
| * function xmlTextWriterEndElement, but since we do not want to | |
| * write any other elements, we simply call xmlTextWriterEndDocument, | |
| * which will do all the work. */ | |
| rc = xmlTextWriterEndDocument(writer); | |
| if (rc < 0) { | |
| printf("testXmlwriterTree: Error at xmlTextWriterEndDocument\n"); | |
| return; | |
| } | |
| xmlFreeTextWriter(writer); | |
| xmlSaveFileEnc(file, doc, MY_ENCODING); | |
| xmlFreeDoc(doc); | |
| } | |
| /** | |
| * ConvertInput: | |
| * @in: string in a given encoding | |
| * @encoding: the encoding used | |
| * | |
| * Converts @in into UTF-8 for processing with libxml2 APIs | |
| * | |
| * Returns the converted UTF-8 string, or NULL in case of error. | |
| */ | |
| xmlChar * | |
| ConvertInput(const char *in, const char *encoding) | |
| { | |
| xmlChar *out; | |
| int ret; | |
| int size; | |
| int out_size; | |
| int temp; | |
| xmlCharEncodingHandlerPtr handler; | |
| if (in == 0) | |
| return 0; | |
| handler = xmlFindCharEncodingHandler(encoding); | |
| if (!handler) { | |
| printf("ConvertInput: no encoding handler found for '%s'\n", | |
| encoding ? encoding : ""); | |
| return 0; | |
| } | |
| size = (int) strlen(in) + 1; | |
| out_size = size * 2 - 1; | |
| out = (unsigned char *) xmlMalloc((size_t) out_size); | |
| if (out != 0) { | |
| temp = size - 1; | |
| ret = handler->input(out, &out_size, (const xmlChar *) in, &temp); | |
| if ((ret < 0) || (temp - size + 1)) { | |
| if (ret < 0) { | |
| printf("ConvertInput: conversion wasn't successful.\n"); | |
| } else { | |
| printf | |
| ("ConvertInput: conversion wasn't successful. converted: %i octets.\n", | |
| temp); | |
| } | |
| xmlFree(out); | |
| out = 0; | |
| } else { | |
| out = (unsigned char *) xmlRealloc(out, out_size + 1); | |
| out[out_size] = 0; /*null terminating out */ | |
| } | |
| } else { | |
| printf("ConvertInput: no mem\n"); | |
| } | |
| return out; | |
| } | |
| #else | |
| int main(void) { | |
| fprintf(stderr, "Writer or output support not compiled in\n"); | |
| return 0; | |
| } | |
| #endif |