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