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
main(void)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
testXmlwriterFilename(const char * uri)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: <���>",
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 */
336 void
testXmlwriterMemory(const char * file)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: <���>",
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 */
622 void
testXmlwriterDoc(const char * file)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: <���>",
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 */
874 void
testXmlwriterTree(const char * file)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: <���>",
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 */
1143 xmlChar *
ConvertInput(const char * in,const char * encoding)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
main(void)1194 int main(void) {
1195 fprintf(stderr, "Writer or output support not compiled in\n");
1196 exit(1);
1197 }
1198 #endif
1199