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