Annotation of XML/SAX.c, revision 1.34

1.1       daniel      1: /*
                      2:  * SAX.c : Default SAX handler to build a tree.
1.5       daniel      3:  *
1.7       daniel      4:  * See Copyright for the status of this software.
                      5:  *
1.5       daniel      6:  * Daniel Veillard <Daniel.Veillard@w3.org>
1.1       daniel      7:  */
                      8: 
1.32      daniel      9: 
1.1       daniel     10: #include <stdio.h>
1.5       daniel     11: #include <stdlib.h>
1.30      daniel     12: #include "xmlmemory.h"
1.1       daniel     13: #include "tree.h"
                     14: #include "parser.h"
1.10      daniel     15: #include "parserInternals.h"
                     16: #include "valid.h"
1.5       daniel     17: #include "entities.h"
1.9       daniel     18: #include "xml-error.h"
1.26      daniel     19: #include "debugXML.h"
1.1       daniel     20: 
1.15      daniel     21: /* #define DEBUG_SAX */
1.26      daniel     22: /* #define DEBUG_SAX_TREE */
1.2       daniel     23: 
1.5       daniel     24: /**
                     25:  * getPublicId:
1.16      daniel     26:  * @ctx: the user data (XML parser context)
1.5       daniel     27:  *
1.1       daniel     28:  * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
1.5       daniel     29:  *
1.34    ! daniel     30:  * Returns a xmlChar *
1.1       daniel     31:  */
1.34    ! daniel     32: const xmlChar *
1.11      daniel     33: getPublicId(void *ctx)
1.5       daniel     34: {
1.11      daniel     35:     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.1       daniel     36:     return(NULL);
                     37: }
                     38: 
1.5       daniel     39: /**
                     40:  * getSystemId:
1.16      daniel     41:  * @ctx: the user data (XML parser context)
1.5       daniel     42:  *
1.12      daniel     43:  * Return the system ID, basically URL or filename e.g.
1.5       daniel     44:  * http://www.sgmlsource.com/dtds/memo.dtd
                     45:  *
1.34    ! daniel     46:  * Returns a xmlChar *
1.5       daniel     47:  */
1.34    ! daniel     48: const xmlChar *
1.11      daniel     49: getSystemId(void *ctx)
1.5       daniel     50: {
1.11      daniel     51:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.28      daniel     52:     return(BAD_CAST ctxt->input->filename); 
1.1       daniel     53: }
                     54: 
1.5       daniel     55: /**
                     56:  * getLineNumber:
1.16      daniel     57:  * @ctx: the user data (XML parser context)
1.5       daniel     58:  *
1.1       daniel     59:  * Return the line number of the current parsing point.
1.5       daniel     60:  *
1.8       daniel     61:  * Returns an int
1.1       daniel     62:  */
1.5       daniel     63: int
1.11      daniel     64: getLineNumber(void *ctx)
1.5       daniel     65: {
1.11      daniel     66:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.1       daniel     67:     return(ctxt->input->line);
                     68: }
1.5       daniel     69: 
                     70: /**
                     71:  * getColumnNumber:
1.16      daniel     72:  * @ctx: the user data (XML parser context)
1.5       daniel     73:  *
1.1       daniel     74:  * Return the column number of the current parsing point.
1.5       daniel     75:  *
1.8       daniel     76:  * Returns an int
1.1       daniel     77:  */
1.5       daniel     78: int
1.11      daniel     79: getColumnNumber(void *ctx)
1.5       daniel     80: {
1.11      daniel     81:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.1       daniel     82:     return(ctxt->input->col);
                     83: }
                     84: 
                     85: /*
                     86:  * The default SAX Locator.
                     87:  */
                     88: 
                     89: xmlSAXLocator xmlDefaultSAXLocator = {
                     90:     getPublicId, getSystemId, getLineNumber, getColumnNumber
                     91: };
                     92: 
1.5       daniel     93: /**
1.10      daniel     94:  * isStandalone:
1.16      daniel     95:  * @ctx: the user data (XML parser context)
1.10      daniel     96:  *
                     97:  * Is this document tagged standalone ?
                     98:  *
                     99:  * Returns 1 if true
                    100:  */
                    101: int
1.11      daniel    102: isStandalone(void *ctx)
1.10      daniel    103: {
1.11      daniel    104:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    105:     return(ctxt->myDoc->standalone == 1);
                    106: }
                    107: 
                    108: /**
                    109:  * hasInternalSubset:
1.16      daniel    110:  * @ctx: the user data (XML parser context)
1.10      daniel    111:  *
                    112:  * Does this document has an internal subset
                    113:  *
                    114:  * Returns 1 if true
                    115:  */
                    116: int
1.11      daniel    117: hasInternalSubset(void *ctx)
1.10      daniel    118: {
1.11      daniel    119:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    120:     return(ctxt->myDoc->intSubset != NULL);
                    121: }
                    122: 
                    123: /**
                    124:  * hasExternalSubset:
1.16      daniel    125:  * @ctx: the user data (XML parser context)
1.10      daniel    126:  *
                    127:  * Does this document has an external subset
                    128:  *
                    129:  * Returns 1 if true
                    130:  */
                    131: int
1.11      daniel    132: hasExternalSubset(void *ctx)
1.10      daniel    133: {
1.11      daniel    134:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    135:     return(ctxt->myDoc->extSubset != NULL);
                    136: }
                    137: 
                    138: /**
1.19      veillard  139:  * internalSubset:
1.16      daniel    140:  * @ctx: the user data (XML parser context)
1.10      daniel    141:  *
                    142:  * Does this document has an internal subset
                    143:  */
                    144: void
1.34    ! daniel    145: internalSubset(void *ctx, const xmlChar *name,
        !           146:               const xmlChar *ExternalID, const xmlChar *SystemID)
