Annotation of XML/tree.c, revision 1.12
1.1 veillard 1: /*
2: * tree.c : implemetation of access function for an XML tree.
1.11 veillard 3: *
4: * See Copyright for the status of this software.
5: *
1.12 ! daniel 6: * $Id: tree.c,v 1.11 1998/05/25 23:58:41 veillard Exp $
1.1 veillard 7: */
8:
9: #include <stdio.h>
10: #include <ctype.h>
11: #include <malloc.h>
1.7 veillard 12: #include <string.h> /* for memset() only ! */
1.1 veillard 13:
14: #include "tree.h"
1.6 veillard 15: #include "entities.h"
1.1 veillard 16:
1.7 veillard 17: static CHAR xmlStringText[] = { 't', 'e', 'x', 't', 0 };
1.12 ! daniel 18: int oldXMLWDcompatibility = 0;
1.7 veillard 19:
1.1 veillard 20: /************************************************************************
21: * *
22: * Allocation and deallocation of basic structures *
23: * *
24: ************************************************************************/
25:
26: /*
27: * Creation of a new DTD.
28: */
1.7 veillard 29: xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const CHAR *href, const CHAR *AS) {
1.1 veillard 30: xmlDtdPtr cur;
31:
32: /*
33: * Allocate a new DTD and fill the fields.
34: */
35: cur = (xmlDtdPtr) malloc(sizeof(xmlDtd));
36: if (cur == NULL) {
37: fprintf(stderr, "xmlNewDtd : malloc failed\n");
38: return(NULL);
39: }
40:
41: cur->next = NULL;
42: if (href != NULL)
1.7 veillard 43: cur->href = xmlStrdup(href);
1.1 veillard 44: else
45: cur->href = NULL;
46: if (AS != NULL)
1.7 veillard 47: cur->AS = xmlStrdup(AS);
1.1 veillard 48: else
49: cur->AS = NULL;
50: if (doc != NULL) {
51: cur->next = doc->dtds;
52: doc->dtds = cur;
53: }
1.3 veillard 54:
1.1 veillard 55: return(cur);
56: }
57:
58: /*
59: * Freeing a DTD
60: */
61: void xmlFreeDtd(xmlDtdPtr cur) {
62: if (cur == NULL) {
63: fprintf(stderr, "xmlFreeDtd : DTD == NULL\n");
64: return;
65: }
66: if (cur->href != NULL) free((char *) cur->href);
67: if (cur->AS != NULL) free((char *) cur->AS);
68: memset(cur, -1, sizeof(xmlDtd));
69: free(cur);
70: }
71:
72: /*
1.6 veillard 73: * Freeing a DTD list
74: */
75: void xmlFreeDtdList(xmlDtdPtr cur) {
76: xmlDtdPtr next;
77: if (cur == NULL) {
78: fprintf(stderr, "xmlFreeDtdList : dtd == NULL\n");
79: return;
80: }
81: while (cur != NULL) {
82: next = cur->next;
83: xmlFreeDtd(cur);
84: cur = next;
85: }
86: }
87:
88: /*
1.1 veillard 89: * Creation of a new document
90: */
1.7 veillard 91: xmlDocPtr xmlNewDoc(const CHAR *version) {
1.1 veillard 92: xmlDocPtr cur;
93:
94: if (version == NULL) {
95: fprintf(stderr, "xmlNewDoc : version == NULL\n");
96: return(NULL);
97: }
98:
99: /*
100: * Allocate a new document and fill the fields.
101: */
102: cur = (xmlDocPtr) malloc(sizeof(xmlDoc));
103: if (cur == NULL) {
104: fprintf(stderr, "xmlNewDoc : malloc failed\n");
105: return(NULL);
106: }
107:
1.7 veillard 108: cur->version = xmlStrdup(version);
1.1 veillard 109: cur->root = NULL;
110: cur->dtds = NULL;
111: return(cur);
112: }
113:
114: /*
115: * Freeing a document : all the tree is freed too.
116: */
117: void xmlFreeDoc(xmlDocPtr cur) {
118: if (cur == NULL) {
119: fprintf(stderr, "xmlFreeDoc : document == NULL\n");
120: return;
121: }
122: free((char *) cur->version);
123: if (cur->root != NULL) xmlFreeNode(cur->root);
1.6 veillard 124: if (cur->dtds != NULL) xmlFreeDtdList(cur->dtds);
1.1 veillard 125: memset(cur, -1, sizeof(xmlDoc));
126: free(cur);
127: }
128:
129: /*
130: * Creation of a new property element in a given DTD.
131: */
1.7 veillard 132: xmlPropPtr xmlNewProp(xmlNodePtr node, const CHAR *name, const CHAR *value) {
1.1 veillard 133: xmlPropPtr cur;
134:
135: if (name == NULL) {
136: fprintf(stderr, "xmlNewProp : name == NULL\n");
137: return(NULL);
138: }
139:
140: /*
141: * Allocate a new property and fill the fields.
142: */
143: cur = (xmlPropPtr) malloc(sizeof(xmlProp));
144: if (cur == NULL) {
145: fprintf(stderr, "xmlNewProp : malloc failed\n");
146: return(NULL);
147: }
148:
149: cur->node = node;
1.7 veillard 150: cur->name = xmlStrdup(name);
1.1 veillard 151: if (value != NULL)
1.7 veillard 152: cur->value = xmlStrdup(value);
1.1 veillard 153: else
154: cur->value = NULL;
155: if (node != NULL) {
156: cur->next = node->properties;
157: node->properties = cur;
158: } else
159: cur->next = NULL;
160: return(cur);
161: }
162:
163: /*
164: * Freeing a property list : Free a property and all its siblings,
165: * this is a recursive behaviour, all the childs
166: * are freed too.
167: */
168: void xmlFreePropList(xmlPropPtr cur) {
169: xmlPropPtr next;
170: if (cur == NULL) {
171: fprintf(stderr, "xmlFreePropList : property == NULL\n");
172: return;
173: }
174: while (cur != NULL) {
175: next = cur->next;
176: xmlFreeProp(cur);
177: cur = next;
178: }
179: }
180:
181: /*
182: * Freeing a property.
183: */
184: void xmlFreeProp(xmlPropPtr cur) {
185: if (cur == NULL) {
186: fprintf(stderr, "xmlFreeProp : property == NULL\n");
187: return;
188: }
189: if (cur->name != NULL) free((char *) cur->name);
190: if (cur->value != NULL) free((char *) cur->value);
191: memset(cur, -1, sizeof(xmlProp));
192: free(cur);
193: }
194:
195: /*
196: * Creation of a new node element in a given DTD.
1.7 veillard 197: * We assume that the "name" has already being strdup'd !
1.1 veillard 198: */
1.7 veillard 199: xmlNodePtr xmlNewNode(xmlDtdPtr dtd, const CHAR *name, CHAR *content) {
1.1 veillard 200: xmlNodePtr cur;
201:
202: if (name == NULL) {
203: fprintf(stderr, "xmlNewNode : name == NULL\n");
204: return(NULL);
205: }
206:
207: /*
208: * Allocate a new node and fill the fields.
209: */
210: cur = (xmlNodePtr) malloc(sizeof(xmlNode));
211: if (cur == NULL) {
212: fprintf(stderr, "xmlNewNode : malloc failed\n");
213: return(NULL);
214: }
215:
216: cur->parent = NULL;
217: cur->next = NULL;
218: cur->childs = NULL;
219: cur->properties = NULL;
220: cur->type = 0;
221: cur->name = name;
222: cur->dtd = dtd;
223: if (content != NULL)
1.7 veillard 224: cur->content = xmlStrdup(content);
1.1 veillard 225: else
226: cur->content = NULL;
227: return(cur);
228: }
229:
230: /*
1.3 veillard 231: * Creation of a new node contening text.
232: */
1.7 veillard 233: xmlNodePtr xmlNewText(CHAR *content) {
1.3 veillard 234: xmlNodePtr cur;
235:
236: /*
237: * Allocate a new node and fill the fields.
238: */
239: cur = (xmlNodePtr) malloc(sizeof(xmlNode));
240: if (cur == NULL) {
241: fprintf(stderr, "xmlNewNode : malloc failed\n");
242: return(NULL);
243: }
244:
245: cur->parent = NULL;
246: cur->next = NULL;
247: cur->childs = NULL;
248: cur->properties = NULL;
249: cur->type = XML_TYPE_TEXT;
1.7 veillard 250: cur->name = xmlStrdup(xmlStringText);;
1.3 veillard 251: cur->dtd = NULL;
252: if (content != NULL)
1.7 veillard 253: cur->content = xmlStrdup(content);
1.3 veillard 254: else
255: cur->content = NULL;
256: return(cur);
257: }
258:
259: /*
1.1 veillard 260: * Creation of a new child element, added at the end.
261: */
262: xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlDtdPtr dtd,
1.7 veillard 263: const CHAR *name, CHAR *content) {
1.1 veillard 264: xmlNodePtr cur, prev;
265:
266: if (parent == NULL) {
267: fprintf(stderr, "xmlNewChild : parent == NULL\n");
268: return(NULL);
269: }
270:
271: if (name == NULL) {
272: fprintf(stderr, "xmlNewChild : name == NULL\n");
273: return(NULL);
274: }
275:
276: /*
277: * Allocate a new node
278: */
279: if (dtd == NULL)
280: cur = xmlNewNode(parent->dtd, name, content);
281: else
282: cur = xmlNewNode(dtd, name, content);
283: if (cur == NULL) return(NULL);
284:
285: /*
286: * add the new element at the end of the childs list.
287: */
288: cur->parent = parent;
289: if (parent->childs == NULL) {
290: parent->childs = cur;
291: } else {
292: prev = parent->childs;
293: while (prev->next != NULL) prev = prev->next;
294: prev->next = cur;
295: }
296:
297: return(cur);
298: }
299:
300: /*
1.2 veillard 301: * Add a new child element, added at the end.
302: */
303: xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
304: xmlNodePtr prev;
305:
306: if (parent == NULL) {
307: fprintf(stderr, "xmladdChild : parent == NULL\n");
308: return(NULL);
309: }
310:
311: if (cur == NULL) {
312: fprintf(stderr, "xmladdChild : child == NULL\n");
313: return(NULL);
314: }
315:
316: /*
317: * add the new element at the end of the childs list.
318: */
319: cur->parent = parent;
320: if (parent->childs == NULL) {
321: parent->childs = cur;
322: } else {
323: prev = parent->childs;
324: while (prev->next != NULL) prev = prev->next;
325: prev->next = cur;
326: }
327:
328: return(cur);
329: }
330:
331: /*
1.1 veillard 332: * Freeing a node list : Free a node and all its siblings,
333: * this is a recursive behaviour, all the childs
334: * are freed too.
335: */
336: void xmlFreeNodeList(xmlNodePtr cur) {
337: xmlNodePtr next;
338: if (cur == NULL) {
339: fprintf(stderr, "xmlFreeNodeList : node == NULL\n");
340: return;
341: }
342: while (cur != NULL) {
343: next = cur->next;
344: xmlFreeNode(cur);
345: cur = next;
346: }
347: }
348:
349: /*
350: * Freeing a node : this is a recursive behaviour, all the childs
351: * are freed too.
352: */
353: void xmlFreeNode(xmlNodePtr cur) {
354: if (cur == NULL) {
355: fprintf(stderr, "xmlFreeNode : node == NULL\n");
356: return;
357: }
358: if (cur->properties != NULL) xmlFreePropList(cur->properties);
359: if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
360: if (cur->content != NULL) free(cur->content);
1.7 veillard 361: if (cur->name != NULL) free((char *) cur->name);
1.1 veillard 362: memset(cur, -1, sizeof(xmlNode));
363: free(cur);
364: }
365:
366: /************************************************************************
367: * *
368: * Content access functions *
369: * *
370: ************************************************************************/
371:
372: /*
373: * Changing the content of a node.
374: */
1.7 veillard 375: void xmlNodeSetContent(xmlNodePtr cur, CHAR *content) {
1.1 veillard 376: if (cur == NULL) {
377: fprintf(stderr, "xmlNodeSetContent : node == NULL\n");
378: return;
379: }
380: if (cur->content != NULL) free(cur->content);
381: if (content != NULL)
1.7 veillard 382: cur->content = xmlStrdup(content);
1.1 veillard 383: else
384: cur->content = NULL;
385: }
386:
1.3 veillard 387: /*
388: * Search a Dtd registered under a given name space for a document.
389: */
1.7 veillard 390: xmlDtdPtr xmlSearchDtd(xmlDocPtr doc, CHAR *nameSpace) {
1.3 veillard 391: xmlDtdPtr cur;
392:
393: if ((doc == NULL) || (nameSpace == NULL)) return(NULL);
394:
395: cur = doc->dtds;
396: while (cur != NULL) {
1.7 veillard 397: if ((cur->AS != NULL) && (!xmlStrcmp(cur->AS, nameSpace)))
1.3 veillard 398: return(cur);
399: cur = cur->next;
400: }
401: return(NULL);
402: }
403:
1.9 veillard 404: /*
405: * Reading the content of a given property.
406: */
407: const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name) {
408: xmlPropPtr prop = node->properties;
409:
410: while (prop != NULL) {
411: if (!xmlStrcmp(prop->name, name)) return(prop->value);
412: prop = prop->next;
413: }
1.10 veillard 414: return(NULL);
1.9 veillard 415: }
416:
1.1 veillard 417: /************************************************************************
418: * *
1.8 veillard 419: * Output : to a FILE or in memory *
1.1 veillard 420: * *
421: ************************************************************************/
422:
423: /*
1.8 veillard 424: * routine which manage and grows an output buffer. One can write
425: * standard char array's (8 bits char) or CHAR's arrays.
426: */
427: static CHAR *buffer = NULL;
428: static int buffer_index = 0;
429: static int buffer_size = 0;
430:
431: static void xmlBufferWriteCHAR(const CHAR *string) {
432: const CHAR *cur;
433:
434: if (buffer == NULL) {
435: buffer_size = 50000;
436: buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
437: if (buffer == NULL) {
438: fprintf(stderr, "xmlBufferWrite : out of memory!\n");
439: exit(1);
440: }
441: }
442:
443: if (string == NULL) return;
444: for (cur = string;*cur != 0;cur++) {
445: if (buffer_index + 10 >= buffer_size) {
446: buffer_size *= 2;
447: buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
448: if (buffer == NULL) {
449: fprintf(stderr, "xmlBufferWrite : out of memory!\n");
450: exit(1);
451: }
452: }
453: buffer[buffer_index++] = *cur;
454: }
455: buffer[buffer_index] = 0;
456: }
457:
458: static void xmlBufferWriteChar(const char *string) {
459: const CHAR *cur;
460:
461: if (buffer == NULL) {
462: buffer_size = 50000;
463: buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
464: if (buffer == NULL) {
465: fprintf(stderr, "xmlBufferWrite : out of memory!\n");
466: exit(1);
467: }
468: }
469:
470: if (string == NULL) return;
471: for (cur = string;*cur != 0;cur++) {
472: if (buffer_index + 10 >= buffer_size) {
473: buffer_size *= 2;
474: buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
475: if (buffer == NULL) {
476: fprintf(stderr, "xmlBufferWrite : out of memory!\n");
477: exit(1);
478: }
479: }
480: buffer[buffer_index++] = *cur;
481: }
482: buffer[buffer_index] = 0;
483: }
484:
485: /*
1.1 veillard 486: * Dump a DTD to the given FD
487: */
1.8 veillard 488: static void xmlDtdDump(xmlDtdPtr cur) {
1.1 veillard 489: if (cur == NULL) {
490: fprintf(stderr, "xmlDtdDump : DTD == NULL\n");
491: return;
492: }
1.12 ! daniel 493: if (oldXMLWDcompatibility) {
! 494: xmlBufferWriteChar("<?namespace");
! 495: if (cur->href != NULL) {
! 496: xmlBufferWriteChar(" href=\"");
! 497: xmlBufferWriteCHAR(cur->href);
! 498: xmlBufferWriteChar("\"");
! 499: }
! 500: if (cur->AS != NULL) {
! 501: xmlBufferWriteChar(" AS=\"");
! 502: xmlBufferWriteCHAR(cur->AS);
! 503: xmlBufferWriteChar("\"");
! 504: }
! 505: xmlBufferWriteChar("?>\n");
! 506: } else {
! 507: xmlBufferWriteChar("<?xml:namespace");
! 508: if (cur->href != NULL) {
! 509: xmlBufferWriteChar(" ns=\"");
! 510: xmlBufferWriteCHAR(cur->href);
! 511: xmlBufferWriteChar("\"");
! 512: }
! 513: if (cur->AS != NULL) {
! 514: xmlBufferWriteChar(" prefix=\"");
! 515: xmlBufferWriteCHAR(cur->AS);
! 516: xmlBufferWriteChar("\"");
! 517: }
! 518: xmlBufferWriteChar("?>\n");
1.8 veillard 519: }
1.1 veillard 520: }
521:
522: /*
1.8 veillard 523: * Dump an XML property to the given FD
1.1 veillard 524: */
525:
1.8 veillard 526: static void xmlPropDump(xmlDocPtr doc, xmlPropPtr cur) {
1.1 veillard 527: if (cur == NULL) {
1.8 veillard 528: fprintf(stderr, "xmlPropDump : property == NULL\n");
1.1 veillard 529: return;
530: }
1.8 veillard 531: xmlBufferWriteChar(" ");
532: xmlBufferWriteCHAR(cur->name);
533: if (cur->value) {
534: xmlBufferWriteChar("=\"");
535: xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->value));
536: xmlBufferWriteChar("\"");
1.3 veillard 537: }
1.8 veillard 538: }
539:
540: /*
541: * Dump an XML property list to the given FD
542: */
1.1 veillard 543:
1.8 veillard 544: static void xmlPropListDump(xmlDocPtr doc, xmlPropPtr cur) {
545: if (cur == NULL) {
546: fprintf(stderr, "xmlPropListDump : property == NULL\n");
1.1 veillard 547: return;
548: }
1.8 veillard 549: while (cur != NULL) {
550: xmlPropDump(doc, cur);
551: cur = cur->next;
1.1 veillard 552: }
553: }
554:
555: /*
1.8 veillard 556: * Dump an XML node list to the given FD
1.1 veillard 557: */
558:
1.8 veillard 559: static void xmlNodeDump(xmlDocPtr doc, xmlNodePtr cur, int level);
560: static void xmlNodeListDump(xmlDocPtr doc, xmlNodePtr cur, int level) {
1.1 veillard 561: if (cur == NULL) {
1.8 veillard 562: fprintf(stderr, "xmlNodeListDump : node == NULL\n");
1.1 veillard 563: return;
564: }
1.8 veillard 565: while (cur != NULL) {
566: xmlNodeDump(doc, cur, level);
567: cur = cur->next;
1.3 veillard 568: }
1.1 veillard 569: }
570:
571: /*
1.8 veillard 572: * Dump an XML node to the given FD
1.1 veillard 573: */
574:
1.8 veillard 575: static void xmlNodeDump(xmlDocPtr doc, xmlNodePtr cur, int level) {
576: int i;
577:
1.1 veillard 578: if (cur == NULL) {
1.8 veillard 579: fprintf(stderr, "xmlNodeDump : node == NULL\n");
580: return;
581: }
582: if (cur->type == XML_TYPE_TEXT) {
583: if (cur->content != NULL)
584: xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->content));
585: return;
586: }
587: for (i = 0;i < level;i++)
588: xmlBufferWriteChar(" ");
589:
590: xmlBufferWriteChar("<");
591: if ((cur->dtd != NULL) && (cur->dtd->AS != NULL)) {
592: xmlBufferWriteCHAR(cur->dtd->AS);
593: xmlBufferWriteChar(":");
594: }
595:
596: xmlBufferWriteCHAR(cur->name);
597: if (cur->properties != NULL)
598: xmlPropListDump(doc, cur->properties);
599:
600: if ((cur->content == NULL) && (cur->childs == NULL)) {
601: xmlBufferWriteChar("/>\n");
1.1 veillard 602: return;
603: }
1.8 veillard 604: xmlBufferWriteChar(">");
605: if (cur->content != NULL)
606: xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->content));
607: if (cur->childs != NULL) {
608: xmlBufferWriteChar("\n");
609: xmlNodeListDump(doc, cur->childs, level + 1);
610: for (i = 0;i < level;i++)
611: xmlBufferWriteChar(" ");
612: }
613: xmlBufferWriteChar("</");
614: if ((cur->dtd != NULL) && (cur->dtd->AS != NULL)) {
615: xmlBufferWriteCHAR(cur->dtd->AS);
616: xmlBufferWriteChar(":");
1.1 veillard 617: }
1.8 veillard 618:
619: xmlBufferWriteCHAR(cur->name);
620: xmlBufferWriteChar(">\n");
1.1 veillard 621: }
622:
623: /*
624: * Dump an XML DTD list to the given FD
625: */
626:
1.8 veillard 627: static void xmlDtdListDump(xmlDtdPtr cur) {
1.1 veillard 628: if (cur == NULL) {
629: fprintf(stderr, "xmlDtdListDump : DTD == NULL\n");
630: return;
631: }
632: while (cur != NULL) {
1.8 veillard 633: xmlDtdDump(cur);
1.1 veillard 634: cur = cur->next;
635: }
636: }
637:
638: /*
1.8 veillard 639: * Dump an XML document to memory.
1.1 veillard 640: */
641:
1.8 veillard 642: void xmlDocDumpMemory(xmlDocPtr cur, CHAR**mem, int *size) {
1.1 veillard 643: if (cur == NULL) {
1.8 veillard 644: fprintf(stderr, "xmlDocDump : document == NULL\n");
645: *mem = NULL;
646: *size = 0;
1.1 veillard 647: return;
648: }
1.8 veillard 649: buffer_index = 0;
1.12 ! daniel 650: if (oldXMLWDcompatibility)
! 651: xmlBufferWriteChar("<?XML version=\"");
! 652: else
! 653: xmlBufferWriteChar("<?xml version=\"");
1.8 veillard 654: xmlBufferWriteCHAR(cur->version);
655: xmlBufferWriteChar("\"?>\n");
656: if (cur->dtds != NULL)
657: xmlDtdListDump(cur->dtds);
658: if (cur->root != NULL)
659: xmlNodeDump(cur, cur->root, 0);
660:
661: *mem = buffer;
662: *size = buffer_index;
1.1 veillard 663: }
664:
665: /*
666: * Dump an XML document to the given FD
667: */
668:
669: void xmlDocDump(FILE *f, xmlDocPtr cur) {
670: if (cur == NULL) {
671: fprintf(stderr, "xmlDocDump : document == NULL\n");
672: return;
673: }
1.8 veillard 674: buffer_index = 0;
1.12 ! daniel 675: if (oldXMLWDcompatibility)
! 676: xmlBufferWriteChar("<?XML version=\"");
! 677: else
! 678: xmlBufferWriteChar("<?xml version=\"");
1.8 veillard 679: xmlBufferWriteCHAR(cur->version);
680: xmlBufferWriteChar("\"?>\n");
1.1 veillard 681: if (cur->dtds != NULL)
1.8 veillard 682: xmlDtdListDump(cur->dtds);
1.1 veillard 683: if (cur->root != NULL)
1.8 veillard 684: xmlNodeDump(cur, cur->root, 0);
685:
686: fwrite(buffer, sizeof(CHAR), buffer_index, f);
1.1 veillard 687: }
688:
689: /************************************************************************
690: * *
691: * Debug *
692: * *
693: ************************************************************************/
694:
695: #ifdef DEBUG_TREE
696: int main(void) {
697: xmlDocPtr doc;
698: xmlNodePtr tree, subtree;
699: xmlDtdPtr dtd1;
700: xmlDtdPtr dtd2;
701:
702: /*
703: * build a fake XML document
704: */
705: doc = xmlNewDoc("1.0");
706: dtd1 = xmlNewDtd(doc, "http://www.ietf.org/standards/dav/", "D");
707: dtd2 = xmlNewDtd(doc, "http://www.w3.com/standards/z39.50/", "Z");
708: doc->root = xmlNewNode(dtd1, "multistatus", NULL);
709: tree = xmlNewChild(doc->root, NULL, "response", NULL);
710: subtree = xmlNewChild(tree, NULL, "prop", NULL);
711: xmlNewChild(subtree, dtd2, "Authors", NULL);
712: subtree = xmlNewChild(tree, NULL, "status", "HTTP/1.1 420 Method Failure");
713: tree = xmlNewChild(doc->root, NULL, "response", NULL);
714: subtree = xmlNewChild(tree, NULL, "prop", NULL);
715: xmlNewChild(subtree, dtd2, "Copyright-Owner", NULL);
716: subtree = xmlNewChild(tree, NULL, "status", "HTTP/1.1 409 Conflict");
717: tree = xmlNewChild(doc->root, NULL, "responsedescription",
718: "Copyright Owner can not be deleted or altered");
719:
720: /*
721: * print it.
722: */
723: xmlDocDump(stdout, doc);
724:
725: /*
726: * free it.
727: */
728: xmlFreeDoc(doc);
729: return(0);
730: }
731: #endif
Webmaster