Home | History | Annotate | Download | only in examples
      1 /**
      2  * section: xmlWriter
      3  * synopsis: use various APIs for the xmlWriter
      4  * purpose: tests a number of APIs for the xmlWriter, especially
      5  *          the various methods to write to a filename, to a memory
      6  *          buffer, to a new document, or to a subtree. It shows how to
      7  *          do encoding string conversions too. The resulting
      8  *          documents are then serialized.
      9  * usage: testWriter
     10  * test: testWriter && for i in 1 2 3 4 ; do diff $(srcdir)/writer.xml writer$$i.tmp || break ; done
     11  * author: Alfred Mickautsch
     12  * copy: see Copyright for the status of this software.
     13  */
     14 #include <stdio.h>
     15 #include <string.h>
     16 #include <libxml/encoding.h>
     17 #include <libxml/xmlwriter.h>
     18 
     19 #if defined(LIBXML_WRITER_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
     20 
     21 #define MY_ENCODING "ISO-8859-1"
     22 
     23 void testXmlwriterFilename(const char *uri);
     24 void testXmlwriterMemory(const char *file);
     25 void testXmlwriterDoc(const char *file);
     26 void testXmlwriterTree(const char *file);
     27 xmlChar *ConvertInput(const char *in, const char *encoding);
     28 
     29 int
     30 main(void)
     31 {
     32     /*
     33      * this initialize the library and check potential ABI mismatches
     34      * between the version it was compiled for and the actual shared
     35      * library used.
     36      */
     37     LIBXML_TEST_VERSION
     38 
     39     /* first, the file version */
     40     testXmlwriterFilename("writer1.tmp");
     41 
     42     /* next, the memory version */
     43     testXmlwriterMemory("writer2.tmp");
     44 
     45     /* next, the DOM version */
     46     testXmlwriterDoc("writer3.tmp");
     47 
     48     /* next, the tree version */
     49     testXmlwriterTree("writer4.tmp");
     50 
     51     /*
     52      * Cleanup function for the XML library.
     53      */
     54     xmlCleanupParser();
     55     /*
     56      * this is to debug memory for regression tests
     57      */
     58     xmlMemoryDump();
     59     return 0;
     60 }
     61 
     62 /**
     63  * testXmlwriterFilename:
     64  * @uri: the output URI
     65  *
     66  * test the xmlWriter interface when writing to a new file
     67  */
     68 void
     69 testXmlwriterFilename(const char *uri)
     70 {
     71     int rc;
     72     xmlTextWriterPtr writer;
     73     xmlChar *tmp;
     74 
     75     /* Create a new XmlWriter for uri, with no compression. */
     76     writer = xmlNewTextWriterFilename(uri, 0);
     77     if (writer == NULL) {
     78         printf("testXmlwriterFilename: Error creating the xml writer\n");
     79         return;
     80     }
     81 
     82     /* Start the document with the xml default for the version,
     83      * encoding ISO 8859-1 and the default for the standalone
     84      * declaration. */
     85     rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL);
     86     if (rc < 0) {
     87         printf
     88             ("testXmlwriterFilename: Error at xmlTextWriterStartDocument\n");
     89         return;
     90     }
     91 
     92     /* Start an element named "EXAMPLE". Since thist is the first
     93      * element, this will be the root element of the document. */
     94     rc = xmlTextWriterStartElement(writer, BAD_CAST "EXAMPLE");
     95     if (rc < 0) {
     96         printf
     97             ("testXmlwriterFilename: Error at xmlTextWriterStartElement\n");
     98         return;
     99     }
    100 
    101     /* Write a comment as child of EXAMPLE.
    102      * Please observe, that the input to the xmlTextWriter functions
    103      * HAS to be in UTF-8, even if the output XML is encoded
    104      * in iso-8859-1 */
    105     tmp = ConvertInput("This is a comment with special chars: <\xE4\xF6\xFC>",
    106                        MY_ENCODING);
    107     rc = xmlTextWriterWriteComment(writer, tmp);
    108     if (rc < 0) {
    109         printf
    110             ("testXmlwriterFilename: Error at xmlTextWriterWriteComment\n");
    111         return;
    112     }
    113     if (tmp != NULL) xmlFree(tmp);
    114 
    115     /* Start an element named "ORDER" as child of EXAMPLE. */
    116     rc = xmlTextWriterStartElement(writer, BAD_CAST "ORDER");
    117     if (rc < 0) {
    118         printf
    119             ("testXmlwriterFilename: Error at xmlTextWriterStartElement\n");
    120         return;
    121     }
    122 
    123     /* Add an attribute with name "version" and value "1.0" to ORDER. */
    124     rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "version",
    125                                      BAD_CAST "1.0");
    126     if (rc < 0) {
    127         printf
    128             ("testXmlwriterFilename: Error at xmlTextWriterWriteAttribute\n");
    129         return;
    130     }
    131 
    132     /* Add an attribute with name "xml:lang" and value "de" to ORDER. */
    133     rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang",
    134                                      BAD_CAST "de");
    135     if (rc < 0) {
    136         printf
    137             ("testXmlwriterFilename: Error at xmlTextWriterWriteAttribute\n");
    138         return;
    139     }
    140 
    141     /* Write a comment as child of ORDER */
    142     tmp = ConvertInput("<\xE4\xF6\xFC>", MY_ENCODING);
    143     rc = xmlTextWriterWriteFormatComment(writer,
    144 		     "This is another comment with special chars: %s",
    145 		     tmp);
    146     if (rc < 0) {
    147         printf
    148             ("testXmlwriterFilename: Error at xmlTextWriterWriteFormatComment\n");
    149         return;
    150     }
    151     if (tmp != NULL) xmlFree(tmp);
    152 
    153     /* Start an element named "HEADER" as child of ORDER. */
    154     rc = xmlTextWriterStartElement(writer, BAD_CAST "HEADER");
    155     if (rc < 0) {
    156         printf
    157             ("testXmlwriterFilename: Error at xmlTextWriterStartElement\n");
    158         return;
    159     }
    160 
    161     /* Write an element named "X_ORDER_ID" as child of HEADER. */
    162     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "X_ORDER_ID",
    163                                          "%010d", 53535);
    164     if (rc < 0) {
    165         printf
    166             ("testXmlwriterFilename: Error at xmlTextWriterWriteFormatElement\n");
    167         return;
    168     }
    169 
    170     /* Write an element named "CUSTOMER_ID" as child of HEADER. */
    171     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "CUSTOMER_ID",
    172                                          "%d", 1010);
    173     if (rc < 0) {
    174         printf
    175             ("testXmlwriterFilename: Error at xmlTextWriterWriteFormatElement\n");
    176         return;
    177     }
    178 
    179     /* Write an element named "NAME_1" as child of HEADER. */
    180     tmp = ConvertInput("M\xFCller", MY_ENCODING);
    181     rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_1", tmp);
    182     if (rc < 0) {
    183         printf
    184             ("testXmlwriterFilename: Error at xmlTextWriterWriteElement\n");
    185         return;
    186     }
    187     if (tmp != NULL) xmlFree(tmp);
    188 
    189     /* Write an element named "NAME_2" as child of HEADER. */
    190     tmp = ConvertInput("J\xF6rg", MY_ENCODING);
    191     rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_2", tmp);
    192     if (rc < 0) {
    193         printf
    194             ("testXmlwriterFilename: Error at xmlTextWriterWriteElement\n");
    195         return;
    196     }
    197     if (tmp != NULL) xmlFree(tmp);
    198 
    199     /* Close the element named HEADER. */
    200     rc = xmlTextWriterEndElement(writer);
    201     if (rc < 0) {
    202         printf
    203             ("testXmlwriterFilename: Error at xmlTextWriterEndElement\n");
    204         return;
    205     }
    206 
    207     /* Start an element named "ENTRIES" as child of ORDER. */
    208     rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRIES");
    209     if (rc < 0) {
    210         printf
    211             ("testXmlwriterFilename: Error at xmlTextWriterStartElement\n");
    212         return;
    213     }
    214 
    215     /* Start an element named "ENTRY" as child of ENTRIES. */
    216     rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY");
    217     if (rc < 0) {
    218         printf
    219             ("testXmlwriterFilename: Error at xmlTextWriterStartElement\n");
    220         return;
    221     }
    222 
    223     /* Write an element named "ARTICLE" as child of ENTRY. */
    224     rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE",
    225                                    BAD_CAST "<Test>");
    226     if (rc < 0) {
    227         printf
    228             ("testXmlwriterFilename: Error at xmlTextWriterWriteElement\n");
    229         return;
    230     }
    231 
    232     /* Write an element named "ENTRY_NO" as child of ENTRY. */
    233     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d",
    234                                          10);
    235     if (rc < 0) {
    236         printf
    237             ("testXmlwriterFilename: Error at xmlTextWriterWriteFormatElement\n");
    238         return;
    239     }
    240 
    241     /* Close the element named ENTRY. */
    242     rc = xmlTextWriterEndElement(writer);
    243     if (rc < 0) {
    244         printf
    245             ("testXmlwriterFilename: Error at xmlTextWriterEndElement\n");
    246         return;
    247     }
    248 
    249     /* Start an element named "ENTRY" as child of ENTRIES. */
    250     rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY");
    251     if (rc < 0) {
    252         printf
    253             ("testXmlwriterFilename: Error at xmlTextWriterStartElement\n");
    254         return;
    255     }
    256 
    257     /* Write an element named "ARTICLE" as child of ENTRY. */
    258     rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE",
    259                                    BAD_CAST "<Test 2>");
    260     if (rc < 0) {
    261         printf
    262             ("testXmlwriterFilename: Error at xmlTextWriterWriteElement\n");
    263         return;
    264     }
    265 
    266     /* Write an element named "ENTRY_NO" as child of ENTRY. */
    267     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d",
    268                                          20);
    269     if (rc < 0) {
    270         printf
    271             ("testXmlwriterFilename: Error at xmlTextWriterWriteFormatElement\n");
    272         return;
    273     }
    274 
    275     /* Close the element named ENTRY. */
    276     rc = xmlTextWriterEndElement(writer);
    277     if (rc < 0) {
    278         printf
    279             ("testXmlwriterFilename: Error at xmlTextWriterEndElement\n");
    280         return;
    281     }
    282 
    283     /* Close the element named ENTRIES. */
    284     rc = xmlTextWriterEndElement(writer);
    285     if (rc < 0) {
    286         printf
    287             ("testXmlwriterFilename: Error at xmlTextWriterEndElement\n");
    288         return;
    289     }
    290 
    291     /* Start an element named "FOOTER" as child of ORDER. */
    292     rc = xmlTextWriterStartElement(writer, BAD_CAST "FOOTER");
    293     if (rc < 0) {
    294         printf
    295             ("testXmlwriterFilename: Error at xmlTextWriterStartElement\n");
    296         return;
    297     }
    298 
    299     /* Write an element named "TEXT" as child of FOOTER. */
    300     rc = xmlTextWriterWriteElement(writer, BAD_CAST "TEXT",
    301                                    BAD_CAST "This is a text.");
    302     if (rc < 0) {
    303         printf
    304             ("testXmlwriterFilename: Error at xmlTextWriterWriteElement\n");
    305         return;
    306     }
    307 
    308     /* Close the element named FOOTER. */
    309     rc = xmlTextWriterEndElement(writer);
    310     if (rc < 0) {
    311         printf
    312             ("testXmlwriterFilename: Error at xmlTextWriterEndElement\n");
    313         return;
    314     }
    315 
    316     /* Here we could close the elements ORDER and EXAMPLE using the
    317      * function xmlTextWriterEndElement, but since we do not want to
    318      * write any other elements, we simply call xmlTextWriterEndDocument,
    319      * which will do all the work. */
    320     rc = xmlTextWriterEndDocument(writer);
    321     if (rc < 0) {
    322         printf
    323             ("testXmlwriterFilename: Error at xmlTextWriterEndDocument\n");
    324         return;
    325     }
    326 
    327     xmlFreeTextWriter(writer);
    328 }
    329 
    330 /**
    331  * testXmlwriterMemory:
    332  * @file: the output file
    333  *
    334  * test the xmlWriter interface when writing to memory
    335  */
    336 void
    337 testXmlwriterMemory(const char *file)
    338 {
    339     int rc;
    340     xmlTextWriterPtr writer;
    341     xmlBufferPtr buf;
    342     xmlChar *tmp;
    343     FILE *fp;
    344 
    345     /* Create a new XML buffer, to which the XML document will be
    346      * written */
    347     buf = xmlBufferCreate();
    348     if (buf == NULL) {
    349         printf("testXmlwriterMemory: Error creating the xml buffer\n");
    350         return;
    351     }
    352 
    353     /* Create a new XmlWriter for memory, with no compression.
    354      * Remark: there is no compression for this kind of xmlTextWriter */
    355     writer = xmlNewTextWriterMemory(buf, 0);
    356     if (writer == NULL) {
    357         printf("testXmlwriterMemory: Error creating the xml writer\n");
    358         return;
    359     }
    360 
    361     /* Start the document with the xml default for the version,
    362      * encoding ISO 8859-1 and the default for the standalone
    363      * declaration. */
    364     rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL);
    365     if (rc < 0) {
    366         printf
    367             ("testXmlwriterMemory: Error at xmlTextWriterStartDocument\n");
    368         return;
    369     }
    370 
    371     /* Start an element named "EXAMPLE". Since thist is the first
    372      * element, this will be the root element of the document. */
    373     rc = xmlTextWriterStartElement(writer, BAD_CAST "EXAMPLE");
    374     if (rc < 0) {
    375         printf
    376             ("testXmlwriterMemory: Error at xmlTextWriterStartElement\n");
    377         return;
    378     }
    379 
    380     /* Write a comment as child of EXAMPLE.
    381      * Please observe, that the input to the xmlTextWriter functions
    382      * HAS to be in UTF-8, even if the output XML is encoded
    383      * in iso-8859-1 */
    384     tmp = ConvertInput("This is a comment with special chars: <\xE4\xF6\xFC>",
    385                        MY_ENCODING);
    386     rc = xmlTextWriterWriteComment(writer, tmp);
    387     if (rc < 0) {
    388         printf
    389             ("testXmlwriterMemory: Error at xmlTextWriterWriteComment\n");
    390         return;
    391     }
    392     if (tmp != NULL) xmlFree(tmp);
    393 
    394     /* Start an element named "ORDER" as child of EXAMPLE. */
    395     rc = xmlTextWriterStartElement(writer, BAD_CAST "ORDER");
    396     if (rc < 0) {
    397         printf
    398             ("testXmlwriterMemory: Error at xmlTextWriterStartElement\n");
    399         return;
    400     }
    401 
    402     /* Add an attribute with name "version" and value "1.0" to ORDER. */
    403     rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "version",
    404                                      BAD_CAST "1.0");
    405     if (rc < 0) {
    406         printf
    407             ("testXmlwriterMemory: Error at xmlTextWriterWriteAttribute\n");
    408         return;
    409     }
    410 
    411     /* Add an attribute with name "xml:lang" and value "de" to ORDER. */
    412     rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang",
    413                                      BAD_CAST "de");
    414     if (rc < 0) {
    415         printf
    416             ("testXmlwriterMemory: Error at xmlTextWriterWriteAttribute\n");
    417         return;
    418     }
    419 
    420     /* Write a comment as child of ORDER */
    421     tmp = ConvertInput("<\xE4\xF6\xFC>", MY_ENCODING);
    422     rc = xmlTextWriterWriteFormatComment(writer,
    423 		     "This is another comment with special chars: %s",
    424                                          tmp);
    425     if (rc < 0) {
    426         printf
    427             ("testXmlwriterMemory: Error at xmlTextWriterWriteFormatComment\n");
    428         return;
    429     }
    430     if (tmp != NULL) xmlFree(tmp);
    431 
    432     /* Start an element named "HEADER" as child of ORDER. */
    433     rc = xmlTextWriterStartElement(writer, BAD_CAST "HEADER");
    434     if (rc < 0) {
    435         printf
    436             ("testXmlwriterMemory: Error at xmlTextWriterStartElement\n");
    437         return;
    438     }
    439 
    440     /* Write an element named "X_ORDER_ID" as child of HEADER. */
    441     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "X_ORDER_ID",
    442                                          "%010d", 53535);
    443     if (rc < 0) {
    444         printf
    445             ("testXmlwriterMemory: Error at xmlTextWriterWriteFormatElement\n");
    446         return;
    447     }
    448 
    449     /* Write an element named "CUSTOMER_ID" as child of HEADER. */
    450     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "CUSTOMER_ID",
    451                                          "%d", 1010);
    452     if (rc < 0) {
    453         printf
    454             ("testXmlwriterMemory: Error at xmlTextWriterWriteFormatElement\n");
    455         return;
    456     }
    457 
    458     /* Write an element named "NAME_1" as child of HEADER. */
    459     tmp = ConvertInput("M\xFCller", MY_ENCODING);
    460     rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_1", tmp);
    461     if (rc < 0) {
    462         printf
    463             ("testXmlwriterMemory: Error at xmlTextWriterWriteElement\n");
    464         return;
    465     }
    466     if (tmp != NULL) xmlFree(tmp);
    467 
    468     /* Write an element named "NAME_2" as child of HEADER. */
    469     tmp = ConvertInput("J\xF6rg", MY_ENCODING);
    470     rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_2", tmp);
    471 
    472     if (rc < 0) {
    473         printf
    474             ("testXmlwriterMemory: Error at xmlTextWriterWriteElement\n");
    475         return;
    476     }
    477     if (tmp != NULL) xmlFree(tmp);
    478 
    479     /* Close the element named HEADER. */
    480     rc = xmlTextWriterEndElement(writer);
    481     if (rc < 0) {
    482         printf("testXmlwriterMemory: Error at xmlTextWriterEndElement\n");
    483         return;
    484     }
    485 
    486     /* Start an element named "ENTRIES" as child of ORDER. */
    487     rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRIES");
    488     if (rc < 0) {
    489         printf
    490             ("testXmlwriterMemory: Error at xmlTextWriterStartElement\n");
    491         return;
    492     }
    493 
    494     /* Start an element named "ENTRY" as child of ENTRIES. */
    495     rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY");
    496     if (rc < 0) {
    497         printf
    498             ("testXmlwriterMemory: Error at xmlTextWriterStartElement\n");
    499         return;
    500     }
    501 
    502     /* Write an element named "ARTICLE" as child of ENTRY. */
    503     rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE",
    504                                    BAD_CAST "<Test>");
    505     if (rc < 0) {
    506         printf
    507             ("testXmlwriterMemory: Error at xmlTextWriterWriteElement\n");
    508         return;
    509     }
    510 
    511     /* Write an element named "ENTRY_NO" as child of ENTRY. */
    512     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d",
    513                                          10);
    514     if (rc < 0) {
    515         printf
    516             ("testXmlwriterMemory: Error at xmlTextWriterWriteFormatElement\n");
    517         return;
    518     }
    519 
    520     /* Close the element named ENTRY. */
    521     rc = xmlTextWriterEndElement(writer);
    522     if (rc < 0) {
    523         printf("testXmlwriterMemory: Error at xmlTextWriterEndElement\n");
    524         return;
    525     }
    526 
    527     /* Start an element named "ENTRY" as child of ENTRIES. */
    528     rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY");
    529     if (rc < 0) {
    530         printf
    531             ("testXmlwriterMemory: Error at xmlTextWriterStartElement\n");
    532         return;
    533     }
    534 
    535     /* Write an element named "ARTICLE" as child of ENTRY. */
    536     rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE",
    537                                    BAD_CAST "<Test 2>");
    538     if (rc < 0) {
    539         printf
    540             ("testXmlwriterMemory: Error at xmlTextWriterWriteElement\n");
    541         return;
    542     }
    543 
    544     /* Write an element named "ENTRY_NO" as child of ENTRY. */
    545     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d",
    546                                          20);
    547     if (rc < 0) {
    548         printf
    549             ("testXmlwriterMemory: Error at xmlTextWriterWriteFormatElement\n");
    550         return;
    551     }
    552 
    553     /* Close the element named ENTRY. */
    554     rc = xmlTextWriterEndElement(writer);
    555     if (rc < 0) {
    556         printf("testXmlwriterMemory: Error at xmlTextWriterEndElement\n");
    557         return;
    558     }
    559 
    560     /* Close the element named ENTRIES. */
    561     rc = xmlTextWriterEndElement(writer);
    562     if (rc < 0) {
    563         printf("testXmlwriterMemory: Error at xmlTextWriterEndElement\n");
    564         return;
    565     }
    566 
    567     /* Start an element named "FOOTER" as child of ORDER. */
    568     rc = xmlTextWriterStartElement(writer, BAD_CAST "FOOTER");
    569     if (rc < 0) {
    570         printf
    571             ("testXmlwriterMemory: Error at xmlTextWriterStartElement\n");
    572         return;
    573     }
    574 
    575     /* Write an element named "TEXT" as child of FOOTER. */
    576     rc = xmlTextWriterWriteElement(writer, BAD_CAST "TEXT",
    577                                    BAD_CAST "This is a text.");
    578     if (rc < 0) {
    579         printf
    580             ("testXmlwriterMemory: Error at xmlTextWriterWriteElement\n");
    581         return;
    582     }
    583 
    584     /* Close the element named FOOTER. */
    585     rc = xmlTextWriterEndElement(writer);
    586     if (rc < 0) {
    587         printf("testXmlwriterMemory: Error at xmlTextWriterEndElement\n");
    588         return;
    589     }
    590 
    591     /* Here we could close the elements ORDER and EXAMPLE using the
    592      * function xmlTextWriterEndElement, but since we do not want to
    593      * write any other elements, we simply call xmlTextWriterEndDocument,
    594      * which will do all the work. */
    595     rc = xmlTextWriterEndDocument(writer);
    596     if (rc < 0) {
    597         printf("testXmlwriterMemory: Error at xmlTextWriterEndDocument\n");
    598         return;
    599     }
    600 
    601     xmlFreeTextWriter(writer);
    602 
    603     fp = fopen(file, "w");
    604     if (fp == NULL) {
    605         printf("testXmlwriterMemory: Error at fopen\n");
    606         return;
    607     }
    608 
    609     fprintf(fp, "%s", (const char *) buf->content);
    610 
    611     fclose(fp);
    612 
    613     xmlBufferFree(buf);
    614 }
    615 
    616 /**
    617  * testXmlwriterDoc:
    618  * @file: the output file
    619  *
    620  * test the xmlWriter interface when creating a new document
    621  */
    622 void
    623 testXmlwriterDoc(const char *file)
    624 {
    625     int rc;
    626     xmlTextWriterPtr writer;
    627     xmlChar *tmp;
    628     xmlDocPtr doc;
    629 
    630 
    631     /* Create a new XmlWriter for DOM, with no compression. */
    632     writer = xmlNewTextWriterDoc(&doc, 0);
    633     if (writer == NULL) {
    634         printf("testXmlwriterDoc: Error creating the xml writer\n");
    635         return;
    636     }
    637 
    638     /* Start the document with the xml default for the version,
    639      * encoding ISO 8859-1 and the default for the standalone
    640      * declaration. */
    641     rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL);
    642     if (rc < 0) {
    643         printf("testXmlwriterDoc: Error at xmlTextWriterStartDocument\n");
    644         return;
    645     }
    646 
    647     /* Start an element named "EXAMPLE". Since thist is the first
    648      * element, this will be the root element of the document. */
    649     rc = xmlTextWriterStartElement(writer, BAD_CAST "EXAMPLE");
    650     if (rc < 0) {
    651         printf("testXmlwriterDoc: Error at xmlTextWriterStartElement\n");
    652         return;
    653     }
    654 
    655     /* Write a comment as child of EXAMPLE.
    656      * Please observe, that the input to the xmlTextWriter functions
    657      * HAS to be in UTF-8, even if the output XML is encoded
    658      * in iso-8859-1 */
    659     tmp = ConvertInput("This is a comment with special chars: <\xE4\xF6\xFC>",
    660                        MY_ENCODING);
    661     rc = xmlTextWriterWriteComment(writer, tmp);
    662     if (rc < 0) {
    663         printf("testXmlwriterDoc: Error at xmlTextWriterWriteComment\n");
    664         return;
    665     }
    666     if (tmp != NULL) xmlFree(tmp);
    667 
    668     /* Start an element named "ORDER" as child of EXAMPLE. */
    669     rc = xmlTextWriterStartElement(writer, BAD_CAST "ORDER");
    670     if (rc < 0) {
    671         printf("testXmlwriterDoc: Error at xmlTextWriterStartElement\n");
    672         return;
    673     }
    674 
    675     /* Add an attribute with name "version" and value "1.0" to ORDER. */
    676     rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "version",
    677                                      BAD_CAST "1.0");
    678     if (rc < 0) {
    679         printf("testXmlwriterDoc: Error at xmlTextWriterWriteAttribute\n");
    680         return;
    681     }
    682 
    683     /* Add an attribute with name "xml:lang" and value "de" to ORDER. */
    684     rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang",
    685                                      BAD_CAST "de");
    686     if (rc < 0) {
    687         printf("testXmlwriterDoc: Error at xmlTextWriterWriteAttribute\n");
    688         return;
    689     }
    690 
    691     /* Write a comment as child of ORDER */
    692     tmp = ConvertInput("<\xE4\xF6\xFC>", MY_ENCODING);
    693     rc = xmlTextWriterWriteFormatComment(writer,
    694 		 "This is another comment with special chars: %s",
    695 		                         tmp);
    696     if (rc < 0) {
    697         printf
    698             ("testXmlwriterDoc: Error at xmlTextWriterWriteFormatComment\n");
    699         return;
    700     }
    701     if (tmp != NULL) xmlFree(tmp);
    702 
    703     /* Start an element named "HEADER" as child of ORDER. */
    704     rc = xmlTextWriterStartElement(writer, BAD_CAST "HEADER");
    705     if (rc < 0) {
    706         printf("testXmlwriterDoc: Error at xmlTextWriterStartElement\n");
    707         return;
    708     }
    709 
    710     /* Write an element named "X_ORDER_ID" as child of HEADER. */
    711     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "X_ORDER_ID",
    712                                          "%010d", 53535);
    713     if (rc < 0) {
    714         printf
    715             ("testXmlwriterDoc: Error at xmlTextWriterWriteFormatElement\n");
    716         return;
    717     }
    718 
    719     /* Write an element named "CUSTOMER_ID" as child of HEADER. */
    720     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "CUSTOMER_ID",
    721                                          "%d", 1010);
    722     if (rc < 0) {
    723         printf
    724             ("testXmlwriterDoc: Error at xmlTextWriterWriteFormatElement\n");
    725         return;
    726     }
    727 
    728     /* Write an element named "NAME_1" as child of HEADER. */
    729     tmp = ConvertInput("M\xFCller", MY_ENCODING);
    730     rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_1", tmp);
    731     if (rc < 0) {
    732         printf("testXmlwriterDoc: Error at xmlTextWriterWriteElement\n");
    733         return;
    734     }
    735     if (tmp != NULL) xmlFree(tmp);
    736 
    737     /* Write an element named "NAME_2" as child of HEADER. */
    738     tmp = ConvertInput("J\xF6rg", MY_ENCODING);
    739     rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_2", tmp);
    740     if (rc < 0) {
    741         printf("testXmlwriterDoc: Error at xmlTextWriterWriteElement\n");
    742         return;
    743     }
    744     if (tmp != NULL) xmlFree(tmp);
    745 
    746     /* Close the element named HEADER. */
    747     rc = xmlTextWriterEndElement(writer);
    748     if (rc < 0) {
    749         printf("testXmlwriterDoc: Error at xmlTextWriterEndElement\n");
    750         return;
    751     }
    752 
    753     /* Start an element named "ENTRIES" as child of ORDER. */
    754     rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRIES");
    755     if (rc < 0) {
    756         printf("testXmlwriterDoc: Error at xmlTextWriterStartElement\n");
    757         return;
    758     }
    759 
    760     /* Start an element named "ENTRY" as child of ENTRIES. */
    761     rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY");
    762     if (rc < 0) {
    763         printf("testXmlwriterDoc: Error at xmlTextWriterStartElement\n");
    764         return;
    765     }
    766 
    767     /* Write an element named "ARTICLE" as child of ENTRY. */
    768     rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE",
    769                                    BAD_CAST "<Test>");
    770     if (rc < 0) {
    771         printf("testXmlwriterDoc: Error at xmlTextWriterWriteElement\n");
    772         return;
    773     }
    774 
    775     /* Write an element named "ENTRY_NO" as child of ENTRY. */
    776     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d",
    777                                          10);
    778     if (rc < 0) {
    779         printf
    780             ("testXmlwriterDoc: Error at xmlTextWriterWriteFormatElement\n");
    781         return;
    782     }
    783 
    784     /* Close the element named ENTRY. */
    785     rc = xmlTextWriterEndElement(writer);
    786     if (rc < 0) {
    787         printf("testXmlwriterDoc: Error at xmlTextWriterEndElement\n");
    788         return;
    789     }
    790 
    791     /* Start an element named "ENTRY" as child of ENTRIES. */
    792     rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY");
    793     if (rc < 0) {
    794         printf("testXmlwriterDoc: Error at xmlTextWriterStartElement\n");
    795         return;
    796     }
    797 
    798     /* Write an element named "ARTICLE" as child of ENTRY. */
    799     rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE",
    800                                    BAD_CAST "<Test 2>");
    801     if (rc < 0) {
    802         printf("testXmlwriterDoc: Error at xmlTextWriterWriteElement\n");
    803         return;
    804     }
    805 
    806     /* Write an element named "ENTRY_NO" as child of ENTRY. */
    807     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d",
    808                                          20);
    809     if (rc < 0) {
    810         printf
    811             ("testXmlwriterDoc: Error at xmlTextWriterWriteFormatElement\n");
    812         return;
    813     }
    814 
    815     /* Close the element named ENTRY. */
    816     rc = xmlTextWriterEndElement(writer);
    817     if (rc < 0) {
    818         printf("testXmlwriterDoc: Error at xmlTextWriterEndElement\n");
    819         return;
    820     }
    821 
    822     /* Close the element named ENTRIES. */
    823     rc = xmlTextWriterEndElement(writer);
    824     if (rc < 0) {
    825         printf("testXmlwriterDoc: Error at xmlTextWriterEndElement\n");
    826         return;
    827     }
    828 
    829     /* Start an element named "FOOTER" as child of ORDER. */
    830     rc = xmlTextWriterStartElement(writer, BAD_CAST "FOOTER");
    831     if (rc < 0) {
    832         printf("testXmlwriterDoc: Error at xmlTextWriterStartElement\n");
    833         return;
    834     }
    835 
    836     /* Write an element named "TEXT" as child of FOOTER. */
    837     rc = xmlTextWriterWriteElement(writer, BAD_CAST "TEXT",
    838                                    BAD_CAST "This is a text.");
    839     if (rc < 0) {
    840         printf("testXmlwriterDoc: Error at xmlTextWriterWriteElement\n");
    841         return;
    842     }
    843 
    844     /* Close the element named FOOTER. */
    845     rc = xmlTextWriterEndElement(writer);
    846     if (rc < 0) {
    847         printf("testXmlwriterDoc: Error at xmlTextWriterEndElement\n");
    848         return;
    849     }
    850 
    851     /* Here we could close the elements ORDER and EXAMPLE using the
    852      * function xmlTextWriterEndElement, but since we do not want to
    853      * write any other elements, we simply call xmlTextWriterEndDocument,
    854      * which will do all the work. */
    855     rc = xmlTextWriterEndDocument(writer);
    856     if (rc < 0) {
    857         printf("testXmlwriterDoc: Error at xmlTextWriterEndDocument\n");
    858         return;
    859     }
    860 
    861     xmlFreeTextWriter(writer);
    862 
    863     xmlSaveFileEnc(file, doc, MY_ENCODING);
    864 
    865     xmlFreeDoc(doc);
    866 }
    867 
    868 /**
    869  * testXmlwriterTree:
    870  * @file: the output file
    871  *
    872  * test the xmlWriter interface when writing to a subtree
    873  */
    874 void
    875 testXmlwriterTree(const char *file)
    876 {
    877     int rc;
    878     xmlTextWriterPtr writer;
    879     xmlDocPtr doc;
    880     xmlNodePtr node;
    881     xmlChar *tmp;
    882 
    883     /* Create a new XML DOM tree, to which the XML document will be
    884      * written */
    885     doc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
    886     if (doc == NULL) {
    887         printf
    888             ("testXmlwriterTree: Error creating the xml document tree\n");
    889         return;
    890     }
    891 
    892     /* Create a new XML node, to which the XML document will be
    893      * appended */
    894     node = xmlNewDocNode(doc, NULL, BAD_CAST "EXAMPLE", NULL);
    895     if (node == NULL) {
    896         printf("testXmlwriterTree: Error creating the xml node\n");
    897         return;
    898     }
    899 
    900     /* Make ELEMENT the root node of the tree */
    901     xmlDocSetRootElement(doc, node);
    902 
    903     /* Create a new XmlWriter for DOM tree, with no compression. */
    904     writer = xmlNewTextWriterTree(doc, node, 0);
    905     if (writer == NULL) {
    906         printf("testXmlwriterTree: Error creating the xml writer\n");
    907         return;
    908     }
    909 
    910     /* Start the document with the xml default for the version,
    911      * encoding ISO 8859-1 and the default for the standalone
    912      * declaration. */
    913     rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL);
    914     if (rc < 0) {
    915         printf("testXmlwriterTree: Error at xmlTextWriterStartDocument\n");
    916         return;
    917     }
    918 
    919     /* Write a comment as child of EXAMPLE.
    920      * Please observe, that the input to the xmlTextWriter functions
    921      * HAS to be in UTF-8, even if the output XML is encoded
    922      * in iso-8859-1 */
    923     tmp = ConvertInput("This is a comment with special chars: <\xE4\xF6\xFC>",
    924                        MY_ENCODING);
    925     rc = xmlTextWriterWriteComment(writer, tmp);
    926     if (rc < 0) {
    927         printf("testXmlwriterTree: Error at xmlTextWriterWriteComment\n");
    928         return;
    929     }
    930     if (tmp != NULL) xmlFree(tmp);
    931 
    932     /* Start an element named "ORDER" as child of EXAMPLE. */
    933     rc = xmlTextWriterStartElement(writer, BAD_CAST "ORDER");
    934     if (rc < 0) {
    935         printf("testXmlwriterTree: Error at xmlTextWriterStartElement\n");
    936         return;
    937     }
    938 
    939     /* Add an attribute with name "version" and value "1.0" to ORDER. */
    940     rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "version",
    941                                      BAD_CAST "1.0");
    942     if (rc < 0) {
    943         printf
    944             ("testXmlwriterTree: Error at xmlTextWriterWriteAttribute\n");
    945         return;
    946     }
    947 
    948     /* Add an attribute with name "xml:lang" and value "de" to ORDER. */
    949     rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang",
    950                                      BAD_CAST "de");
    951     if (rc < 0) {
    952         printf
    953             ("testXmlwriterTree: Error at xmlTextWriterWriteAttribute\n");
    954         return;
    955     }
    956 
    957     /* Write a comment as child of ORDER */
    958     tmp = ConvertInput("<\xE4\xF6\xFC>", MY_ENCODING);
    959     rc = xmlTextWriterWriteFormatComment(writer,
    960 			 "This is another comment with special chars: %s",
    961 					  tmp);
    962     if (rc < 0) {
    963         printf
    964             ("testXmlwriterTree: Error at xmlTextWriterWriteFormatComment\n");
    965         return;
    966     }
    967     if (tmp != NULL) xmlFree(tmp);
    968 
    969     /* Start an element named "HEADER" as child of ORDER. */
    970     rc = xmlTextWriterStartElement(writer, BAD_CAST "HEADER");
    971     if (rc < 0) {
    972         printf("testXmlwriterTree: Error at xmlTextWriterStartElement\n");
    973         return;
    974     }
    975 
    976     /* Write an element named "X_ORDER_ID" as child of HEADER. */
    977     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "X_ORDER_ID",
    978                                          "%010d", 53535);
    979     if (rc < 0) {
    980         printf
    981             ("testXmlwriterTree: Error at xmlTextWriterWriteFormatElement\n");
    982         return;
    983     }
    984 
    985     /* Write an element named "CUSTOMER_ID" as child of HEADER. */
    986     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "CUSTOMER_ID",
    987                                          "%d", 1010);
    988     if (rc < 0) {
    989         printf
    990             ("testXmlwriterTree: Error at xmlTextWriterWriteFormatElement\n");
    991         return;
    992     }
    993 
    994     /* Write an element named "NAME_1" as child of HEADER. */
    995     tmp = ConvertInput("M\xFCller", MY_ENCODING);
    996     rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_1", tmp);
    997     if (rc < 0) {
    998         printf("testXmlwriterTree: Error at xmlTextWriterWriteElement\n");
    999         return;
   1000     }
   1001     if (tmp != NULL) xmlFree(tmp);
   1002 
   1003     /* Write an element named "NAME_2" as child of HEADER. */
   1004     tmp = ConvertInput("J\xF6rg", MY_ENCODING);
   1005     rc = xmlTextWriterWriteElement(writer, BAD_CAST "NAME_2", tmp);
   1006     if (rc < 0) {
   1007         printf("testXmlwriterTree: Error at xmlTextWriterWriteElement\n");
   1008         return;
   1009     }
   1010     if (tmp != NULL) xmlFree(tmp);
   1011 
   1012     /* Close the element named HEADER. */
   1013     rc = xmlTextWriterEndElement(writer);
   1014     if (rc < 0) {
   1015         printf("testXmlwriterTree: Error at xmlTextWriterEndElement\n");
   1016         return;
   1017     }
   1018 
   1019     /* Start an element named "ENTRIES" as child of ORDER. */
   1020     rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRIES");
   1021     if (rc < 0) {
   1022         printf("testXmlwriterTree: Error at xmlTextWriterStartElement\n");
   1023         return;
   1024     }
   1025 
   1026     /* Start an element named "ENTRY" as child of ENTRIES. */
   1027     rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY");
   1028     if (rc < 0) {
   1029         printf("testXmlwriterTree: Error at xmlTextWriterStartElement\n");
   1030         return;
   1031     }
   1032 
   1033     /* Write an element named "ARTICLE" as child of ENTRY. */
   1034     rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE",
   1035                                    BAD_CAST "<Test>");
   1036     if (rc < 0) {
   1037         printf("testXmlwriterTree: Error at xmlTextWriterWriteElement\n");
   1038         return;
   1039     }
   1040 
   1041     /* Write an element named "ENTRY_NO" as child of ENTRY. */
   1042     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d",
   1043                                          10);
   1044     if (rc < 0) {
   1045         printf
   1046             ("testXmlwriterTree: Error at xmlTextWriterWriteFormatElement\n");
   1047         return;
   1048     }
   1049 
   1050     /* Close the element named ENTRY. */
   1051     rc = xmlTextWriterEndElement(writer);
   1052     if (rc < 0) {
   1053         printf("testXmlwriterTree: Error at xmlTextWriterEndElement\n");
   1054         return;
   1055     }
   1056 
   1057     /* Start an element named "ENTRY" as child of ENTRIES. */
   1058     rc = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY");
   1059     if (rc < 0) {
   1060         printf("testXmlwriterTree: Error at xmlTextWriterStartElement\n");
   1061         return;
   1062     }
   1063 
   1064     /* Write an element named "ARTICLE" as child of ENTRY. */
   1065     rc = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE",
   1066                                    BAD_CAST "<Test 2>");
   1067     if (rc < 0) {
   1068         printf("testXmlwriterTree: Error at xmlTextWriterWriteElement\n");
   1069         return;
   1070     }
   1071 
   1072     /* Write an element named "ENTRY_NO" as child of ENTRY. */
   1073     rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ENTRY_NO", "%d",
   1074                                          20);
   1075     if (rc < 0) {
   1076         printf
   1077             ("testXmlwriterTree: Error at xmlTextWriterWriteFormatElement\n");
   1078         return;
   1079     }
   1080 
   1081     /* Close the element named ENTRY. */
   1082     rc = xmlTextWriterEndElement(writer);
   1083     if (rc < 0) {
   1084         printf("testXmlwriterTree: Error at xmlTextWriterEndElement\n");
   1085         return;
   1086     }
   1087 
   1088     /* Close the element named ENTRIES. */
   1089     rc = xmlTextWriterEndElement(writer);
   1090     if (rc < 0) {
   1091         printf("testXmlwriterTree: Error at xmlTextWriterEndElement\n");
   1092         return;
   1093     }
   1094 
   1095     /* Start an element named "FOOTER" as child of ORDER. */
   1096     rc = xmlTextWriterStartElement(writer, BAD_CAST "FOOTER");
   1097     if (rc < 0) {
   1098         printf("testXmlwriterTree: Error at xmlTextWriterStartElement\n");
   1099         return;
   1100     }
   1101 
   1102     /* Write an element named "TEXT" as child of FOOTER. */
   1103     rc = xmlTextWriterWriteElement(writer, BAD_CAST "TEXT",
   1104                                    BAD_CAST "This is a text.");
   1105     if (rc < 0) {
   1106         printf("testXmlwriterTree: Error at xmlTextWriterWriteElement\n");
   1107         return;
   1108     }
   1109 
   1110     /* Close the element named FOOTER. */
   1111     rc = xmlTextWriterEndElement(writer);
   1112     if (rc < 0) {
   1113         printf("testXmlwriterTree: Error at xmlTextWriterEndElement\n");
   1114         return;
   1115     }
   1116 
   1117     /* Here we could close the elements ORDER and EXAMPLE using the
   1118      * function xmlTextWriterEndElement, but since we do not want to
   1119      * write any other elements, we simply call xmlTextWriterEndDocument,
   1120      * which will do all the work. */
   1121     rc = xmlTextWriterEndDocument(writer);
   1122     if (rc < 0) {
   1123         printf("testXmlwriterTree: Error at xmlTextWriterEndDocument\n");
   1124         return;
   1125     }
   1126 
   1127     xmlFreeTextWriter(writer);
   1128 
   1129     xmlSaveFileEnc(file, doc, MY_ENCODING);
   1130 
   1131     xmlFreeDoc(doc);
   1132 }
   1133 
   1134 /**
   1135  * ConvertInput:
   1136  * @in: string in a given encoding
   1137  * @encoding: the encoding used
   1138  *
   1139  * Converts @in into UTF-8 for processing with libxml2 APIs
   1140  *
   1141  * Returns the converted UTF-8 string, or NULL in case of error.
   1142  */
   1143 xmlChar *
   1144 ConvertInput(const char *in, const char *encoding)
   1145 {
   1146     xmlChar *out;
   1147     int ret;
   1148     int size;
   1149     int out_size;
   1150     int temp;
   1151     xmlCharEncodingHandlerPtr handler;
   1152 
   1153     if (in == 0)
   1154         return 0;
   1155 
   1156     handler = xmlFindCharEncodingHandler(encoding);
   1157 
   1158     if (!handler) {
   1159         printf("ConvertInput: no encoding handler found for '%s'\n",
   1160                encoding ? encoding : "");
   1161         return 0;
   1162     }
   1163 
   1164     size = (int) strlen(in) + 1;
   1165     out_size = size * 2 - 1;
   1166     out = (unsigned char *) xmlMalloc((size_t) out_size);
   1167 
   1168     if (out != 0) {
   1169         temp = size - 1;
   1170         ret = handler->input(out, &out_size, (const xmlChar *) in, &temp);
   1171         if ((ret < 0) || (temp - size + 1)) {
   1172             if (ret < 0) {
   1173                 printf("ConvertInput: conversion wasn't successful.\n");
   1174             } else {
   1175                 printf
   1176                     ("ConvertInput: conversion wasn't successful. converted: %i octets.\n",
   1177                      temp);
   1178             }
   1179 
   1180             xmlFree(out);
   1181             out = 0;
   1182         } else {
   1183             out = (unsigned char *) xmlRealloc(out, out_size + 1);
   1184             out[out_size] = 0;  /*null terminating out */
   1185         }
   1186     } else {
   1187         printf("ConvertInput: no mem\n");
   1188     }
   1189 
   1190     return out;
   1191 }
   1192 
   1193 #else
   1194 int main(void) {
   1195     fprintf(stderr, "Writer or output support not compiled in\n");
   1196     exit(1);
   1197 }
   1198 #endif
   1199