Annotation of XML/tree.c, revision 1.14

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.14    ! daniel      6:  * $Id: tree.c,v 1.13 1998/07/29 04:43:17 daniel 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.14    ! daniel    260:  * Creation of a new node contening a comment.
        !           261:  */
        !           262: xmlNodePtr xmlNewComment(CHAR *content) {
        !           263:     xmlNodePtr cur;
        !           264: 
        !           265:     /*
        !           266:      * Allocate a new node and fill the fields.
        !           267:      */
        !           268:     cur = (xmlNodePtr) malloc(sizeof(xmlNode));
        !           269:     if (cur == NULL) {
        !           270:         fprintf(stderr, "xmlNewNode : malloc failed\n");
        !           271:        return(NULL);
        !           272:     }
        !           273: 
        !           274:     cur->parent = NULL; 
        !           275:     cur->next = NULL; 
        !           276:     cur->childs = NULL; 
        !           277:     cur->properties = NULL; 
        !           278:     cur->type = XML_TYPE_COMMENT;
        !           279:     cur->name = xmlStrdup(xmlStringText);;
        !           280:     cur->dtd = NULL;
        !           281:     if (content != NULL)
        !           282:        cur->content = xmlStrdup(content);
        !           283:     else 
        !           284:        cur->content = NULL;
        !           285:     return(cur);
        !           286: }
        !           287: 
        !           288: /*
1.1       veillard  289:  * Creation of a new child element, added at the end.
                    290:  */
                    291: xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlDtdPtr dtd,
1.7       veillard  292:                        const CHAR *name, CHAR *content) {
1.1       veillard  293:     xmlNodePtr cur, prev;
                    294: 
                    295:     if (parent == NULL) {
                    296:         fprintf(stderr, "xmlNewChild : parent == NULL\n");
                    297:        return(NULL);
                    298:     }
                    299: 
                    300:     if (name == NULL) {
                    301:         fprintf(stderr, "xmlNewChild : name == NULL\n");
                    302:        return(NULL);
                    303:     }
                    304: 
                    305:     /*
                    306:      * Allocate a new node
                    307:      */
                    308:     if (dtd == NULL)
                    309:        cur = xmlNewNode(parent->dtd, name, content);
                    310:     else
                    311:        cur = xmlNewNode(dtd, name, content);
                    312:     if (cur == NULL) return(NULL);
                    313: 
                    314:     /*
                    315:      * add the new element at the end of the childs list.
                    316:      */
                    317:     cur->parent = parent;
                    318:     if (parent->childs == NULL) {
                    319:         parent->childs = cur;
                    320:     } else {
                    321:         prev = parent->childs;
                    322:        while (prev->next != NULL) prev = prev->next;
                    323:        prev->next = cur;
                    324:     }
                    325: 
                    326:     return(cur);
                    327: }
                    328: 
                    329: /*
1.2       veillard  330:  * Add a new child element, added at the end.
                    331:  */
                    332: xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
                    333:     xmlNodePtr prev;
                    334: 
                    335:     if (parent == NULL) {
                    336:         fprintf(stderr, "xmladdChild : parent == NULL\n");
                    337:        return(NULL);
                    338:     }
                    339: 
                    340:     if (cur == NULL) {
                    341:         fprintf(stderr, "xmladdChild : child == NULL\n");
                    342:        return(NULL);
                    343:     }
                    344: 
                    345:     /*
                    346:      * add the new element at the end of the childs list.
                    347:      */
                    348:     cur->parent = parent;
                    349:     if (parent->childs == NULL) {
                    350:         parent->childs = cur;
                    351:     } else {
                    352:         prev = parent->childs;
                    353:        while (prev->next != NULL) prev = prev->next;
                    354:        prev->next = cur;
                    355:     }
                    356: 
                    357:     return(cur);
                    358: }
                    359: 
                    360: /*
1.1       veillard  361:  * Freeing a node list : Free a node and all its siblings,
                    362:  *                       this is a recursive behaviour, all the childs
                    363:  *                       are freed too.
                    364:  */
                    365: void xmlFreeNodeList(xmlNodePtr cur) {
                    366:     xmlNodePtr next;
                    367:     if (cur == NULL) {
                    368:         fprintf(stderr, "xmlFreeNodeList : node == NULL\n");
                    369:        return;
                    370:     }
                    371:     while (cur != NULL) {
                    372:         next = cur->next;
                    373:         xmlFreeNode(cur);
                    374:        cur = next;
                    375:     }
                    376: }
                    377: 
                    378: /*
                    379:  * Freeing a node : this is a recursive behaviour, all the childs
                    380:  *                  are freed too.
                    381:  */
                    382: void xmlFreeNode(xmlNodePtr cur) {
                    383:     if (cur == NULL) {
                    384:         fprintf(stderr, "xmlFreeNode : node == NULL\n");
                    385:        return;
                    386:     }
                    387:     if (cur->properties != NULL) xmlFreePropList(cur->properties);
                    388:     if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
                    389:     if (cur->content != NULL) free(cur->content);
1.7       veillard  390:     if (cur->name != NULL) free((char *) cur->name);
1.1       veillard  391:     memset(cur, -1, sizeof(xmlNode));
                    392:     free(cur);
                    393: }
                    394: 
                    395: /************************************************************************
                    396:  *                                                                     *
                    397:  *             Content access functions                                *
                    398:  *                                                                     *
                    399:  ************************************************************************/
                    400:  
                    401: /*
                    402:  * Changing the content of a node.
                    403:  */