1.10      daniel    147: {
1.11      daniel    148:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    149: #ifdef DEBUG_SAX
                    150:     fprintf(stderr, "SAX.internalSubset(%s, %s, %s)\n",
                    151:             name, ExternalID, SystemID);
                    152: #endif
                    153:     xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
1.24      daniel    154:     if (((ExternalID != NULL) || (SystemID != NULL)) &&
                    155:         (ctxt->validate && ctxt->wellFormed && ctxt->myDoc)) {
                    156:        /*
                    157:         * Try to fetch and parse the external subset.
                    158:         */
                    159:        xmlDtdPtr ret = NULL;
                    160:        xmlParserCtxtPtr dtdCtxt;
                    161:        xmlParserInputPtr input = NULL;
                    162:        xmlCharEncoding enc;
                    163: 
                    164:        dtdCtxt = xmlNewParserCtxt();
                    165:        if (dtdCtxt == NULL) return;
                    166: 
                    167:        /*
                    168:         * Ask the Entity resolver to load the damn thing
                    169:         */
                    170:        if ((ctxt->directory != NULL) && (dtdCtxt->directory == NULL))
1.28      daniel    171:            dtdCtxt->directory = (char *) xmlStrdup(BAD_CAST ctxt->directory);
1.24      daniel    172: 
                    173:        if ((dtdCtxt->sax != NULL) && (dtdCtxt->sax->resolveEntity != NULL))
                    174:            input = dtdCtxt->sax->resolveEntity(dtdCtxt->userData, ExternalID,
                    175:                                                SystemID);
                    176:        if (input == NULL) {
                    177:            xmlFreeParserCtxt(dtdCtxt);
                    178:            return;
                    179:        }
                    180: 
                    181:        /*
                    182:         * plug some encoding conversion routines here. !!!
                    183:         */
                    184:        xmlPushInput(dtdCtxt, input);
                    185:        enc = xmlDetectCharEncoding(dtdCtxt->input->cur);
                    186:        xmlSwitchEncoding(dtdCtxt, enc);
                    187: 
                    188:        if (input->filename == NULL)
1.28      daniel    189:            input->filename = (char *) xmlStrdup(SystemID);
1.24      daniel    190:        input->line = 1;
                    191:        input->col = 1;
                    192:        input->base = dtdCtxt->input->cur;
                    193:        input->cur = dtdCtxt->input->cur;
                    194:        input->free = NULL;
                    195: 
                    196:        /*
                    197:         * let's parse that entity knowing it's an external subset.
                    198:         */
                    199:        xmlParseExternalSubset(dtdCtxt, ExternalID, SystemID);
                    200: 
                    201:        if (dtdCtxt->myDoc != NULL) {
                    202:            if (dtdCtxt->wellFormed) {
                    203:                ret = dtdCtxt->myDoc->intSubset;
                    204:                dtdCtxt->myDoc->intSubset = NULL;
                    205:            } else {
                    206:                ret = NULL;
                    207:            }
                    208:            xmlFreeDoc(dtdCtxt->myDoc);
                    209:            dtdCtxt->myDoc = NULL;
                    210:        }
                    211:        xmlFreeParserCtxt(dtdCtxt);
                    212:        
                    213:        ctxt->myDoc->extSubset = ret;
1.12      daniel    214:     }
1.10      daniel    215: }
                    216: 
                    217: /**
1.5       daniel    218:  * resolveEntity:
1.16      daniel    219:  * @ctx: the user data (XML parser context)
1.5       daniel    220:  * @publicId: The public ID of the entity
                    221:  * @systemId: The system ID of the entity
                    222:  *
1.1       daniel    223:  * Special entity resolver, better left to the parser, it has
                    224:  * more context than the application layer.
1.5       daniel    225:  * The default behaviour is to NOT resolve the entities, in that case
                    226:  * the ENTITY_REF nodes are built in the structure (and the parameter
1.6       daniel    227:  * values).
1.5       daniel    228:  *
1.8       daniel    229:  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1.5       daniel    230:  */
                    231: xmlParserInputPtr
1.34    ! daniel    232: resolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
1.5       daniel    233: {
1.12      daniel    234:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2       daniel    235: 
                    236: #ifdef DEBUG_SAX
                    237:     fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
                    238: #endif
1.5       daniel    239: 
1.12      daniel    240:     if (systemId != NULL) {
1.33      daniel    241:        return(xmlNewInputFromFile(ctxt, (char *) systemId));
1.12      daniel    242:     }
1.1       daniel    243:     return(NULL);
                    244: }
                    245: 
1.5       daniel    246: /**
1.10      daniel    247:  * getEntity:
1.16      daniel    248:  * @ctx: the user data (XML parser context)
1.10      daniel    249:  * @name: The entity name
                    250:  *
                    251:  * Get an entity by name
                    252:  *
1.13      daniel    253:  * Returns the xmlEntityPtr if found.
1.10      daniel    254:  */
                    255: xmlEntityPtr
1.34    ! daniel    256: getEntity(void *ctx, const xmlChar *name)
1.10      daniel    257: {
1.11      daniel    258:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    259:     xmlEntityPtr ret;
                    260: 
                    261: #ifdef DEBUG_SAX
                    262:     fprintf(stderr, "SAX.getEntity(%s)\n", name);
                    263: #endif
                    264: 
                    265:     ret = xmlGetDocEntity(ctxt->myDoc, name);
                    266:     return(ret);
                    267: }
                    268: 
1.20      daniel    269: /**
                    270:  * getParameterEntity:
                    271:  * @ctx: the user data (XML parser context)
                    272:  * @name: The entity name
                    273:  *
                    274:  * Get a parameter entity by name
                    275:  *
                    276:  * Returns the xmlEntityPtr if found.
                    277:  */
                    278: xmlEntityPtr
1.34    ! daniel    279: getParameterEntity(void *ctx, const xmlChar *name)
1.20      daniel    280: {
                    281:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                    282:     xmlEntityPtr ret;
                    283: 
                    284: #ifdef DEBUG_SAX
                    285:     fprintf(stderr, "SAX.getParameterEntity(%s)\n", name);
                    286: #endif
                    287: 
                    288:     ret = xmlGetParameterEntity(ctxt->myDoc, name);
                    289:     return(ret);
                    290: }
                    291: 
1.10      daniel    292: 
                    293: /**
                    294:  * entityDecl:
1.16      daniel    295:  * @ctx: the user data (XML parser context)
1.10      daniel    296:  * @name:  the entity name 
                    297:  * @type:  the entity type 
                    298:  * @publicId: The public ID of the entity
                    299:  * @systemId: The system ID of the entity
                    300:  * @content: the entity value (without processing).
                    301:  *
                    302:  * An entity definition has been parsed
                    303:  */
                    304: void
