/ libxml2 / doc / examples / testWriter.c
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  
  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