1.7       veillard  404: void xmlNodeSetContent(xmlNodePtr cur, CHAR *content) {
1.1       veillard  405:     if (cur == NULL) {
                    406:         fprintf(stderr, "xmlNodeSetContent : node == NULL\n");
                    407:        return;
                    408:     }
                    409:     if (cur->content != NULL) free(cur->content);
                    410:     if (content != NULL)
1.7       veillard  411:        cur->content = xmlStrdup(content);
1.1       veillard  412:     else 
                    413:        cur->content = NULL;
                    414: }
                    415: 
1.3       veillard  416: /*
                    417:  * Search a Dtd registered under a given name space for a document.
                    418:  */
1.7       veillard  419: xmlDtdPtr xmlSearchDtd(xmlDocPtr doc, CHAR *nameSpace) {
1.3       veillard  420:     xmlDtdPtr cur;
                    421: 
                    422:     if ((doc == NULL) || (nameSpace == NULL)) return(NULL);
                    423: 
                    424:     cur = doc->dtds;
                    425:     while (cur != NULL) {
1.7       veillard  426:         if ((cur->AS != NULL) && (!xmlStrcmp(cur->AS, nameSpace)))
1.3       veillard  427:            return(cur);
                    428:        cur = cur->next;
                    429:     }
                    430:     return(NULL);
                    431: }
                    432: 
1.9       veillard  433: /*
                    434:  * Reading the content of a given property.
                    435:  */
                    436: const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name) {
                    437:     xmlPropPtr prop = node->properties;
                    438: 
                    439:     while (prop != NULL) {
                    440:         if (!xmlStrcmp(prop->name, name)) return(prop->value);
                    441:        prop = prop->next;
                    442:     }
1.10      veillard  443:     return(NULL);
1.13      daniel    444: }
                    445: 
                    446: /*
                    447:  * Setting the content of a given property.
                    448:  */
                    449: xmlPropPtr xmlSetProp(xmlNodePtr node, const CHAR *name, const CHAR *value) {
                    450:     xmlPropPtr prop = node->properties;
                    451: 
                    452:     while (prop != NULL) {
                    453:         if (!xmlStrcmp(prop->name, name)) {
                    454:            if (prop->value != NULL) 
                    455:                free((char *) prop->value);
                    456:            prop->value = NULL;
                    457:            if (value != NULL)
                    458:                prop->value = xmlStrdup(value);
                    459:            return(prop);
                    460:        }
                    461:        prop = prop->next;
                    462:     }
                    463:     prop = xmlNewProp(node, name, value);
                    464:     return(prop);
1.9       veillard  465: }
                    466: 