1.34    ! daniel    305: entityDecl(void *ctx, const xmlChar *name, int type,
        !           306:           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1.10      daniel    307: {
1.11      daniel    308:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    309: 
                    310: #ifdef DEBUG_SAX
                    311:     fprintf(stderr, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
                    312:             name, type, publicId, systemId, content);
                    313: #endif
                    314:     xmlAddDocEntity(ctxt->myDoc, name, type, publicId, systemId, content);
                    315: }
                    316: 
                    317: /**
                    318:  * attributeDecl:
1.16      daniel    319:  * @ctx: the user data (XML parser context)
1.10      daniel    320:  * @name:  the attribute name 
                    321:  * @type:  the attribute type 
                    322:  * @publicId: The public ID of the attribute
                    323:  * @systemId: The system ID of the attribute
                    324:  * @content: the attribute value (without processing).
                    325:  *
                    326:  * An attribute definition has been parsed
                    327:  */
                    328: void
1.34    ! daniel    329: attributeDecl(void *ctx, const xmlChar *elem, const xmlChar *name,
        !           330:               int type, int def, const xmlChar *defaultValue,
1.10      daniel    331:              xmlEnumerationPtr tree)
                    332: {
1.11      daniel    333:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.21      daniel    334:     xmlAttributePtr attr;
1.10      daniel    335: 
                    336: #ifdef DEBUG_SAX
                    337:     fprintf(stderr, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
                    338:             elem, name, type, def, defaultValue);
                    339: #endif
1.21      daniel    340:     attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
                    341:                                name, type, def, defaultValue, tree);
                    342:     if (attr == 0) ctxt->valid = 0;
1.23      daniel    343:     if (ctxt->validate && ctxt->wellFormed &&
                    344:         ctxt->myDoc && ctxt->myDoc->intSubset)
1.21      daniel    345:        ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
                    346:                                                attr);
1.10      daniel    347: }
                    348: 
                    349: /**
                    350:  * elementDecl:
1.16      daniel    351:  * @ctx: the user data (XML parser context)
1.10      daniel    352:  * @name:  the element name 
                    353:  * @type:  the element type 
                    354:  * @publicId: The public ID of the element
                    355:  * @systemId: The system ID of the element
                    356:  * @content: the element value (without processing).
                    357:  *
                    358:  * An element definition has been parsed
                    359:  */
                    360: void
1.34    ! daniel    361: elementDecl(void *ctx, const xmlChar *name, int type,
1.10      daniel    362:            xmlElementContentPtr content)
                    363: {
1.11      daniel    364:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.21      daniel    365:     xmlElementPtr elem;
1.10      daniel    366: 
                    367: #ifdef DEBUG_SAX
                    368:     fprintf(stderr, "SAX.elementDecl(%s, %d, ...)\n",
                    369:             name, type);
                    370: #endif
1.21      daniel    371:     
                    372:     elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
                    373:                              name, type, content);
                    374:     if (elem == 0) ctxt->valid = 0;
1.23      daniel    375:     if (ctxt->validate && ctxt->wellFormed &&
                    376:         ctxt->myDoc && ctxt->myDoc->intSubset)
1.21      daniel    377:        ctxt->valid &= xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
1.10      daniel    378: }
                    379: 
                    380: /**
1.5       daniel    381:  * notationDecl:
1.16      daniel    382:  * @ctx: the user data (XML parser context)
1.5       daniel    383:  * @name: The name of the notation
                    384:  * @publicId: The public ID of the entity
                    385:  * @systemId: The system ID of the entity
                    386:  *
1.1       daniel    387:  * What to do when a notation declaration has been parsed.
                    388:  */
1.5       daniel    389: void
1.34    ! daniel    390: notationDecl(void *ctx, const xmlChar *name,
        !           391:             const xmlChar *publicId, const xmlChar *systemId)
1.5       daniel    392: {
1.11      daniel    393:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.21      daniel    394:     xmlNotationPtr nota;
                    395: 
1.2       daniel    396: #ifdef DEBUG_SAX
                    397:     fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
                    398: #endif
1.21      daniel    399: 
                    400:     nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
                    401:                               publicId, systemId);
                    402:     if (nota == 0) ctxt->valid = 0;
1.23      daniel    403:     if (ctxt->validate && ctxt->wellFormed &&
                    404:         ctxt->myDoc && ctxt->myDoc->intSubset)
1.21      daniel    405:        ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
                    406:                                               nota);
1.1       daniel    407: }
                    408: 
1.5       daniel    409: /**
                    410:  * unparsedEntityDecl:
1.16      daniel    411:  * @ctx: the user data (XML parser context)
1.5       daniel    412:  * @name: The name of the entity
                    413:  * @publicId: The public ID of the entity
                    414:  * @systemId: The system ID of the entity
                    415:  * @notationName: the name of the notation
                    416:  *
1.1       daniel    417:  * What to do when an unparsed entity declaration is parsed
                    418:  */
1.5       daniel    419: void
1.34    ! daniel    420: unparsedEntityDecl(void *ctx, const xmlChar *name,
        !           421:                   const xmlChar *publicId, const xmlChar *systemId,
        !           422:                   const xmlChar *notationName)
1.5       daniel    423: {
1.28      daniel    424:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2       daniel    425: #ifdef DEBUG_SAX
                    426:     fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
                    427:             name, publicId, systemId, notationName);
                    428: #endif
1.28      daniel    429:     if (ctxt->validate && ctxt->wellFormed &&
                    430:         ctxt->myDoc && ctxt->myDoc->intSubset)
                    431:        ctxt->valid &= xmlValidateNotationUse(&ctxt->vctxt, ctxt->myDoc,
                    432:                                              notationName);
                    433:     xmlAddDocEntity(ctxt->myDoc, name,
                    434:                     XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
                    435:                    publicId, systemId, notationName);
1.1       daniel    436: }
                    437: 
1.5       daniel    438: /**
                    439:  * setDocumentLocator:
1.16      daniel    440:  * @ctx: the user data (XML parser context)
1.5       daniel    441:  * @loc: A SAX Locator
                    442:  *
1.1       daniel    443:  * Receive the document locator at startup, actually xmlDefaultSAXLocator
                    444:  * Everything is available on the context, so this is useless in our case.
                    445:  */
1.5       daniel    446: void
1.11      daniel    447: setDocumentLocator(void *ctx, xmlSAXLocatorPtr loc)
1.5       daniel    448: {
1.11      daniel    449:     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2       daniel    450: #ifdef DEBUG_SAX
                    451:     fprintf(stderr, "SAX.setDocumentLocator()\n");
                    452: #endif
1.1       daniel    453: }
                    454: 
1.5       daniel    455: /**
                    456:  * startDocument:
1.16      daniel    457:  * @ctx: the user data (XML parser context)
1.5       daniel    458:  *
1.1       daniel    459:  * called when the document start being processed.
                    460:  */
1.5       daniel    461: void
1.11      daniel    462: startDocument(void *ctx)
1.5       daniel    463: {
1.11      daniel    464:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    465:     xmlDocPtr doc;
                    466: 
1.2       daniel    467: #ifdef DEBUG_SAX
                    468:     fprintf(stderr, "SAX.startDocument()\n");
                    469: #endif
1.10      daniel    470:     doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
                    471:     if (doc != NULL) {
                    472:        if (ctxt->encoding != NULL)
                    473:            doc->encoding = xmlStrdup(ctxt->encoding);
                    474:        else
                    475:            doc->encoding = NULL;
                    476:        doc->standalone = ctxt->standalone;
                    477:     }
1.1       daniel    478: }
                    479: 
