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