1.1       veillard  467: /************************************************************************
                    468:  *                                                                     *
1.8       veillard  469:  *                     Output : to a FILE or in memory                 *
1.1       veillard  470:  *                                                                     *
                    471:  ************************************************************************/
                    472: 
                    473: /*
1.8       veillard  474:  * routine which manage and grows an output buffer. One can write
                    475:  * standard char array's (8 bits char) or CHAR's arrays.
                    476:  */
                    477: static CHAR *buffer = NULL;
                    478: static int buffer_index = 0;
                    479: static int buffer_size = 0;
                    480: 
                    481: static void xmlBufferWriteCHAR(const CHAR *string) {
                    482:     const CHAR *cur;
                    483: 
                    484:     if (buffer == NULL) {
                    485:         buffer_size = 50000;
                    486:         buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
                    487:        if (buffer == NULL) {
                    488:            fprintf(stderr, "xmlBufferWrite : out of memory!\n");
                    489:            exit(1);
                    490:        }
                    491:     }
                    492:     
                    493:     if (string == NULL) return;
                    494:     for (cur = string;*cur != 0;cur++) {
                    495:         if (buffer_index  + 10 >= buffer_size) {
                    496:            buffer_size *= 2;
                    497:            buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
                    498:            if (buffer == NULL) {
                    499:                fprintf(stderr, "xmlBufferWrite : out of memory!\n");
                    500:                exit(1);
                    501:            }
                    502:        }
                    503:         buffer[buffer_index++] = *cur;
                    504:     }
                    505:     buffer[buffer_index] = 0;
                    506: }
                    507: 
                    508: static void xmlBufferWriteChar(const char *string) {
                    509:     const CHAR *cur;
                    510: 
                    511:     if (buffer == NULL) {
                    512:         buffer_size = 50000;
                    513:         buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
                    514:        if (buffer == NULL) {
                    515:            fprintf(stderr, "xmlBufferWrite : out of memory!\n");
                    516:            exit(1);
                    517:        }
                    518:     }
                    519:     
                    520:     if (string == NULL) return;
                    521:     for (cur = string;*cur != 0;cur++) {
                    522:         if (buffer_index  + 10 >= buffer_size) {
                    523:            buffer_size *= 2;
                    524:            buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
                    525:            if (buffer == NULL) {
                    526:                fprintf(stderr, "xmlBufferWrite : out of memory!\n");
                    527:                exit(1);
                    528:            }
                    529:        }
                    530:         buffer[buffer_index++] = *cur;
                    531:     }
                    532:     buffer[buffer_index] = 0;
                    533: }
                    534: 
                    535: /*
1.1       veillard  536:  * Dump a DTD to the given FD
                    537:  */
1.8       veillard  538: static void xmlDtdDump(xmlDtdPtr cur) {
1.1       veillard  539:     if (cur == NULL) {
                    540:         fprintf(stderr, "xmlDtdDump : DTD == NULL\n");
                    541:        return;
                    542:     }
1.12      daniel    543:     if (oldXMLWDcompatibility) {
                    544:        xmlBufferWriteChar("<?namespace");
                    545:        if (cur->href != NULL) {
                    546:            xmlBufferWriteChar(" href=\"");
                    547:            xmlBufferWriteCHAR(cur->href);
                    548:            xmlBufferWriteChar("\"");
                    549:        }
                    550:        if (cur->AS != NULL) {
                    551:            xmlBufferWriteChar(" AS=\"");
                    552:            xmlBufferWriteCHAR(cur->AS);
                    553:            xmlBufferWriteChar("\"");
                    554:        }
                    555:        xmlBufferWriteChar("?>\n");
                    556:     } else {
                    557:        xmlBufferWriteChar("<?xml:namespace");
                    558:        if (cur->href != NULL) {
                    559:            xmlBufferWriteChar(" ns=\"");
                    560:            xmlBufferWriteCHAR(cur->href);
                    561:            xmlBufferWriteChar("\"");
                    562:        }
                    563:        if (cur->AS != NULL) {
                    564:            xmlBufferWriteChar(" prefix=\"");
                    565:            xmlBufferWriteCHAR(cur->AS);
                    566:            xmlBufferWriteChar("\"");
                    567:        }
                    568:        xmlBufferWriteChar("?>\n");
1.8       veillard  569:     }
1.1       veillard  570: }
                    571: 
                    572: /*
1.8       veillard  573:  * Dump an XML property to the given FD
1.1       veillard  574:  */
                    575: 
1.8       veillard  576: static void xmlPropDump(xmlDocPtr doc, xmlPropPtr cur) {
1.1       veillard  577:     if (cur == NULL) {
1.8       veillard  578:         fprintf(stderr, "xmlPropDump : property == NULL\n");
1.1       veillard  579:        return;
                    580:     }
1.8       veillard  581:     xmlBufferWriteChar(" ");
                    582:     xmlBufferWriteCHAR(cur->name);
                    583:     if (cur->value) {
                    584:        xmlBufferWriteChar("=\"");
                    585:        xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->value));
                    586:        xmlBufferWriteChar("\"");
1.3       veillard  587:     }
1.8       veillard  588: }
                    589: 
                    590: /*
                    591:  * Dump an XML property list to the given FD
                    592:  */