1.5       daniel    480: /**
                    481:  * endDocument:
1.16      daniel    482:  * @ctx: the user data (XML parser context)
1.5       daniel    483:  *
1.1       daniel    484:  * called when the document end has been detected.
                    485:  */
1.5       daniel    486: void
1.11      daniel    487: endDocument(void *ctx)
1.5       daniel    488: {
1.31      daniel    489:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2       daniel    490: #ifdef DEBUG_SAX
                    491:     fprintf(stderr, "SAX.endDocument()\n");
                    492: #endif
1.31      daniel    493:     if (ctxt->validate && ctxt->wellFormed &&
                    494:         ctxt->myDoc && ctxt->myDoc->intSubset)
                    495:        ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
1.1       daniel    496: }
                    497: 
1.5       daniel    498: /**
1.10      daniel    499:  * attribute:
1.16      daniel    500:  * @ctx: the user data (XML parser context)
1.10      daniel    501:  * @name:  The attribute name
                    502:  * @value:  The attribute value
                    503:  *
                    504:  * Handle an attribute that has been read by the parser.
                    505:  * The default handling is to convert the attribute into an
                    506:  * DOM subtree and past it in a new xmlAttr element added to
                    507:  * the element.
                    508:  */
                    509: void
1.34    ! daniel    510: attribute(void *ctx, const xmlChar *fullname, const xmlChar *value)
1.10      daniel    511: {
1.11      daniel    512:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    513:     xmlAttrPtr ret;
1.34    ! daniel    514:     xmlChar *name;
        !           515:     xmlChar *ns;
1.29      daniel    516:     xmlNsPtr namespace;
1.10      daniel    517: 
                    518: /****************
                    519: #ifdef DEBUG_SAX
                    520:     fprintf(stderr, "SAX.attribute(%s, %s)\n", fullname, value);
                    521: #endif
                    522:  ****************/
                    523:     /*
                    524:      * Split the full name into a namespace prefix and the tag name
                    525:      */
                    526:     name = xmlSplitQName(fullname, &ns);
                    527: 
                    528:     /*
                    529:      * Check whether it's a namespace definition
                    530:      */
                    531:     if ((ns == NULL) &&
                    532:         (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
                    533:         (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
                    534:        /* a default namespace definition */
                    535:        xmlNewNs(ctxt->node, value, NULL);
                    536:        if (name != NULL) 
1.30      daniel    537:            xmlFree(name);
1.10      daniel    538:        return;
                    539:     }
                    540:     if ((ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
                    541:         (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
                    542:        /* a standard namespace definition */
                    543:        xmlNewNs(ctxt->node, value, name);
1.30      daniel    544:        xmlFree(ns);
1.10      daniel    545:        if (name != NULL) 
1.30      daniel    546:            xmlFree(name);
1.10      daniel    547:        return;
                    548:     }
                    549: 
1.29      daniel    550:     namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
                    551:     /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
                    552:     ret = xmlNewNsProp(ctxt->node, namespace, name, NULL);
1.22      daniel    553: 
1.26      daniel    554:     if (ret != NULL) {
                    555:         if (ctxt->replaceEntities == 0)
                    556:            ret->val = xmlStringGetNodeList(ctxt->myDoc, value);
                    557:        else
                    558:            ret->val = xmlNewDocText(ctxt->myDoc, value);
                    559:     }
1.22      daniel    560: 
1.23      daniel    561:     if (ctxt->validate && ctxt->wellFormed &&
                    562:         ctxt->myDoc && ctxt->myDoc->intSubset)
1.22      daniel    563:         ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
                    564:                                               ctxt->node, ret, value);
1.26      daniel    565:     else {
                    566:         /*
                    567:         * when validating, the ID registration is done at the attribute
                    568:         * validation level. Otherwise we have to do specific handling here.
                    569:         */
                    570:        if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
                    571:            xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
1.31      daniel    572:        else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
                    573:            xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
1.26      daniel    574:     }
1.22      daniel    575: 
1.10      daniel    576:     if (name != NULL) 
1.30      daniel    577:        xmlFree(name);
1.10      daniel    578:     if (ns != NULL) 
1.30      daniel    579:        xmlFree(ns);
1.10      daniel    580: }
                    581: 
                    582: /**
1.5       daniel    583:  * startElement:
1.16      daniel    584:  * @ctx: the user data (XML parser context)
1.5       daniel    585:  * @name:  The element name
1.10      daniel    586:  * @atts:  An array of name/value attributes pairs, NULL terminated
1.5       daniel    587:  *
1.1       daniel    588:  * called when an opening tag has been processed.
                    589:  */
1.5       daniel    590: void
1.34    ! daniel    591: startElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
1.5       daniel    592: {
1.11      daniel    593:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    594:     xmlNodePtr ret;
                    595:     xmlNodePtr parent = ctxt->node;
                    596:     xmlNsPtr ns;
1.34    ! daniel    597:     xmlChar *name;
        !           598:     xmlChar *prefix;
        !           599:     const xmlChar *att;
        !           600:     const xmlChar *value;
1.10      daniel    601:     int i;
                    602: 
1.2       daniel    603: #ifdef DEBUG_SAX
1.10      daniel    604:     fprintf(stderr, "SAX.startElement(%s)\n", fullname);
1.2       daniel    605: #endif
1.33      daniel    606: 
                    607:     /*
                    608:      * First check on validity:
                    609:      */
                    610:     if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) && 
                    611:         ((ctxt->myDoc->intSubset == NULL) ||
                    612:         ((ctxt->myDoc->intSubset->notations == NULL) && 
                    613:          (ctxt->myDoc->intSubset->elements == NULL) &&
                    614:          (ctxt->myDoc->intSubset->attributes == NULL) && 
                    615:          (ctxt->myDoc->intSubset->entities == NULL)))) {
                    616:        if (ctxt->vctxt.error != NULL) {
                    617:             ctxt->vctxt.error(ctxt->vctxt.userData,
                    618:              "Validation failed: no DTD found !\n");
                    619:        }
                    620:        ctxt->validate = 0;
                    621:     }
                    622:        
                    623: 
1.10      daniel    624:     /*
                    625:      * Split the full name into a namespace prefix and the tag name
                    626:      */
                    627:     name = xmlSplitQName(fullname, &prefix);
                    628: 
                    629: 
                    630:     /*
                    631:      * Note : the namespace resolution is deferred until the end of the
                    632:      *        attributes parsing, since local namespace can be defined as
                    633:      *        an attribute at this level.
                    634:      */
                    635:     ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
                    636:     if (ret == NULL) return;
1.26      daniel    637:     if (ctxt->myDoc->root == NULL) {
                    638: #ifdef DEBUG_SAX_TREE
                    639:        fprintf(stderr, "Setting %s as root\n", name);
                    640: #endif
1.10      daniel    641:         ctxt->myDoc->root = ret;
1.26      daniel    642:     } else if (parent == NULL) {
                    643:         parent = ctxt->myDoc->root;
                    644:     }
1.10      daniel    645: 
                    646:     /*
                    647:      * We are parsing a new node.
                    648:      */
1.26      daniel    649: #ifdef DEBUG_SAX_TREE
                    650:     fprintf(stderr, "pushing(%s)\n", name);
                    651: #endif
1.10      daniel    652:     nodePush(ctxt, ret);
                    653: 
                    654:     /*
                    655:      * Link the child element
                    656:      */
1.26      daniel    657:     if (parent != NULL) {
                    658:         if (parent->type == XML_ELEMENT_NODE) {
                    659: #ifdef DEBUG_SAX_TREE
                    660:            fprintf(stderr, "adding child %s to %s\n", name, parent->name);
                    661: #endif
                    662:            xmlAddChild(parent, ret);
                    663:        } else {
                    664: #ifdef DEBUG_SAX_TREE
                    665:            fprintf(stderr, "adding sibling %s to ", name);
                    666:            xmlDebugDumpOneNode(stderr, parent, 0);
                    667: #endif
                    668:            xmlAddSibling(parent, ret);
                    669:        }
                    670:     }
1.10      daniel    671: 
                    672:     /*
1.29      daniel    673:      * process all the attributes whose name start with "xml"
1.10      daniel    674:      */
                    675:     if (atts != NULL) {
                    676:         i = 0;
                    677:        att = atts[i++];
                    678:        value = atts[i++];
                    679:         while ((att != NULL) && (value != NULL)) {
1.29      daniel    680:            if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l'))
                    681:                attribute(ctxt, att, value);
                    682: 
                    683:            att = atts[i++];
                    684:            value = atts[i++];
                    685:        }
                    686:     }
                    687: 
                    688:     /*
                    689:      * process all the other attributes
                    690:      */
                    691:     if (atts != NULL) {
                    692:         i = 0;
                    693:        att = atts[i++];
                    694:        value = atts[i++];
                    695:         while ((att != NULL) && (value != NULL)) {
                    696:            if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l'))
                    697:                attribute(ctxt, att, value);
1.10      daniel    698: 
                    699:            /*
                    700:             * Next ones
                    701:             */
                    702:            att = atts[i++];
                    703:            value = atts[i++];
                    704:        }
                    705:     }
                    706: 
                    707:     /*
                    708:      * Search the namespace, note that since the attributes have been
                    709:      * processed, the local namespaces are available.
                    710:      */
                    711:     ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
                    712:     if ((ns == NULL) && (parent != NULL))
                    713:        ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
                    714:     xmlSetNs(ret, ns);
                    715: 
                    716:     if (prefix != NULL)
1.30      daniel    717:        xmlFree(prefix);
1.10      daniel    718:     if (name != NULL)
1.30      daniel    719:        xmlFree(name);
1.10      daniel    720: 
1.1       daniel    721: }
                    722: 
1.5       daniel    723: /**
                    724:  * endElement:
1.16      daniel    725:  * @ctx: the user data (XML parser context)
1.5       daniel    726:  * @name:  The element name
                    727:  *
1.1       daniel    728:  * called when the end of an element has been detected.
                    729:  */
1.5       daniel    730: void
1.34    ! daniel    731: endElement(void *ctx, const xmlChar *name)
1.5       daniel    732: {
1.11      daniel    733:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    734:     xmlParserNodeInfo node_info;
                    735:     xmlNodePtr cur = ctxt->node;
                    736: 
1.2       daniel    737: #ifdef DEBUG_SAX
1.10      daniel    738:     if (name == NULL)
                    739:         fprintf(stderr, "SAX.endElement(NULL)\n");
                    740:     else
                    741:        fprintf(stderr, "SAX.endElement(%s)\n", name);
                    742: #endif
                    743:     
                    744:     /* Capture end position and add node */
                    745:     if (cur != NULL && ctxt->record_info) {
                    746:       node_info.end_pos = ctxt->input->cur - ctxt->input->base;
                    747:       node_info.end_line = ctxt->input->line;
                    748:       node_info.node = cur;
                    749:       xmlParserAddNodeInfo(ctxt, &node_info);
                    750:     }
                    751: 
1.23      daniel    752:     if (ctxt->validate && ctxt->wellFormed &&
                    753:         ctxt->myDoc && ctxt->myDoc->intSubset)
1.22      daniel    754:         ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
                    755:                                             cur);
                    756: 
                    757:     
1.10      daniel    758:     /*
                    759:      * end of parsing of this node.
                    760:      */
1.26      daniel    761: #ifdef DEBUG_SAX_TREE
                    762:     fprintf(stderr, "popping(%s)\n", cur->name);
                    763: #endif
1.10      daniel    764:     nodePop(ctxt);
1.1       daniel    765: }
                    766: 
