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 23void testXmlwriterFilename(const char *uri); 24void testXmlwriterMemory(const char *file); 25void testXmlwriterDoc(const char *file); 26void testXmlwriterTree(const char *file); 27xmlChar *ConvertInput(const char *in, const char *encoding); 28 29int 30main(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 */ 68void 69testXmlwriterFilename(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: <���>", 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("<���>", 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�ller", 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�rg", 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 */ 336void 337testXmlwriterMemory(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: <���>", 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("<���>", 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�ller", 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�rg", 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 */ 622void 623testXmlwriterDoc(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: <���>", 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("<���>", 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�ller", 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�rg", 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 */ 874void 875testXmlwriterTree(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: <���>", 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("<���>", 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�ller", 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�rg", 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 */ 1143xmlChar * 1144ConvertInput(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 1194int main(void) { 1195 fprintf(stderr, "Writer or output support not compiled in\n"); 1196 exit(1); 1197} 1198#endif 1199