1.1       veillard  593: 
1.8       veillard  594: static void xmlPropListDump(xmlDocPtr doc, xmlPropPtr cur) {
                    595:     if (cur == NULL) {
                    596:         fprintf(stderr, "xmlPropListDump : property == NULL\n");
1.1       veillard  597:        return;
                    598:     }
1.8       veillard  599:     while (cur != NULL) {
                    600:         xmlPropDump(doc, cur);
                    601:        cur = cur->next;
1.1       veillard  602:     }
                    603: }
                    604: 
                    605: /*
1.8       veillard  606:  * Dump an XML node list to the given FD
1.1       veillard  607:  */
                    608: 
1.8       veillard  609: static void xmlNodeDump(xmlDocPtr doc, xmlNodePtr cur, int level);
                    610: static void xmlNodeListDump(xmlDocPtr doc, xmlNodePtr cur, int level) {
1.1       veillard  611:     if (cur == NULL) {
1.8       veillard  612:         fprintf(stderr, "xmlNodeListDump : node == NULL\n");
1.1       veillard  613:        return;
                    614:     }
1.8       veillard  615:     while (cur != NULL) {
                    616:         xmlNodeDump(doc, cur, level);
                    617:        cur = cur->next;
1.3       veillard  618:     }
1.1       veillard  619: }
                    620: 
                    621: /*
1.8       veillard  622:  * Dump an XML node to the given FD
1.1       veillard  623:  */
                    624: 
1.8       veillard  625: static void xmlNodeDump(xmlDocPtr doc, xmlNodePtr cur, int level) {
                    626:     int i;
                    627: 
1.1       veillard  628:     if (cur == NULL) {
1.8       veillard  629:         fprintf(stderr, "xmlNodeDump : node == NULL\n");
                    630:        return;
                    631:     }
                    632:     if (cur->type == XML_TYPE_TEXT) {
                    633:        if (cur->content != NULL)
                    634:            xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->content));
1.14    ! daniel    635:        return;
        !           636:     }
        !           637:     if (cur->type == XML_TYPE_COMMENT) {
        !           638:        if (cur->content != NULL) {
        !           639:            xmlBufferWriteChar("<!--");
        !           640:            xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->content));
        !           641:            xmlBufferWriteChar("-->");
        !           642:        }
1.8       veillard  643:        return;
                    644:     }
                    645:     for (i = 0;i < level;i++)
                    646:         xmlBufferWriteChar("  ");
                    647: 
                    648:     xmlBufferWriteChar("<");
                    649:     if ((cur->dtd != NULL) && (cur->dtd->AS != NULL)) {
                    650:         xmlBufferWriteCHAR(cur->dtd->AS);
                    651:        xmlBufferWriteChar(":");
                    652:     }
                    653: 
                    654:     xmlBufferWriteCHAR(cur->name);
                    655:     if (cur->properties != NULL)
                    656:         xmlPropListDump(doc, cur->properties);
                    657: 
                    658:     if ((cur->content == NULL) && (cur->childs == NULL)) {
                    659:         xmlBufferWriteChar("/>\n");
1.1       veillard  660:        return;
                    661:     }
1.8       veillard  662:     xmlBufferWriteChar(">");
                    663:     if (cur->content != NULL)
                    664:        xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->content));
                    665:     if (cur->childs != NULL) {
                    666:        xmlBufferWriteChar("\n");
                    667:        xmlNodeListDump(doc, cur->childs, level + 1);
                    668:        for (i = 0;i < level;i++)
                    669:            xmlBufferWriteChar("  ");
                    670:     }
                    671:     xmlBufferWriteChar("</");
                    672:     if ((cur->dtd != NULL) && (cur->dtd->AS != NULL)) {
                    673:         xmlBufferWriteCHAR(cur->dtd->AS);
                    674:        xmlBufferWriteChar(":");
1.1       veillard  675:     }
1.8       veillard  676: 
                    677:     xmlBufferWriteCHAR(cur->name);
                    678:     xmlBufferWriteChar(">\n");
1.1       veillard  679: }
                    680: 
                    681: /*
                    682:  * Dump an XML DTD list to the given FD
                    683:  */
                    684: 
1.8       veillard  685: static void xmlDtdListDump(xmlDtdPtr cur) {
1.1       veillard  686:     if (cur == NULL) {
                    687:         fprintf(stderr, "xmlDtdListDump : DTD == NULL\n");
                    688:        return;
                    689:     }
                    690:     while (cur != NULL) {
1.8       veillard  691:         xmlDtdDump(cur);
1.1       veillard  692:        cur = cur->next;
                    693:     }
                    694: }
                    695: 
                    696: /*
1.8       veillard  697:  * Dump an XML document to memory.
1.1       veillard  698:  */
                    699: 