1.5       daniel    767: /**
1.10      daniel    768:  * reference:
1.16      daniel    769:  * @ctx: the user data (XML parser context)
1.10      daniel    770:  * @name:  The entity name
1.5       daniel    771:  *
1.10      daniel    772:  * called when an entity reference is detected. 
1.5       daniel    773:  */
                    774: void
1.34    ! daniel    775: reference(void *ctx, const xmlChar *name)
1.5       daniel    776: {
1.11      daniel    777:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    778:     xmlNodePtr ret;
                    779: 
1.5       daniel    780: #ifdef DEBUG_SAX
1.10      daniel    781:     fprintf(stderr, "SAX.reference(%s)\n", name);
1.5       daniel    782: #endif
1.10      daniel    783:     ret = xmlNewReference(ctxt->myDoc, name);
1.26      daniel    784: #ifdef DEBUG_SAX_TREE
                    785:     fprintf(stderr, "add reference %s to %s \n", name, ctxt->node->name);
                    786: #endif
1.10      daniel    787:     xmlAddChild(ctxt->node, ret);
1.5       daniel    788: }
                    789: 
                    790: /**
                    791:  * characters:
1.16      daniel    792:  * @ctx: the user data (XML parser context)
1.34    ! daniel    793:  * @ch:  a xmlChar string
        !           794:  * @len: the number of xmlChar
1.5       daniel    795:  *
1.1       daniel    796:  * receiving some chars from the parser.
                    797:  * Question: how much at a time ???
                    798:  */