1.8       veillard  700: void xmlDocDumpMemory(xmlDocPtr cur, CHAR**mem, int *size) {
1.1       veillard  701:     if (cur == NULL) {
1.8       veillard  702:         fprintf(stderr, "xmlDocDump : document == NULL\n");
                    703:        *mem = NULL;
                    704:        *size = 0;
1.1       veillard  705:        return;
                    706:     }
1.8       veillard  707:     buffer_index = 0;
1.12      daniel    708:     if (oldXMLWDcompatibility)
                    709:        xmlBufferWriteChar("<?XML version=\"");
                    710:     else 
                    711:        xmlBufferWriteChar("<?xml version=\"");
1.8       veillard  712:     xmlBufferWriteCHAR(cur->version);
                    713:     xmlBufferWriteChar("\"?>\n");
                    714:     if (cur->dtds != NULL)
                    715:         xmlDtdListDump(cur->dtds);
                    716:     if (cur->root != NULL)
                    717:         xmlNodeDump(cur, cur->root, 0);
                    718: 
                    719:     *mem = buffer;
                    720:     *size = buffer_index;
1.1       veillard  721: }
                    722: 
                    723: /*
                    724:  * Dump an XML document to the given FD
                    725:  */
                    726: 
                    727: void xmlDocDump(FILE *f, xmlDocPtr cur) {
                    728:     if (cur == NULL) {
                    729:         fprintf(stderr, "xmlDocDump : document == NULL\n");
                    730:        return;
                    731:     }
1.8       veillard  732:     buffer_index = 0;
1.12      daniel    733:     if (oldXMLWDcompatibility)
                    734:        xmlBufferWriteChar("<?XML version=\"");
                    735:     else 
                    736:        xmlBufferWriteChar("<?xml version=\"");
1.8       veillard  737:     xmlBufferWriteCHAR(cur->version);
                    738:     xmlBufferWriteChar("\"?>\n");
1.1       veillard  739:     if (cur->dtds != NULL)
1.8       veillard  740:         xmlDtdListDump(cur->dtds);
1.1       veillard  741:     if (cur->root != NULL)
1.8       veillard  742:         xmlNodeDump(cur, cur->root, 0);
                    743: 
                    744:     fwrite(buffer, sizeof(CHAR), buffer_index, f);
1.1       veillard  745: }
                    746: 
                    747: /************************************************************************
                    748:  *                                                                     *
                    749:  *                             Debug                                   *
                    750:  *                                                                     *
                    751:  ************************************************************************/
                    752: 
                    753: #ifdef DEBUG_TREE
                    754: int main(void) {
                    755:     xmlDocPtr doc;
                    756:     xmlNodePtr tree, subtree;
                    757:     xmlDtdPtr dtd1;
                    758:     xmlDtdPtr dtd2;
                    759: 
                    760:     /*
                    761:      * build a fake XML document
                    762:      */
                    763:     doc = xmlNewDoc("1.0");
                    764:     dtd1 = xmlNewDtd(doc, "http://www.ietf.org/standards/dav/", "D");
                    765:     dtd2 = xmlNewDtd(doc, "http://www.w3.com/standards/z39.50/", "Z");
                    766:     doc->root = xmlNewNode(dtd1, "multistatus", NULL);
                    767:     tree = xmlNewChild(doc->root, NULL, "response", NULL);
                    768:     subtree = xmlNewChild(tree, NULL, "prop", NULL);
                    769:     xmlNewChild(subtree, dtd2, "Authors", NULL);
                    770:     subtree = xmlNewChild(tree, NULL, "status", "HTTP/1.1 420 Method Failure");
                    771:     tree = xmlNewChild(doc->root, NULL, "response", NULL);
                    772:     subtree = xmlNewChild(tree, NULL, "prop", NULL);
                    773:     xmlNewChild(subtree, dtd2, "Copyright-Owner", NULL);
                    774:     subtree = xmlNewChild(tree, NULL, "status", "HTTP/1.1 409 Conflict");
                    775:     tree = xmlNewChild(doc->root, NULL, "responsedescription",
                    776:                        "Copyright Owner can not be deleted or altered");
                    777: 
                    778:     /*
                    779:      * print it.
                    780:      */
                    781:     xmlDocDump(stdout, doc);
                    782: 
                    783:     /*
                    784:      * free it.
                    785:      */
                    786:     xmlFreeDoc(doc);
                    787:     return(0);
                    788: }
                    789: #endif

Webmaster