1.5       daniel    799: void
1.34    ! daniel    800: characters(void *ctx, const xmlChar *ch, int len)
1.5       daniel    801: {
1.11      daniel    802:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2       daniel    803:     xmlNodePtr lastChild;
                    804: 
                    805: #ifdef DEBUG_SAX
1.10      daniel    806:     fprintf(stderr, "SAX.characters(%.30s, %d)\n", ch, len);
1.2       daniel    807: #endif
                    808:     /*
                    809:      * Handle the data if any. If there is no child
                    810:      * add it as content, otherwise if the last child is text,
                    811:      * concatenate it, else create a new node of type text.
                    812:      */
                    813: 
                    814:     lastChild = xmlGetLastChild(ctxt->node);
1.26      daniel    815: #ifdef DEBUG_SAX_TREE
                    816:     fprintf(stderr, "add chars to %s \n", ctxt->node->name);
                    817: #endif
1.2       daniel    818:     if (lastChild == NULL)
1.10      daniel    819:        xmlNodeAddContentLen(ctxt->node, ch, len);
1.2       daniel    820:     else {
                    821:        if (xmlNodeIsText(lastChild))
1.10      daniel    822:            xmlTextConcat(lastChild, ch, len);
1.2       daniel    823:        else {
1.10      daniel    824:            lastChild = xmlNewTextLen(ch, len);
1.2       daniel    825:            xmlAddChild(ctxt->node, lastChild);
                    826:        }
                    827:     }
1.1       daniel    828: }
                    829: 
1.5       daniel    830: /**
                    831:  * ignorableWhitespace:
1.16      daniel    832:  * @ctx: the user data (XML parser context)
1.34    ! daniel    833:  * @ch:  a xmlChar string
        !           834:  * @len: the number of xmlChar
1.5       daniel    835:  *
1.1       daniel    836:  * receiving some ignorable whitespaces from the parser.
                    837:  * Question: how much at a time ???
                    838:  */
1.5       daniel    839: void
1.34    ! daniel    840: ignorableWhitespace(void *ctx, const xmlChar *ch, int len)
1.5       daniel    841: {
1.11      daniel    842:     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2       daniel    843: #ifdef DEBUG_SAX
1.10      daniel    844:     fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
1.2       daniel    845: #endif
1.1       daniel    846: }
                    847: 
1.5       daniel    848: /**
                    849:  * processingInstruction:
1.16      daniel    850:  * @ctx: the user data (XML parser context)
1.5       daniel    851:  * @target:  the target name
                    852:  * @data: the PI data's
1.34    ! daniel    853:  * @len: the number of xmlChar
1.5       daniel    854:  *
                    855:  * A processing instruction has been parsed.
                    856:  */
                    857: void
1.34    ! daniel    858: processingInstruction(void *ctx, const xmlChar *target,
        !           859:                       const xmlChar *data)
1.5       daniel    860: {
1.26      daniel    861:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                    862:     xmlNodePtr ret;
                    863:     xmlNodePtr parent = ctxt->node;
                    864: 
1.2       daniel    865: #ifdef DEBUG_SAX
                    866:     fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
                    867: #endif
1.26      daniel    868: 
                    869:     ret = xmlNewPI(target, data);
                    870:     if (ret == NULL) return;
                    871:     ret->doc = ctxt->myDoc;
                    872:     if (ctxt->myDoc->root == NULL) {
                    873: #ifdef DEBUG_SAX_TREE
                    874:            fprintf(stderr, "Setting PI %s as root\n", target);
                    875: #endif
                    876:         ctxt->myDoc->root = ret;
                    877:     } else if (parent == NULL) {
                    878:         parent = ctxt->myDoc->root;
                    879:     }
                    880:     if (parent != NULL) {
                    881:         if (parent->type == XML_ELEMENT_NODE) {
                    882: #ifdef DEBUG_SAX_TREE
                    883:            fprintf(stderr, "adding PI child %s to %s\n", target, parent->name);
                    884: #endif
                    885:            xmlAddChild(parent, ret);
                    886:        } else {
                    887: #ifdef DEBUG_SAX_TREE
                    888:            fprintf(stderr, "adding PI sibling %s to ", target);
                    889:            xmlDebugDumpOneNode(stderr, parent, 0);
                    890: #endif
                    891:            xmlAddSibling(parent, ret);
                    892:        }
                    893:     }
                    894: 
1.1       daniel    895: }
                    896: 
1.10      daniel    897: /**
                    898:  * globalNamespace:
1.16      daniel    899:  * @ctx: the user data (XML parser context)
1.10      daniel    900:  * @href:  the namespace associated URN
                    901:  * @prefix: the namespace prefix
                    902:  *
                    903:  * An old global namespace has been parsed.
                    904:  */
                    905: void
1.34    ! daniel    906: globalNamespace(void *ctx, const xmlChar *href, const xmlChar *prefix)
1.10      daniel    907: {
1.11      daniel    908:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    909: #ifdef DEBUG_SAX
                    910:     fprintf(stderr, "SAX.globalNamespace(%s, %s)\n", href, prefix);
                    911: #endif
                    912:     xmlNewGlobalNs(ctxt->myDoc, href, prefix);
                    913: }
                    914: 
                    915: /**
                    916:  * setNamespace:
1.16      daniel    917:  * @ctx: the user data (XML parser context)
1.10      daniel    918:  * @name:  the namespace prefix
                    919:  *
                    920:  * Set the current element namespace.
                    921:  */
                    922: void
1.34    ! daniel    923: setNamespace(void *ctx, const xmlChar *name)
1.10      daniel    924: {
1.11      daniel    925:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    926:     xmlNsPtr ns;
                    927:     xmlNodePtr parent;
                    928: 
                    929: #ifdef DEBUG_SAX
                    930:     fprintf(stderr, "SAX.setNamespace(%s)\n", name);
                    931: #endif
                    932:     ns = xmlSearchNs(ctxt->myDoc, ctxt->node, name);
                    933:     if (ns == NULL) { /* ctxt->node may not have a parent yet ! */
                    934:         if (ctxt->nodeNr >= 2) {
                    935:            parent = ctxt->nodeTab[ctxt->nodeNr - 2];
                    936:            if (parent != NULL)
                    937:                ns = xmlSearchNs(ctxt->myDoc, parent, name);
                    938:        }
                    939:     }
                    940:     xmlSetNs(ctxt->node, ns);
                    941: }
                    942: 
                    943: /**
                    944:  * getNamespace:
1.16      daniel    945:  * @ctx: the user data (XML parser context)
1.10      daniel    946:  *
                    947:  * Get the current element namespace.
                    948:  */
                    949: xmlNsPtr
1.11      daniel    950: getNamespace(void *ctx)
1.10      daniel    951: {
1.11      daniel    952:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    953:     xmlNsPtr ret;
                    954: 
                    955: #ifdef DEBUG_SAX
                    956:     fprintf(stderr, "SAX.getNamespace()\n");
                    957: #endif
                    958:     ret = ctxt->node->ns;
                    959:     return(ret);
                    960: }
                    961: 
                    962: /**
                    963:  * checkNamespace:
1.16      daniel    964:  * @ctx: the user data (XML parser context)
1.10      daniel    965:  * @namespace: the namespace to check against
                    966:  *
                    967:  * Check that the current element namespace is the same as the
                    968:  * one read upon parsing.
                    969:  */
                    970: int
1.34    ! daniel    971: checkNamespace(void *ctx, xmlChar *namespace)
1.10      daniel    972: {
1.11      daniel    973:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    974:     xmlNodePtr cur = ctxt->node;
                    975: 
                    976: #ifdef DEBUG_SAX
                    977:     fprintf(stderr, "SAX.checkNamespace(%s)\n", namespace);
                    978: #endif
                    979: 
                    980:     /*
                    981:      * Check that the Name in the ETag is the same as in the STag.
                    982:      */
                    983:     if (namespace == NULL) {
                    984:         if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
                    985:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    986:                ctxt->sax->error(ctxt, 
                    987:                 "End tags for %s don't hold the namespace %s\n",
                    988:                                 cur->name, cur->ns->prefix);
                    989:            ctxt->wellFormed = 0;
                    990:        }
                    991:     } else {
                    992:         if ((cur->ns == NULL) || (cur->ns->prefix == NULL)) {
                    993:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    994:                ctxt->sax->error(ctxt, 
                    995:                 "End tags %s holds a prefix %s not used by the open tag\n",
                    996:                                 cur->name, namespace);
                    997:            ctxt->wellFormed = 0;
1.28      daniel    998:        } else if (xmlStrcmp(namespace, cur->ns->prefix)) {
1.10      daniel    999:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1000:                ctxt->sax->error(ctxt, 
                   1001:     "Start and End tags for %s don't use the same namespaces: %s and %s\n",
                   1002:                                 cur->name, cur->ns->prefix, namespace);
                   1003:            ctxt->wellFormed = 0;
                   1004:        } else
                   1005:            return(1);
                   1006:     }
                   1007:     return(0);
                   1008: }
                   1009: 
                   1010: /**
                   1011:  * namespaceDecl:
1.16      daniel   1012:  * @ctx: the user data (XML parser context)
1.10      daniel   1013:  * @href:  the namespace associated URN
                   1014:  * @prefix: the namespace prefix
                   1015:  *
                   1016:  * A namespace has been parsed.
                   1017:  */
                   1018: void
1.34    ! daniel   1019: namespaceDecl(void *ctx, const xmlChar *href, const xmlChar *prefix)
1.10      daniel   1020: {
1.11      daniel   1021:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel   1022: #ifdef DEBUG_SAX
                   1023:     if (prefix == NULL)
                   1024:        fprintf(stderr, "SAX.namespaceDecl(%s, NULL)\n", href);
                   1025:     else
                   1026:        fprintf(stderr, "SAX.namespaceDecl(%s, %s)\n", href, prefix);
                   1027: #endif
                   1028:     xmlNewNs(ctxt->node, href, prefix);
                   1029: }
                   1030: 
                   1031: /**
                   1032:  * comment:
1.16      daniel   1033:  * @ctx: the user data (XML parser context)
1.10      daniel   1034:  * @value:  the comment content
                   1035:  *
                   1036:  * A comment has been parsed.
                   1037:  */
                   1038: void
1.34    ! daniel   1039: comment(void *ctx, const xmlChar *value)
1.10      daniel   1040: {
1.11      daniel   1041:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.17      daniel   1042:     xmlNodePtr ret;
1.27      daniel   1043:     xmlNodePtr parent = ctxt->node;
1.17      daniel   1044: 
1.10      daniel   1045: #ifdef DEBUG_SAX
                   1046:     fprintf(stderr, "SAX.comment(%s)\n", value);
                   1047: #endif
1.17      daniel   1048:     ret = xmlNewDocComment(ctxt->myDoc, value);
1.27      daniel   1049:     if (ret == NULL) return;
                   1050: 
                   1051:     if (ctxt->myDoc->root == NULL) {
                   1052: #ifdef DEBUG_SAX_TREE
                   1053:            fprintf(stderr, "Setting comment as root\n");
                   1054: #endif
                   1055:         ctxt->myDoc->root = ret;
                   1056:     } else if (parent == NULL) {
                   1057:         parent = ctxt->myDoc->root;
                   1058:     }
                   1059:     if (parent != NULL) {
                   1060:         if (parent->type == XML_ELEMENT_NODE) {
                   1061: #ifdef DEBUG_SAX_TREE
                   1062:            fprintf(stderr, "adding comment child to %s\n", parent->name);
                   1063: #endif
                   1064:            xmlAddChild(parent, ret);
                   1065:        } else {
                   1066: #ifdef DEBUG_SAX_TREE
                   1067:            fprintf(stderr, "adding comment sibling to ");
                   1068:            xmlDebugDumpOneNode(stderr, parent, 0);
                   1069: #endif
                   1070:            xmlAddSibling(parent, ret);
                   1071:        }
                   1072:     }
1.25      daniel   1073: }
                   1074: 
                   1075: /**
                   1076:  * cdataBlock:
                   1077:  * @ctx: the user data (XML parser context)
                   1078:  * @value:  The pcdata content
                   1079:  * @len:  the block length
                   1080:  *
                   1081:  * called when a pcdata block has been parsed
                   1082:  */
                   1083: void
1.34    ! daniel   1084: cdataBlock(void *ctx, const xmlChar *value, int len)
1.25      daniel   1085: {
                   1086:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                   1087:     xmlNodePtr ret;
                   1088: 
                   1089: #ifdef DEBUG_SAX
1.26      daniel   1090:     fprintf(stderr, "SAX.pcdata(%.10s, %d)\n", value, len);
1.25      daniel   1091: #endif
                   1092:     ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
                   1093:     xmlAddChild(ctxt->node, ret);
                   1094:     /* !!!!! merges */
1.10      daniel   1095: }
                   1096: 
1.18      daniel   1097: /*
                   1098:  * Default handler for XML, builds the DOM tree
                   1099:  */
1.1       daniel   1100: xmlSAXHandler xmlDefaultSAXHandler = {
1.10      daniel   1101:     internalSubset,
                   1102:     isStandalone,
                   1103:     hasInternalSubset,
                   1104:     hasExternalSubset,
1.1       daniel   1105:     resolveEntity,
1.10      daniel   1106:     getEntity,
                   1107:     entityDecl,
1.1       daniel   1108:     notationDecl,
1.10      daniel   1109:     attributeDecl,
                   1110:     elementDecl,
1.1       daniel   1111:     unparsedEntityDecl,
                   1112:     setDocumentLocator,
                   1113:     startDocument,
                   1114:     endDocument,
                   1115:     startElement,
                   1116:     endElement,
1.10      daniel   1117:     reference,
1.1       daniel   1118:     characters,
                   1119:     ignorableWhitespace,
                   1120:     processingInstruction,
1.10      daniel   1121:     comment,
1.1       daniel   1122:     xmlParserWarning,
                   1123:     xmlParserError,
1.2       daniel   1124:     xmlParserError,
1.20      daniel   1125:     getParameterEntity,
1.25      daniel   1126:     cdataBlock,
1.1       daniel   1127: };
1.2       daniel   1128: 
1.5       daniel   1129: /**
                   1130:  * xmlDefaultSAXHandlerInit:
                   1131:  *
                   1132:  * Initialize the default SAX handler
                   1133:  */
                   1134: void
                   1135: xmlDefaultSAXHandlerInit(void)
                   1136: {
1.10      daniel   1137:     xmlDefaultSAXHandler.internalSubset = internalSubset;
                   1138:     xmlDefaultSAXHandler.isStandalone = isStandalone;
                   1139:     xmlDefaultSAXHandler.hasInternalSubset = hasInternalSubset;
                   1140:     xmlDefaultSAXHandler.hasExternalSubset = hasExternalSubset;
1.2       daniel   1141:     xmlDefaultSAXHandler.resolveEntity = resolveEntity;
1.10      daniel   1142:     xmlDefaultSAXHandler.getEntity = getEntity;
1.20      daniel   1143:     xmlDefaultSAXHandler.getParameterEntity = getParameterEntity;
1.10      daniel   1144:     xmlDefaultSAXHandler.entityDecl = entityDecl;
                   1145:     xmlDefaultSAXHandler.attributeDecl = attributeDecl;
                   1146:     xmlDefaultSAXHandler.elementDecl = elementDecl;
1.2       daniel   1147:     xmlDefaultSAXHandler.notationDecl = notationDecl;
                   1148:     xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
                   1149:     xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
                   1150:     xmlDefaultSAXHandler.startDocument = startDocument;
                   1151:     xmlDefaultSAXHandler.endDocument = endDocument;
                   1152:     xmlDefaultSAXHandler.startElement = startElement;
                   1153:     xmlDefaultSAXHandler.endElement = endElement;
1.10      daniel   1154:     xmlDefaultSAXHandler.reference = reference;
1.2       daniel   1155:     xmlDefaultSAXHandler.characters = characters;
1.25      daniel   1156:     xmlDefaultSAXHandler.cdataBlock = cdataBlock;
1.2       daniel   1157:     xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
                   1158:     xmlDefaultSAXHandler.processingInstruction = processingInstruction;
1.10      daniel   1159:     xmlDefaultSAXHandler.comment = comment;
1.2       daniel   1160:     xmlDefaultSAXHandler.warning = xmlParserWarning;
                   1161:     xmlDefaultSAXHandler.error = xmlParserError;
                   1162:     xmlDefaultSAXHandler.fatalError = xmlParserError;
1.18      daniel   1163: }
                   1164: 
                   1165: /*
                   1166:  * Default handler for HTML, builds the DOM tree
                   1167:  */
                   1168: xmlSAXHandler htmlDefaultSAXHandler = {
                   1169:     NULL,
                   1170:     NULL,
                   1171:     NULL,
                   1172:     NULL,
                   1173:     NULL,
                   1174:     getEntity,
                   1175:     NULL,
                   1176:     NULL,
                   1177:     NULL,
                   1178:     NULL,
                   1179:     NULL,
                   1180:     setDocumentLocator,
                   1181:     startDocument,
                   1182:     endDocument,
                   1183:     startElement,
                   1184:     endElement,
                   1185:     NULL,
                   1186:     characters,
                   1187:     ignorableWhitespace,
                   1188:     NULL,
                   1189:     comment,
                   1190:     xmlParserWarning,
                   1191:     xmlParserError,
                   1192:     xmlParserError,
1.20      daniel   1193:     getParameterEntity,
1.25      daniel   1194:     NULL,
1.18      daniel   1195: };
                   1196: 
                   1197: /**
                   1198:  * htmlDefaultSAXHandlerInit:
                   1199:  *
                   1200:  * Initialize the default SAX handler
                   1201:  */
                   1202: void
                   1203: htmlDefaultSAXHandlerInit(void)
                   1204: {
                   1205:     htmlDefaultSAXHandler.internalSubset = NULL;
                   1206:     htmlDefaultSAXHandler.isStandalone = NULL;
                   1207:     htmlDefaultSAXHandler.hasInternalSubset = NULL;
                   1208:     htmlDefaultSAXHandler.hasExternalSubset = NULL;
                   1209:     htmlDefaultSAXHandler.resolveEntity = NULL;
                   1210:     htmlDefaultSAXHandler.getEntity = getEntity;
1.20      daniel   1211:     htmlDefaultSAXHandler.getParameterEntity = NULL;
1.18      daniel   1212:     htmlDefaultSAXHandler.entityDecl = NULL;
                   1213:     htmlDefaultSAXHandler.attributeDecl = NULL;
                   1214:     htmlDefaultSAXHandler.elementDecl = NULL;
                   1215:     htmlDefaultSAXHandler.notationDecl = NULL;
                   1216:     htmlDefaultSAXHandler.unparsedEntityDecl = NULL;
                   1217:     htmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
                   1218:     htmlDefaultSAXHandler.startDocument = startDocument;
                   1219:     htmlDefaultSAXHandler.endDocument = endDocument;
                   1220:     htmlDefaultSAXHandler.startElement = startElement;
                   1221:     htmlDefaultSAXHandler.endElement = endElement;
                   1222:     htmlDefaultSAXHandler.reference = NULL;
                   1223:     htmlDefaultSAXHandler.characters = characters;
1.25      daniel   1224:     htmlDefaultSAXHandler.cdataBlock = NULL;
1.18      daniel   1225:     htmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
                   1226:     htmlDefaultSAXHandler.processingInstruction = NULL;
                   1227:     htmlDefaultSAXHandler.comment = comment;
                   1228:     htmlDefaultSAXHandler.warning = xmlParserWarning;
                   1229:     htmlDefaultSAXHandler.error = xmlParserError;
                   1230:     htmlDefaultSAXHandler.fatalError = xmlParserError;
1.2       daniel   1231: }

Webmaster