Annotation of XML/SAX.c, revision 1.72

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.39      daniel     10: #ifdef WIN32
                     11: #include "win32config.h"
                     12: #else
                     13: #include "config.h"
                     14: #endif
1.1       daniel     15: #include <stdio.h>
1.5       daniel     16: #include <stdlib.h>
1.68      veillard   17: #include <string.h>
1.57      daniel     18: #include <libxml/xmlmemory.h>
                     19: #include <libxml/tree.h>
                     20: #include <libxml/parser.h>
                     21: #include <libxml/parserInternals.h>
                     22: #include <libxml/valid.h>
                     23: #include <libxml/entities.h>
1.68      veillard   24: #include <libxml/xml-error.h>
1.57      daniel     25: #include <libxml/debugXML.h>
                     26: #include <libxml/xmlIO.h>
                     27: #include <libxml/SAX.h>
1.60      daniel     28: #include <libxml/uri.h>
1.66      daniel     29: #include <libxml/HTMLtree.h>
1.1       daniel     30: 
1.15      daniel     31: /* #define DEBUG_SAX */
1.26      daniel     32: /* #define DEBUG_SAX_TREE */
1.2       daniel     33: 
1.5       daniel     34: /**
                     35:  * getPublicId:
1.16      daniel     36:  * @ctx: the user data (XML parser context)
1.5       daniel     37:  *
1.1       daniel     38:  * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
1.5       daniel     39:  *
1.34      daniel     40:  * Returns a xmlChar *
1.1       daniel     41:  */
1.34      daniel     42: const xmlChar *
1.11      daniel     43: getPublicId(void *ctx)
1.5       daniel     44: {
1.11      daniel     45:     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.1       daniel     46:     return(NULL);
                     47: }
                     48: 
1.5       daniel     49: /**
                     50:  * getSystemId:
1.16      daniel     51:  * @ctx: the user data (XML parser context)
1.5       daniel     52:  *
1.12      daniel     53:  * Return the system ID, basically URL or filename e.g.
1.5       daniel     54:  * http://www.sgmlsource.com/dtds/memo.dtd
                     55:  *
1.34      daniel     56:  * Returns a xmlChar *
1.5       daniel     57:  */
1.34      daniel     58: const xmlChar *
1.11      daniel     59: getSystemId(void *ctx)
1.5       daniel     60: {
1.11      daniel     61:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.28      daniel     62:     return(BAD_CAST ctxt->input->filename); 
1.1       daniel     63: }
                     64: 
1.5       daniel     65: /**
                     66:  * getLineNumber:
1.16      daniel     67:  * @ctx: the user data (XML parser context)
1.5       daniel     68:  *
1.1       daniel     69:  * Return the line number of the current parsing point.
1.5       daniel     70:  *
1.8       daniel     71:  * Returns an int
1.1       daniel     72:  */
1.5       daniel     73: int
1.11      daniel     74: getLineNumber(void *ctx)
1.5       daniel     75: {
1.11      daniel     76:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.1       daniel     77:     return(ctxt->input->line);
                     78: }
1.5       daniel     79: 
                     80: /**
                     81:  * getColumnNumber:
1.16      daniel     82:  * @ctx: the user data (XML parser context)
1.5       daniel     83:  *
1.1       daniel     84:  * Return the column number of the current parsing point.
1.5       daniel     85:  *
1.8       daniel     86:  * Returns an int
1.1       daniel     87:  */
1.5       daniel     88: int
1.11      daniel     89: getColumnNumber(void *ctx)
1.5       daniel     90: {
1.11      daniel     91:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.1       daniel     92:     return(ctxt->input->col);
                     93: }
                     94: 
                     95: /*
                     96:  * The default SAX Locator.
                     97:  */
                     98: 
                     99: xmlSAXLocator xmlDefaultSAXLocator = {
                    100:     getPublicId, getSystemId, getLineNumber, getColumnNumber
                    101: };
                    102: 
1.5       daniel    103: /**
1.10      daniel    104:  * isStandalone:
1.16      daniel    105:  * @ctx: the user data (XML parser context)
1.10      daniel    106:  *
                    107:  * Is this document tagged standalone ?
                    108:  *
                    109:  * Returns 1 if true
                    110:  */
                    111: int
1.11      daniel    112: isStandalone(void *ctx)
1.10      daniel    113: {
1.11      daniel    114:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    115:     return(ctxt->myDoc->standalone == 1);
                    116: }
                    117: 
                    118: /**
                    119:  * hasInternalSubset:
1.16      daniel    120:  * @ctx: the user data (XML parser context)
1.10      daniel    121:  *
                    122:  * Does this document has an internal subset
                    123:  *
                    124:  * Returns 1 if true
                    125:  */
                    126: int
1.11      daniel    127: hasInternalSubset(void *ctx)
1.10      daniel    128: {
1.11      daniel    129:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    130:     return(ctxt->myDoc->intSubset != NULL);
                    131: }
                    132: 
                    133: /**
                    134:  * hasExternalSubset:
1.16      daniel    135:  * @ctx: the user data (XML parser context)
1.10      daniel    136:  *
                    137:  * Does this document has an external subset
                    138:  *
                    139:  * Returns 1 if true
                    140:  */
                    141: int
1.11      daniel    142: hasExternalSubset(void *ctx)
1.10      daniel    143: {
1.11      daniel    144:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    145:     return(ctxt->myDoc->extSubset != NULL);
                    146: }
                    147: 
                    148: /**
1.19      veillard  149:  * internalSubset:
1.58      daniel    150:  * @ctx:  the user data (XML parser context)
                    151:  * @name:  the root element name
                    152:  * @ExternalID:  the external ID
                    153:  * @SystemID:  the SYSTEM ID (e.g. filename or URL)
1.10      daniel    154:  *
1.41      daniel    155:  * Callback on internal subset declaration.
1.10      daniel    156:  */
                    157: void
1.34      daniel    158: internalSubset(void *ctx, const xmlChar *name,
                    159:               const xmlChar *ExternalID, const xmlChar *SystemID)
1.10      daniel    160: {
1.11      daniel    161:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.66      daniel    162:     xmlDtdPtr dtd;
1.10      daniel    163: #ifdef DEBUG_SAX
                    164:     fprintf(stderr, "SAX.internalSubset(%s, %s, %s)\n",
                    165:             name, ExternalID, SystemID);
                    166: #endif
1.66      daniel    167: 
1.67      daniel    168:     if (ctxt->myDoc == NULL)
                    169:        return;
1.66      daniel    170:     dtd = xmlGetIntSubset(ctxt->myDoc);
                    171:     if (dtd != NULL) {
1.72    ! veillard  172:        if (ctxt->html)
        !           173:            return;
1.66      daniel    174:        xmlUnlinkNode((xmlNodePtr) dtd);
                    175:        xmlFreeDtd(dtd);
1.67      daniel    176:        ctxt->myDoc->intSubset = NULL;
1.66      daniel    177:     }
1.67      daniel    178:     ctxt->myDoc->intSubset = 
                    179:        xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
1.49      daniel    180: }
                    181: 
                    182: /**
                    183:  * externalSubset:
                    184:  * @ctx: the user data (XML parser context)
1.58      daniel    185:  * @name:  the root element name
                    186:  * @ExternalID:  the external ID
                    187:  * @SystemID:  the SYSTEM ID (e.g. filename or URL)
1.49      daniel    188:  *
                    189:  * Callback on external subset declaration.
                    190:  */
                    191: void
                    192: externalSubset(void *ctx, const xmlChar *name,
                    193:               const xmlChar *ExternalID, const xmlChar *SystemID)
                    194: {
                    195:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                    196: #ifdef DEBUG_SAX
                    197:     fprintf(stderr, "SAX.externalSubset(%s, %s, %s)\n",
                    198:             name, ExternalID, SystemID);
                    199: #endif
1.24      daniel    200:     if (((ExternalID != NULL) || (SystemID != NULL)) &&
                    201:         (ctxt->validate && ctxt->wellFormed && ctxt->myDoc)) {
                    202:        /*
                    203:         * Try to fetch and parse the external subset.
                    204:         */
1.49      daniel    205:        xmlParserInputPtr oldinput;
                    206:        int oldinputNr;
                    207:        int oldinputMax;
                    208:        xmlParserInputPtr *oldinputTab;
1.50      daniel    209:        int oldwellFormed;
1.24      daniel    210:        xmlParserInputPtr input = NULL;
                    211:        xmlCharEncoding enc;
1.68      veillard  212:        int oldcharset;
1.24      daniel    213: 
                    214:        /*
                    215:         * Ask the Entity resolver to load the damn thing
                    216:         */
1.49      daniel    217:        if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
                    218:            input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
1.24      daniel    219:                                                SystemID);
                    220:        if (input == NULL) {
                    221:            return;
                    222:        }
                    223: 
1.50      daniel    224:        xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
                    225: 
1.49      daniel    226:        /*
                    227:         * make sure we won't destroy the main document context
                    228:         */
                    229:        oldinput = ctxt->input;
                    230:        oldinputNr = ctxt->inputNr;
                    231:        oldinputMax = ctxt->inputMax;
                    232:        oldinputTab = ctxt->inputTab;
1.50      daniel    233:        oldwellFormed = ctxt->wellFormed;
1.62      daniel    234:        oldcharset = ctxt->charset;
1.49      daniel    235: 
                    236:        ctxt->inputTab = (xmlParserInputPtr *)
                    237:                         xmlMalloc(5 * sizeof(xmlParserInputPtr));
                    238:        if (ctxt->inputTab == NULL) {
                    239:            ctxt->errNo = XML_ERR_NO_MEMORY;
                    240:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    241:                ctxt->sax->error(ctxt->userData, 
                    242:                     "externalSubset: out of memory\n");
                    243:            ctxt->errNo = XML_ERR_NO_MEMORY;
                    244:            ctxt->input = oldinput;
                    245:            ctxt->inputNr = oldinputNr;
                    246:            ctxt->inputMax = oldinputMax;
                    247:            ctxt->inputTab = oldinputTab;
1.62      daniel    248:            ctxt->charset = oldcharset;
1.49      daniel    249:            return;
                    250:        }
                    251:        ctxt->inputNr = 0;
                    252:        ctxt->inputMax = 5;
                    253:        ctxt->input = NULL;
                    254:        xmlPushInput(ctxt, input);
1.43      daniel    255: 
1.24      daniel    256:        /*
1.43      daniel    257:         * On the fly encoding conversion if needed
1.24      daniel    258:         */
1.49      daniel    259:        enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
                    260:        xmlSwitchEncoding(ctxt, enc);
1.24      daniel    261: 
                    262:        if (input->filename == NULL)
1.28      daniel    263:            input->filename = (char *) xmlStrdup(SystemID);
1.24      daniel    264:        input->line = 1;
                    265:        input->col = 1;
1.49      daniel    266:        input->base = ctxt->input->cur;
                    267:        input->cur = ctxt->input->cur;
1.24      daniel    268:        input->free = NULL;
                    269: 
                    270:        /*
                    271:         * let's parse that entity knowing it's an external subset.
                    272:         */
1.49      daniel    273:        xmlParseExternalSubset(ctxt, ExternalID, SystemID);
                    274: 
                    275:         /*
                    276:         * Free up the external entities
                    277:         */
1.24      daniel    278: 
1.49      daniel    279:        while (ctxt->inputNr > 1)
                    280:            xmlPopInput(ctxt);
                    281:        xmlFreeInputStream(ctxt->input);
                    282:         xmlFree(ctxt->inputTab);
                    283: 
                    284:        /*
                    285:         * Restore the parsing context of the main entity
                    286:         */
                    287:        ctxt->input = oldinput;
                    288:        ctxt->inputNr = oldinputNr;
                    289:        ctxt->inputMax = oldinputMax;
                    290:        ctxt->inputTab = oldinputTab;
1.62      daniel    291:        ctxt->charset = oldcharset;
1.52      daniel    292:        /* ctxt->wellFormed = oldwellFormed; */
1.12      daniel    293:     }
1.10      daniel    294: }
                    295: 
                    296: /**
1.5       daniel    297:  * resolveEntity:
1.16      daniel    298:  * @ctx: the user data (XML parser context)
1.5       daniel    299:  * @publicId: The public ID of the entity
                    300:  * @systemId: The system ID of the entity
                    301:  *
1.41      daniel    302:  * The entity loader, to control the loading of external entities,
                    303:  * the application can either:
                    304:  *    - override this resolveEntity() callback in the SAX block
                    305:  *    - or better use the xmlSetExternalEntityLoader() function to
                    306:  *      set up it's own entity resolution routine
1.5       daniel    307:  *
1.8       daniel    308:  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1.5       daniel    309:  */
                    310: xmlParserInputPtr
1.34      daniel    311: resolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
1.5       daniel    312: {
1.12      daniel    313:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2       daniel    314: 
                    315: #ifdef DEBUG_SAX
                    316:     fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
                    317: #endif
1.5       daniel    318: 
1.41      daniel    319:     return(xmlLoadExternalEntity((const char *) systemId,
                    320:                                 (const char *) publicId, ctxt));
1.1       daniel    321: }
                    322: 
1.5       daniel    323: /**
1.10      daniel    324:  * getEntity:
1.16      daniel    325:  * @ctx: the user data (XML parser context)
1.10      daniel    326:  * @name: The entity name
                    327:  *
                    328:  * Get an entity by name
                    329:  *
1.13      daniel    330:  * Returns the xmlEntityPtr if found.
1.10      daniel    331:  */
                    332: xmlEntityPtr
1.34      daniel    333: getEntity(void *ctx, const xmlChar *name)
1.10      daniel    334: {
1.11      daniel    335:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    336:     xmlEntityPtr ret;
                    337: 
                    338: #ifdef DEBUG_SAX
                    339:     fprintf(stderr, "SAX.getEntity(%s)\n", name);
                    340: #endif
                    341: 
                    342:     ret = xmlGetDocEntity(ctxt->myDoc, name);
1.71      veillard  343:     if ((ret != NULL) && (ctxt->validate) && (ret->children == NULL) &&
                    344:        (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
                    345:        /*
                    346:         * for validation purposes we really need to fetch and
                    347:         * parse the external entity
                    348:         */
                    349:        int parse;
                    350:        xmlNodePtr children;
                    351: 
                    352:         parse = xmlParseCtxtExternalEntity(ctxt,
                    353:                  ret->SystemID, ret->ExternalID, &children);
                    354:        xmlAddChildList((xmlNodePtr) ret, children);
                    355:     }
1.10      daniel    356:     return(ret);
                    357: }
                    358: 
1.20      daniel    359: /**
                    360:  * getParameterEntity:
                    361:  * @ctx: the user data (XML parser context)
                    362:  * @name: The entity name
                    363:  *
                    364:  * Get a parameter entity by name
                    365:  *
                    366:  * Returns the xmlEntityPtr if found.
                    367:  */
                    368: xmlEntityPtr
1.34      daniel    369: getParameterEntity(void *ctx, const xmlChar *name)
1.20      daniel    370: {
                    371:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                    372:     xmlEntityPtr ret;
                    373: 
                    374: #ifdef DEBUG_SAX
                    375:     fprintf(stderr, "SAX.getParameterEntity(%s)\n", name);
                    376: #endif
                    377: 
                    378:     ret = xmlGetParameterEntity(ctxt->myDoc, name);
                    379:     return(ret);
                    380: }
                    381: 
1.10      daniel    382: 
                    383: /**
                    384:  * entityDecl:
1.16      daniel    385:  * @ctx: the user data (XML parser context)
1.10      daniel    386:  * @name:  the entity name 
                    387:  * @type:  the entity type 
                    388:  * @publicId: The public ID of the entity
                    389:  * @systemId: The system ID of the entity
                    390:  * @content: the entity value (without processing).
                    391:  *
                    392:  * An entity definition has been parsed
                    393:  */
                    394: void
1.34      daniel    395: entityDecl(void *ctx, const xmlChar *name, int type,
                    396:           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1.10      daniel    397: {
1.11      daniel    398:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    399: 
                    400: #ifdef DEBUG_SAX
                    401:     fprintf(stderr, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
                    402:             name, type, publicId, systemId, content);
                    403: #endif
1.50      daniel    404:     if (ctxt->inSubset == 1)
1.51      daniel    405:        xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
                    406:                              systemId, content);
1.50      daniel    407:     else if (ctxt->inSubset == 2)
1.51      daniel    408:        xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
                    409:                              systemId, content);
1.50      daniel    410:     else {
                    411:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    412:            ctxt->sax->error(ctxt, 
                    413:             "SAX.entityDecl(%s) called while not in subset\n", name);
                    414:     }
1.10      daniel    415: }
                    416: 
                    417: /**
                    418:  * attributeDecl:
1.16      daniel    419:  * @ctx: the user data (XML parser context)
1.58      daniel    420:  * @elem:  the name of the element
1.48      daniel    421:  * @fullname:  the attribute name 
1.10      daniel    422:  * @type:  the attribute type 
1.58      daniel    423:  * @def:  the type of default value
                    424:  * @defaultValue: the attribute default value
                    425:  * @tree:  the tree of enumerated value set
1.10      daniel    426:  *
                    427:  * An attribute definition has been parsed
                    428:  */
                    429: void
1.48      daniel    430: attributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
1.34      daniel    431:               int type, int def, const xmlChar *defaultValue,
1.10      daniel    432:              xmlEnumerationPtr tree)
                    433: {
1.11      daniel    434:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.21      daniel    435:     xmlAttributePtr attr;
1.48      daniel    436:     xmlChar *name = NULL, *prefix = NULL;
1.10      daniel    437: 
                    438: #ifdef DEBUG_SAX
                    439:     fprintf(stderr, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1.48      daniel    440:             elem, fullname, type, def, defaultValue);
1.10      daniel    441: #endif
1.48      daniel    442:     name = xmlSplitQName(ctxt, fullname, &prefix);
1.50      daniel    443:     if (ctxt->inSubset == 1)
                    444:        attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
1.68      veillard  445:               name, prefix, (xmlAttributeType) type,
                    446:               (xmlAttributeDefault) def, defaultValue, tree);
1.50      daniel    447:     else if (ctxt->inSubset == 2)
                    448:        attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
1.68      veillard  449:           name, prefix, (xmlAttributeType) type, 
                    450:           (xmlAttributeDefault) def, defaultValue, tree);
1.50      daniel    451:     else {
                    452:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    453:            ctxt->sax->error(ctxt, 
                    454:             "SAX.attributeDecl(%s) called while not in subset\n", name);
                    455:        return;
                    456:     }
1.21      daniel    457:     if (attr == 0) ctxt->valid = 0;
1.23      daniel    458:     if (ctxt->validate && ctxt->wellFormed &&
                    459:         ctxt->myDoc && ctxt->myDoc->intSubset)
1.21      daniel    460:        ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
                    461:                                                attr);
1.48      daniel    462:     if (prefix != NULL)
                    463:        xmlFree(prefix);
                    464:     if (name != NULL)
                    465:        xmlFree(name);
1.10      daniel    466: }
                    467: 
                    468: /**
                    469:  * elementDecl:
1.16      daniel    470:  * @ctx: the user data (XML parser context)
1.10      daniel    471:  * @name:  the element name 
                    472:  * @type:  the element type 
1.58      daniel    473:  * @content: the element value tree
1.10      daniel    474:  *
                    475:  * An element definition has been parsed
                    476:  */
                    477: void
1.34      daniel    478: elementDecl(void *ctx, const xmlChar *name, int type,
1.10      daniel    479:            xmlElementContentPtr content)
                    480: {
1.11      daniel    481:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.50      daniel    482:     xmlElementPtr elem = NULL;
1.10      daniel    483: 
                    484: #ifdef DEBUG_SAX
                    485:     fprintf(stderr, "SAX.elementDecl(%s, %d, ...)\n",
1.48      daniel    486:             fullname, type);
1.10      daniel    487: #endif
1.21      daniel    488:     
1.50      daniel    489:     if (ctxt->inSubset == 1)
                    490:        elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
1.68      veillard  491:                              name, (xmlElementTypeVal) type, content);
1.50      daniel    492:     else if (ctxt->inSubset == 2)
                    493:        elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
1.68      veillard  494:                              name, (xmlElementTypeVal) type, content);
1.50      daniel    495:     else {
                    496:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    497:            ctxt->sax->error(ctxt, 
                    498:             "SAX.elementDecl(%s) called while not in subset\n", name);
                    499:        return;
                    500:     }
                    501:     if (elem == NULL) ctxt->valid = 0;
1.23      daniel    502:     if (ctxt->validate && ctxt->wellFormed &&
                    503:         ctxt->myDoc && ctxt->myDoc->intSubset)
1.21      daniel    504:        ctxt->valid &= xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
1.10      daniel    505: }
                    506: 
                    507: /**
1.5       daniel    508:  * notationDecl:
1.16      daniel    509:  * @ctx: the user data (XML parser context)
1.5       daniel    510:  * @name: The name of the notation
                    511:  * @publicId: The public ID of the entity
                    512:  * @systemId: The system ID of the entity
                    513:  *
1.1       daniel    514:  * What to do when a notation declaration has been parsed.
                    515:  */
1.5       daniel    516: void
1.34      daniel    517: notationDecl(void *ctx, const xmlChar *name,
                    518:             const xmlChar *publicId, const xmlChar *systemId)
1.5       daniel    519: {
1.11      daniel    520:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.50      daniel    521:     xmlNotationPtr nota = NULL;
1.21      daniel    522: 
1.2       daniel    523: #ifdef DEBUG_SAX
                    524:     fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
                    525: #endif
1.21      daniel    526: 
1.50      daniel    527:     if (ctxt->inSubset == 1)
                    528:        nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
                    529:                               publicId, systemId);
                    530:     else if (ctxt->inSubset == 2)
                    531:        nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
1.21      daniel    532:                               publicId, systemId);
1.50      daniel    533:     else {
                    534:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    535:            ctxt->sax->error(ctxt, 
                    536:             "SAX.notationDecl(%s) called while not in subset\n", name);
                    537:        return;
                    538:     }
                    539:     if (nota == NULL) ctxt->valid = 0;
1.23      daniel    540:     if (ctxt->validate && ctxt->wellFormed &&
                    541:         ctxt->myDoc && ctxt->myDoc->intSubset)
1.21      daniel    542:        ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
                    543:                                               nota);
1.1       daniel    544: }
                    545: 
1.5       daniel    546: /**
                    547:  * unparsedEntityDecl:
1.16      daniel    548:  * @ctx: the user data (XML parser context)
1.5       daniel    549:  * @name: The name of the entity
                    550:  * @publicId: The public ID of the entity
                    551:  * @systemId: The system ID of the entity
                    552:  * @notationName: the name of the notation
                    553:  *
1.1       daniel    554:  * What to do when an unparsed entity declaration is parsed
                    555:  */
1.5       daniel    556: void
1.34      daniel    557: unparsedEntityDecl(void *ctx, const xmlChar *name,
                    558:                   const xmlChar *publicId, const xmlChar *systemId,
                    559:                   const xmlChar *notationName)
1.5       daniel    560: {
1.28      daniel    561:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2       daniel    562: #ifdef DEBUG_SAX
                    563:     fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
                    564:             name, publicId, systemId, notationName);
                    565: #endif
1.28      daniel    566:     if (ctxt->validate && ctxt->wellFormed &&
                    567:         ctxt->myDoc && ctxt->myDoc->intSubset)
                    568:        ctxt->valid &= xmlValidateNotationUse(&ctxt->vctxt, ctxt->myDoc,
                    569:                                              notationName);
                    570:     xmlAddDocEntity(ctxt->myDoc, name,
                    571:                     XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
                    572:                    publicId, systemId, notationName);
1.1       daniel    573: }
                    574: 
1.5       daniel    575: /**
                    576:  * setDocumentLocator:
1.16      daniel    577:  * @ctx: the user data (XML parser context)
1.5       daniel    578:  * @loc: A SAX Locator
                    579:  *
1.1       daniel    580:  * Receive the document locator at startup, actually xmlDefaultSAXLocator
                    581:  * Everything is available on the context, so this is useless in our case.
                    582:  */
1.5       daniel    583: void
1.11      daniel    584: setDocumentLocator(void *ctx, xmlSAXLocatorPtr loc)
1.5       daniel    585: {
1.11      daniel    586:     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2       daniel    587: #ifdef DEBUG_SAX
                    588:     fprintf(stderr, "SAX.setDocumentLocator()\n");
                    589: #endif
1.1       daniel    590: }
                    591: 
1.5       daniel    592: /**
                    593:  * startDocument:
1.16      daniel    594:  * @ctx: the user data (XML parser context)
1.5       daniel    595:  *
1.1       daniel    596:  * called when the document start being processed.
                    597:  */
1.5       daniel    598: void
1.11      daniel    599: startDocument(void *ctx)
1.5       daniel    600: {
1.11      daniel    601:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    602:     xmlDocPtr doc;
                    603: 
1.2       daniel    604: #ifdef DEBUG_SAX
                    605:     fprintf(stderr, "SAX.startDocument()\n");
                    606: #endif
1.66      daniel    607:     if (ctxt->html) {
                    608:        if (ctxt->myDoc == NULL)
1.69      veillard  609: #ifdef LIBXML_HTML_ENABLED
1.72    ! veillard  610:            ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
1.69      veillard  611: #else
                    612:         fprintf(stderr, "libxml2 built without HTML support\n");
                    613: #endif
1.66      daniel    614:     } else {
                    615:        doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
                    616:        if (doc != NULL) {
                    617:            if (ctxt->encoding != NULL)
                    618:                doc->encoding = xmlStrdup(ctxt->encoding);
                    619:            else
                    620:                doc->encoding = NULL;
                    621:            doc->standalone = ctxt->standalone;
                    622:        }
1.10      daniel    623:     }
1.70      veillard  624:     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
                    625:        (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
                    626:         ctxt->myDoc->URL = xmlStrdup((xmlChar *) ctxt->input->filename);
                    627:     }
1.1       daniel    628: }
                    629: 
1.5       daniel    630: /**
                    631:  * endDocument:
1.16      daniel    632:  * @ctx: the user data (XML parser context)
1.5       daniel    633:  *
1.1       daniel    634:  * called when the document end has been detected.
                    635:  */
1.5       daniel    636: void
1.11      daniel    637: endDocument(void *ctx)
1.5       daniel    638: {
1.31      daniel    639:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2       daniel    640: #ifdef DEBUG_SAX
                    641:     fprintf(stderr, "SAX.endDocument()\n");
                    642: #endif
1.31      daniel    643:     if (ctxt->validate && ctxt->wellFormed &&
                    644:         ctxt->myDoc && ctxt->myDoc->intSubset)
                    645:        ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
1.59      daniel    646: 
                    647:     /*
                    648:      * Grab the encoding if it was added on-the-fly
                    649:      */
                    650:     if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
                    651:        (ctxt->myDoc->encoding == NULL)) {
                    652:        ctxt->myDoc->encoding = ctxt->encoding;
                    653:        ctxt->encoding = NULL;
                    654:     }
1.62      daniel    655:     if ((ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
                    656:        (ctxt->myDoc->encoding == NULL)) {
                    657:        ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
                    658:     }
                    659:     if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
                    660:        (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
                    661:        ctxt->myDoc->charset = ctxt->charset;
                    662:     }
1.1       daniel    663: }
                    664: 
1.5       daniel    665: /**
1.10      daniel    666:  * attribute:
1.16      daniel    667:  * @ctx: the user data (XML parser context)
1.58      daniel    668:  * @fullname:  The attribute name, including namespace prefix
1.10      daniel    669:  * @value:  The attribute value
                    670:  *
                    671:  * Handle an attribute that has been read by the parser.
                    672:  * The default handling is to convert the attribute into an
                    673:  * DOM subtree and past it in a new xmlAttr element added to
                    674:  * the element.
                    675:  */
                    676: void
1.34      daniel    677: attribute(void *ctx, const xmlChar *fullname, const xmlChar *value)
1.10      daniel    678: {
1.11      daniel    679:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    680:     xmlAttrPtr ret;
1.34      daniel    681:     xmlChar *name;
                    682:     xmlChar *ns;
1.56      daniel    683:     xmlChar *nval;
1.29      daniel    684:     xmlNsPtr namespace;
1.10      daniel    685: 
                    686: /****************
                    687: #ifdef DEBUG_SAX
                    688:     fprintf(stderr, "SAX.attribute(%s, %s)\n", fullname, value);
                    689: #endif
                    690:  ****************/
                    691:     /*
                    692:      * Split the full name into a namespace prefix and the tag name
                    693:      */
1.48      daniel    694:     name = xmlSplitQName(ctxt, fullname, &ns);
1.10      daniel    695: 
                    696:     /*
1.55      daniel    697:      * Do the last stave of the attribute normalization
                    698:      */
1.65      daniel    699:     if (ctxt->html)
                    700:        nval = NULL;
                    701:     else
                    702:        nval = xmlValidNormalizeAttributeValue(ctxt->myDoc,
1.56      daniel    703:                               ctxt->node, fullname, value);
                    704:     if (nval != NULL)
                    705:        value = nval;
1.55      daniel    706: 
                    707:     /*
1.10      daniel    708:      * Check whether it's a namespace definition
                    709:      */
1.65      daniel    710:     if ((!ctxt->html) && (ns == NULL) &&
1.10      daniel    711:         (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
                    712:         (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
1.60      daniel    713:        xmlURIPtr uri;
                    714: 
                    715:        uri = xmlParseURI((const char *)value);
                    716:        if (uri == NULL) {
                    717:            if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
                    718:                ctxt->sax->warning(ctxt->userData, 
                    719:                     "nmlns: %s not a valid URI\n", value);
                    720:        } else {
1.61      daniel    721:            if (uri->scheme == NULL) {
1.60      daniel    722:                if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
                    723:                    ctxt->sax->warning(ctxt->userData, 
                    724:                         "nmlns: URI %s is not absolute\n", value);
                    725:            }
                    726:            xmlFreeURI(uri);
                    727:        }
                    728: 
1.10      daniel    729:        /* a default namespace definition */
                    730:        xmlNewNs(ctxt->node, value, NULL);
                    731:        if (name != NULL) 
1.30      daniel    732:            xmlFree(name);
1.55      daniel    733:        if (nval != NULL)
                    734:            xmlFree(nval);
1.10      daniel    735:        return;
                    736:     }
1.65      daniel    737:     if ((!ctxt->html) &&
                    738:        (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
1.10      daniel    739:         (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
1.54      daniel    740:        /*
                    741:         * Validate also for namespace decls, they are attributes from
                    742:         * an XML-1.0 perspective
                    743:         TODO ... doesn't map well with current API
                    744:         if (ctxt->validate && ctxt->wellFormed &&
                    745:            ctxt->myDoc && ctxt->myDoc->intSubset)
                    746:            ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
                    747:                                               ctxt->node, ret, value);
                    748:         */
1.10      daniel    749:        /* a standard namespace definition */
                    750:        xmlNewNs(ctxt->node, value, name);
1.30      daniel    751:        xmlFree(ns);
1.10      daniel    752:        if (name != NULL) 
1.30      daniel    753:            xmlFree(name);
1.55      daniel    754:        if (nval != NULL)
                    755:            xmlFree(nval);
1.10      daniel    756:        return;
                    757:     }
                    758: 
1.38      daniel    759:     if (ns != NULL)
                    760:        namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
                    761:     else {
                    762:        namespace = NULL;
                    763:     }
                    764: 
1.29      daniel    765:     /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
                    766:     ret = xmlNewNsProp(ctxt->node, namespace, name, NULL);
1.22      daniel    767: 
1.26      daniel    768:     if (ret != NULL) {
1.46      daniel    769:         if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
                    770:            xmlNodePtr tmp;
                    771: 
1.44      daniel    772:            ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
1.46      daniel    773:            tmp = ret->children;
                    774:            while (tmp != NULL) {
                    775:                tmp->parent = (xmlNodePtr) ret;
                    776:                if (tmp->next == NULL)
                    777:                    ret->last = tmp;
                    778:                tmp = tmp->next;
                    779:            }
1.65      daniel    780:        } else if (value != NULL) {
1.44      daniel    781:            ret->children = xmlNewDocText(ctxt->myDoc, value);
1.46      daniel    782:            ret->last = ret->children;
                    783:            if (ret->children != NULL)
                    784:                ret->children->parent = (xmlNodePtr) ret;
                    785:        }
1.26      daniel    786:     }
1.22      daniel    787: 
1.65      daniel    788:     if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
1.56      daniel    789:         ctxt->myDoc && ctxt->myDoc->intSubset) {
                    790:        
                    791:        /*
                    792:         * If we don't substitute entities, the validation should be
                    793:         * done on a value with replaced entities anyway.
                    794:         */
                    795:         if (!ctxt->replaceEntities) {
                    796:            xmlChar *val;
                    797: 
                    798:            ctxt->depth++;
                    799:            val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
                    800:                                          0,0,0);
                    801:            ctxt->depth--;
                    802:            if (val == NULL)
                    803:                ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
                    804:                                ctxt->myDoc, ctxt->node, ret, value);
                    805:            else {
                    806:                ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
                    807:                                ctxt->myDoc, ctxt->node, ret, val);
                    808:                 xmlFree(val);
                    809:            }
                    810:        } else {
                    811:            ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
1.22      daniel    812:                                               ctxt->node, ret, value);
1.56      daniel    813:        }
                    814:     } else {
1.26      daniel    815:         /*
                    816:         * when validating, the ID registration is done at the attribute
                    817:         * validation level. Otherwise we have to do specific handling here.
                    818:         */
                    819:        if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
                    820:            xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
1.31      daniel    821:        else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
                    822:            xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
1.26      daniel    823:     }
1.22      daniel    824: 
1.55      daniel    825:     if (nval != NULL)
                    826:        xmlFree(nval);
1.10      daniel    827:     if (name != NULL) 
1.30      daniel    828:        xmlFree(name);
1.10      daniel    829:     if (ns != NULL) 
1.30      daniel    830:        xmlFree(ns);
1.10      daniel    831: }
                    832: 
                    833: /**
1.5       daniel    834:  * startElement:
1.16      daniel    835:  * @ctx: the user data (XML parser context)
1.58      daniel    836:  * @fullname:  The element name, including namespace prefix
1.10      daniel    837:  * @atts:  An array of name/value attributes pairs, NULL terminated
1.5       daniel    838:  *
1.1       daniel    839:  * called when an opening tag has been processed.
                    840:  */
1.5       daniel    841: void
1.34      daniel    842: startElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
1.5       daniel    843: {
1.11      daniel    844:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    845:     xmlNodePtr ret;
                    846:     xmlNodePtr parent = ctxt->node;
                    847:     xmlNsPtr ns;
1.34      daniel    848:     xmlChar *name;
                    849:     xmlChar *prefix;
                    850:     const xmlChar *att;
                    851:     const xmlChar *value;
1.10      daniel    852:     int i;
                    853: 
1.2       daniel    854: #ifdef DEBUG_SAX
1.10      daniel    855:     fprintf(stderr, "SAX.startElement(%s)\n", fullname);
1.2       daniel    856: #endif
1.33      daniel    857: 
                    858:     /*
                    859:      * First check on validity:
                    860:      */
                    861:     if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) && 
                    862:         ((ctxt->myDoc->intSubset == NULL) ||
                    863:         ((ctxt->myDoc->intSubset->notations == NULL) && 
                    864:          (ctxt->myDoc->intSubset->elements == NULL) &&
                    865:          (ctxt->myDoc->intSubset->attributes == NULL) && 
                    866:          (ctxt->myDoc->intSubset->entities == NULL)))) {
                    867:        if (ctxt->vctxt.error != NULL) {
                    868:             ctxt->vctxt.error(ctxt->vctxt.userData,
                    869:              "Validation failed: no DTD found !\n");
                    870:        }
                    871:        ctxt->validate = 0;
                    872:     }
                    873:        
                    874: 
1.10      daniel    875:     /*
                    876:      * Split the full name into a namespace prefix and the tag name
                    877:      */
1.48      daniel    878:     name = xmlSplitQName(ctxt, fullname, &prefix);
1.10      daniel    879: 
                    880: 
                    881:     /*
                    882:      * Note : the namespace resolution is deferred until the end of the
                    883:      *        attributes parsing, since local namespace can be defined as
                    884:      *        an attribute at this level.
                    885:      */
                    886:     ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
                    887:     if (ret == NULL) return;
1.44      daniel    888:     if (ctxt->myDoc->children == NULL) {
1.26      daniel    889: #ifdef DEBUG_SAX_TREE
                    890:        fprintf(stderr, "Setting %s as root\n", name);
                    891: #endif
1.45      daniel    892:         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1.26      daniel    893:     } else if (parent == NULL) {
1.44      daniel    894:         parent = ctxt->myDoc->children;
1.26      daniel    895:     }
1.63      daniel    896:     ctxt->nodemem = -1;
1.10      daniel    897: 
                    898:     /*
                    899:      * We are parsing a new node.
                    900:      */
1.26      daniel    901: #ifdef DEBUG_SAX_TREE
                    902:     fprintf(stderr, "pushing(%s)\n", name);
                    903: #endif
1.10      daniel    904:     nodePush(ctxt, ret);
                    905: 
                    906:     /*
                    907:      * Link the child element
                    908:      */
1.26      daniel    909:     if (parent != NULL) {
                    910:         if (parent->type == XML_ELEMENT_NODE) {
                    911: #ifdef DEBUG_SAX_TREE
                    912:            fprintf(stderr, "adding child %s to %s\n", name, parent->name);
                    913: #endif
                    914:            xmlAddChild(parent, ret);
                    915:        } else {
                    916: #ifdef DEBUG_SAX_TREE
                    917:            fprintf(stderr, "adding sibling %s to ", name);
                    918:            xmlDebugDumpOneNode(stderr, parent, 0);
                    919: #endif
                    920:            xmlAddSibling(parent, ret);
                    921:        }
                    922:     }
1.10      daniel    923: 
1.54      daniel    924:     /*
1.29      daniel    925:      * process all the attributes whose name start with "xml"
1.10      daniel    926:      */
                    927:     if (atts != NULL) {
                    928:         i = 0;
                    929:        att = atts[i++];
                    930:        value = atts[i++];
1.65      daniel    931:        if (!ctxt->html) {
                    932:            while ((att != NULL) && (value != NULL)) {
                    933:                if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l'))
                    934:                    attribute(ctxt, att, value);
1.29      daniel    935: 
1.65      daniel    936:                att = atts[i++];
                    937:                value = atts[i++];
                    938:            }
1.29      daniel    939:        }
                    940:     }
                    941: 
                    942:     /*
1.64      daniel    943:      * Search the namespace, note that since the attributes have been
                    944:      * processed, the local namespaces are available.
                    945:      */
                    946:     ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
                    947:     if ((ns == NULL) && (parent != NULL))
                    948:        ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
                    949:     xmlSetNs(ret, ns);
                    950: 
                    951:     /*
1.29      daniel    952:      * process all the other attributes
                    953:      */
                    954:     if (atts != NULL) {
                    955:         i = 0;
                    956:        att = atts[i++];
                    957:        value = atts[i++];
1.65      daniel    958:        if (ctxt->html) {
                    959:            while (att != NULL) {
1.29      daniel    960:                attribute(ctxt, att, value);
1.65      daniel    961:                att = atts[i++];
                    962:                value = atts[i++];
                    963:            }
                    964:        } else {
                    965:            while ((att != NULL) && (value != NULL)) {
                    966:                if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l'))
                    967:                    attribute(ctxt, att, value);
                    968: 
                    969:                /*
                    970:                 * Next ones
                    971:                 */
                    972:                att = atts[i++];
                    973:                value = atts[i++];
                    974:            }
1.10      daniel    975:        }
                    976:     }
                    977: 
                    978:     /*
1.64      daniel    979:      * If it's the Document root, finish the Dtd validation and
                    980:      * check the document root element for validity
1.10      daniel    981:      */
1.64      daniel    982:     if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) {
                    983:        ctxt->valid &= xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
                    984:        ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
                    985:        ctxt->vctxt.finishDtd = 1;
                    986:     }
1.10      daniel    987: 
                    988:     if (prefix != NULL)
1.30      daniel    989:        xmlFree(prefix);
1.10      daniel    990:     if (name != NULL)
1.30      daniel    991:        xmlFree(name);
1.10      daniel    992: 
1.1       daniel    993: }
                    994: 
1.5       daniel    995: /**
                    996:  * endElement:
1.16      daniel    997:  * @ctx: the user data (XML parser context)
1.5       daniel    998:  * @name:  The element name
                    999:  *
1.1       daniel   1000:  * called when the end of an element has been detected.
                   1001:  */
1.5       daniel   1002: void
1.34      daniel   1003: endElement(void *ctx, const xmlChar *name)
1.5       daniel   1004: {
1.11      daniel   1005:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel   1006:     xmlParserNodeInfo node_info;
                   1007:     xmlNodePtr cur = ctxt->node;
                   1008: 
1.2       daniel   1009: #ifdef DEBUG_SAX
1.10      daniel   1010:     if (name == NULL)
                   1011:         fprintf(stderr, "SAX.endElement(NULL)\n");
                   1012:     else
                   1013:        fprintf(stderr, "SAX.endElement(%s)\n", name);
                   1014: #endif
                   1015:     
                   1016:     /* Capture end position and add node */
                   1017:     if (cur != NULL && ctxt->record_info) {
                   1018:       node_info.end_pos = ctxt->input->cur - ctxt->input->base;
                   1019:       node_info.end_line = ctxt->input->line;
                   1020:       node_info.node = cur;
                   1021:       xmlParserAddNodeInfo(ctxt, &node_info);
                   1022:     }
1.63      daniel   1023:     ctxt->nodemem = -1;
1.10      daniel   1024: 
1.23      daniel   1025:     if (ctxt->validate && ctxt->wellFormed &&
                   1026:         ctxt->myDoc && ctxt->myDoc->intSubset)
1.22      daniel   1027:         ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
                   1028:                                             cur);
                   1029: 
                   1030:     
1.10      daniel   1031:     /*
                   1032:      * end of parsing of this node.
                   1033:      */
1.26      daniel   1034: #ifdef DEBUG_SAX_TREE
                   1035:     fprintf(stderr, "popping(%s)\n", cur->name);
                   1036: #endif
1.10      daniel   1037:     nodePop(ctxt);
1.1       daniel   1038: }
                   1039: 
1.5       daniel   1040: /**
1.10      daniel   1041:  * reference:
1.16      daniel   1042:  * @ctx: the user data (XML parser context)
1.10      daniel   1043:  * @name:  The entity name
1.5       daniel   1044:  *
1.10      daniel   1045:  * called when an entity reference is detected. 
1.5       daniel   1046:  */
                   1047: void
1.34      daniel   1048: reference(void *ctx, const xmlChar *name)
1.5       daniel   1049: {
1.11      daniel   1050:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel   1051:     xmlNodePtr ret;
                   1052: 
1.5       daniel   1053: #ifdef DEBUG_SAX
1.10      daniel   1054:     fprintf(stderr, "SAX.reference(%s)\n", name);
1.5       daniel   1055: #endif
1.42      daniel   1056:     if (name[0] == '#')
                   1057:        ret = xmlNewCharRef(ctxt->myDoc, name);
                   1058:     else
                   1059:        ret = xmlNewReference(ctxt->myDoc, name);
1.26      daniel   1060: #ifdef DEBUG_SAX_TREE
                   1061:     fprintf(stderr, "add reference %s to %s \n", name, ctxt->node->name);
                   1062: #endif
1.10      daniel   1063:     xmlAddChild(ctxt->node, ret);
1.5       daniel   1064: }
                   1065: 
                   1066: /**
                   1067:  * characters:
1.16      daniel   1068:  * @ctx: the user data (XML parser context)
1.34      daniel   1069:  * @ch:  a xmlChar string
                   1070:  * @len: the number of xmlChar
1.5       daniel   1071:  *
1.1       daniel   1072:  * receiving some chars from the parser.
                   1073:  * Question: how much at a time ???
                   1074:  */
1.5       daniel   1075: void
1.34      daniel   1076: characters(void *ctx, const xmlChar *ch, int len)
1.5       daniel   1077: {
1.11      daniel   1078:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2       daniel   1079:     xmlNodePtr lastChild;
                   1080: 
                   1081: #ifdef DEBUG_SAX
1.10      daniel   1082:     fprintf(stderr, "SAX.characters(%.30s, %d)\n", ch, len);
1.2       daniel   1083: #endif
                   1084:     /*
                   1085:      * Handle the data if any. If there is no child
                   1086:      * add it as content, otherwise if the last child is text,
                   1087:      * concatenate it, else create a new node of type text.
                   1088:      */
                   1089: 
1.36      daniel   1090:     if (ctxt->node == NULL) {
                   1091: #ifdef DEBUG_SAX_TREE
                   1092:        fprintf(stderr, "add chars: ctxt->node == NULL !\n");
                   1093: #endif
                   1094:         return;
                   1095:     }
1.2       daniel   1096:     lastChild = xmlGetLastChild(ctxt->node);
1.26      daniel   1097: #ifdef DEBUG_SAX_TREE
                   1098:     fprintf(stderr, "add chars to %s \n", ctxt->node->name);
                   1099: #endif
1.62      daniel   1100: 
                   1101:     /*
                   1102:      * Here we needed an accelerator mechanism in case of very large
                   1103:      * elements. Use an attribute in the structure !!!
                   1104:      */
1.63      daniel   1105:     if (lastChild == NULL) {
                   1106:        /* first node, first time */
1.10      daniel   1107:        xmlNodeAddContentLen(ctxt->node, ch, len);
1.63      daniel   1108: #ifndef XML_USE_BUFFER_CONTENT
                   1109:        if (ctxt->node->children != NULL) {
                   1110:            ctxt->nodelen = len;
                   1111:            ctxt->nodemem = len + 1;
                   1112:        }
                   1113: #endif
                   1114:     } else {
1.62      daniel   1115:        if (xmlNodeIsText(lastChild)) {
1.63      daniel   1116: #ifndef XML_USE_BUFFER_CONTENT
                   1117:            /*
                   1118:             * The whole point of maintaining nodelen and nodemem,
                   1119:             * xmlTextConcat is too costly, i.e. compute lenght,
                   1120:             * reallocate a new buffer, move data, append ch. Here
                   1121:             * We try to minimaze realloc() uses and avoid copying
                   1122:             * and recomputing lenght over and over.
                   1123:             */
                   1124:            if (ctxt->nodelen + len >= ctxt->nodemem) {
                   1125:                xmlChar *newbuf;
                   1126:                int size;
                   1127: 
                   1128:                size = ctxt->nodemem + len;
                   1129:                size *= 2;
                   1130:                 newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
                   1131:                if (newbuf == NULL) {
                   1132:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1133:                        ctxt->sax->error(ctxt->userData, 
                   1134:                             "SAX.characters(): out of memory\n");
                   1135:                    return;
                   1136:                }
                   1137:                ctxt->nodemem = size;
                   1138:                lastChild->content = newbuf;
                   1139:            }
                   1140:            memcpy(&lastChild->content[ctxt->nodelen], ch, len);
                   1141:            ctxt->nodelen += len;
                   1142:            lastChild->content[ctxt->nodelen] = 0;
                   1143: #else
1.10      daniel   1144:            xmlTextConcat(lastChild, ch, len);
1.63      daniel   1145: #endif
1.62      daniel   1146:        } else {
1.63      daniel   1147:            /* Mixed content, first time */
1.10      daniel   1148:            lastChild = xmlNewTextLen(ch, len);
1.2       daniel   1149:            xmlAddChild(ctxt->node, lastChild);
1.63      daniel   1150: #ifndef XML_USE_BUFFER_CONTENT
                   1151:            if (ctxt->node->children != NULL) {
                   1152:                ctxt->nodelen = len;
                   1153:                ctxt->nodemem = len + 1;
                   1154:            }
                   1155: #endif
1.2       daniel   1156:        }
                   1157:     }
1.1       daniel   1158: }
                   1159: 
1.5       daniel   1160: /**
                   1161:  * ignorableWhitespace:
1.16      daniel   1162:  * @ctx: the user data (XML parser context)
1.34      daniel   1163:  * @ch:  a xmlChar string
                   1164:  * @len: the number of xmlChar
1.5       daniel   1165:  *
1.1       daniel   1166:  * receiving some ignorable whitespaces from the parser.
                   1167:  * Question: how much at a time ???
                   1168:  */
1.5       daniel   1169: void
1.34      daniel   1170: ignorableWhitespace(void *ctx, const xmlChar *ch, int len)
1.5       daniel   1171: {
1.11      daniel   1172:     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2       daniel   1173: #ifdef DEBUG_SAX
1.10      daniel   1174:     fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
1.2       daniel   1175: #endif
1.1       daniel   1176: }
                   1177: 
1.5       daniel   1178: /**
                   1179:  * processingInstruction:
1.16      daniel   1180:  * @ctx: the user data (XML parser context)
1.5       daniel   1181:  * @target:  the target name
                   1182:  * @data: the PI data's
                   1183:  *
                   1184:  * A processing instruction has been parsed.
                   1185:  */
                   1186: void
1.34      daniel   1187: processingInstruction(void *ctx, const xmlChar *target,
                   1188:                       const xmlChar *data)
1.5       daniel   1189: {
1.26      daniel   1190:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                   1191:     xmlNodePtr ret;
                   1192:     xmlNodePtr parent = ctxt->node;
                   1193: 
1.2       daniel   1194: #ifdef DEBUG_SAX
                   1195:     fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
                   1196: #endif
1.26      daniel   1197: 
                   1198:     ret = xmlNewPI(target, data);
                   1199:     if (ret == NULL) return;
1.53      daniel   1200:     parent = ctxt->node;
                   1201: 
                   1202:     if (ctxt->inSubset == 1) {
                   1203:        xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
                   1204:        return;
                   1205:     } else if (ctxt->inSubset == 2) {
                   1206:        xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
                   1207:        return;
                   1208:     }
                   1209:     if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
1.26      daniel   1210: #ifdef DEBUG_SAX_TREE
                   1211:            fprintf(stderr, "Setting PI %s as root\n", target);
                   1212: #endif
1.45      daniel   1213:         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1.53      daniel   1214:        return;
1.26      daniel   1215:     }
1.53      daniel   1216:     if (parent->type == XML_ELEMENT_NODE) {
1.26      daniel   1217: #ifdef DEBUG_SAX_TREE
1.53      daniel   1218:        fprintf(stderr, "adding PI %s child to %s\n", target, parent->name);
1.26      daniel   1219: #endif
1.53      daniel   1220:        xmlAddChild(parent, ret);
                   1221:     } else {
1.26      daniel   1222: #ifdef DEBUG_SAX_TREE
1.53      daniel   1223:        fprintf(stderr, "adding PI %s sibling to ", target);
                   1224:        xmlDebugDumpOneNode(stderr, parent, 0);
1.26      daniel   1225: #endif
1.53      daniel   1226:        xmlAddSibling(parent, ret);
1.26      daniel   1227:     }
1.1       daniel   1228: }
                   1229: 
1.10      daniel   1230: /**
                   1231:  * globalNamespace:
1.16      daniel   1232:  * @ctx: the user data (XML parser context)
1.10      daniel   1233:  * @href:  the namespace associated URN
                   1234:  * @prefix: the namespace prefix
                   1235:  *
                   1236:  * An old global namespace has been parsed.
                   1237:  */
                   1238: void
1.34      daniel   1239: globalNamespace(void *ctx, const xmlChar *href, const xmlChar *prefix)
1.10      daniel   1240: {
1.11      daniel   1241:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel   1242: #ifdef DEBUG_SAX
                   1243:     fprintf(stderr, "SAX.globalNamespace(%s, %s)\n", href, prefix);
                   1244: #endif
                   1245:     xmlNewGlobalNs(ctxt->myDoc, href, prefix);
                   1246: }
                   1247: 
                   1248: /**
                   1249:  * setNamespace:
1.16      daniel   1250:  * @ctx: the user data (XML parser context)
1.10      daniel   1251:  * @name:  the namespace prefix
                   1252:  *
                   1253:  * Set the current element namespace.
                   1254:  */
1.58      daniel   1255: 
1.10      daniel   1256: void
1.34      daniel   1257: setNamespace(void *ctx, const xmlChar *name)
1.10      daniel   1258: {
1.11      daniel   1259:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel   1260:     xmlNsPtr ns;
                   1261:     xmlNodePtr parent;
                   1262: 
                   1263: #ifdef DEBUG_SAX
                   1264:     fprintf(stderr, "SAX.setNamespace(%s)\n", name);
                   1265: #endif
                   1266:     ns = xmlSearchNs(ctxt->myDoc, ctxt->node, name);
                   1267:     if (ns == NULL) { /* ctxt->node may not have a parent yet ! */
                   1268:         if (ctxt->nodeNr >= 2) {
                   1269:            parent = ctxt->nodeTab[ctxt->nodeNr - 2];
                   1270:            if (parent != NULL)
                   1271:                ns = xmlSearchNs(ctxt->myDoc, parent, name);
                   1272:        }
                   1273:     }
                   1274:     xmlSetNs(ctxt->node, ns);
                   1275: }
                   1276: 
                   1277: /**
                   1278:  * getNamespace:
1.16      daniel   1279:  * @ctx: the user data (XML parser context)
1.10      daniel   1280:  *
                   1281:  * Get the current element namespace.
1.58      daniel   1282:  *
                   1283:  * Returns the xmlNsPtr or NULL if none
1.10      daniel   1284:  */
1.58      daniel   1285: 
1.10      daniel   1286: xmlNsPtr
1.11      daniel   1287: getNamespace(void *ctx)
1.10      daniel   1288: {
1.11      daniel   1289:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel   1290:     xmlNsPtr ret;
                   1291: 
                   1292: #ifdef DEBUG_SAX
                   1293:     fprintf(stderr, "SAX.getNamespace()\n");
                   1294: #endif
                   1295:     ret = ctxt->node->ns;
                   1296:     return(ret);
                   1297: }
                   1298: 
                   1299: /**
                   1300:  * checkNamespace:
1.16      daniel   1301:  * @ctx: the user data (XML parser context)
1.10      daniel   1302:  * @namespace: the namespace to check against
                   1303:  *
                   1304:  * Check that the current element namespace is the same as the
                   1305:  * one read upon parsing.
1.58      daniel   1306:  *
                   1307:  * Returns 1 if true 0 otherwise
1.10      daniel   1308:  */
1.58      daniel   1309: 
1.10      daniel   1310: int
1.34      daniel   1311: checkNamespace(void *ctx, xmlChar *namespace)
1.10      daniel   1312: {
1.11      daniel   1313:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel   1314:     xmlNodePtr cur = ctxt->node;
                   1315: 
                   1316: #ifdef DEBUG_SAX
                   1317:     fprintf(stderr, "SAX.checkNamespace(%s)\n", namespace);
                   1318: #endif
                   1319: 
                   1320:     /*
                   1321:      * Check that the Name in the ETag is the same as in the STag.
                   1322:      */
                   1323:     if (namespace == NULL) {
                   1324:         if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
                   1325:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1326:                ctxt->sax->error(ctxt, 
                   1327:                 "End tags for %s don't hold the namespace %s\n",
                   1328:                                 cur->name, cur->ns->prefix);
                   1329:            ctxt->wellFormed = 0;
                   1330:        }
                   1331:     } else {
                   1332:         if ((cur->ns == NULL) || (cur->ns->prefix == NULL)) {
                   1333:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1334:                ctxt->sax->error(ctxt, 
                   1335:                 "End tags %s holds a prefix %s not used by the open tag\n",
                   1336:                                 cur->name, namespace);
                   1337:            ctxt->wellFormed = 0;
1.28      daniel   1338:        } else if (xmlStrcmp(namespace, cur->ns->prefix)) {
1.10      daniel   1339:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1340:                ctxt->sax->error(ctxt, 
                   1341:     "Start and End tags for %s don't use the same namespaces: %s and %s\n",
                   1342:                                 cur->name, cur->ns->prefix, namespace);
                   1343:            ctxt->wellFormed = 0;
                   1344:        } else
                   1345:            return(1);
                   1346:     }
                   1347:     return(0);
                   1348: }
                   1349: 
                   1350: /**
                   1351:  * namespaceDecl:
1.16      daniel   1352:  * @ctx: the user data (XML parser context)
1.10      daniel   1353:  * @href:  the namespace associated URN
                   1354:  * @prefix: the namespace prefix
                   1355:  *
                   1356:  * A namespace has been parsed.
                   1357:  */
                   1358: void
1.34      daniel   1359: namespaceDecl(void *ctx, const xmlChar *href, const xmlChar *prefix)
1.10      daniel   1360: {
1.11      daniel   1361:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel   1362: #ifdef DEBUG_SAX
                   1363:     if (prefix == NULL)
                   1364:        fprintf(stderr, "SAX.namespaceDecl(%s, NULL)\n", href);
                   1365:     else
                   1366:        fprintf(stderr, "SAX.namespaceDecl(%s, %s)\n", href, prefix);
                   1367: #endif
                   1368:     xmlNewNs(ctxt->node, href, prefix);
                   1369: }
                   1370: 
                   1371: /**
                   1372:  * comment:
1.16      daniel   1373:  * @ctx: the user data (XML parser context)
1.10      daniel   1374:  * @value:  the comment content
                   1375:  *
                   1376:  * A comment has been parsed.
                   1377:  */
                   1378: void
1.34      daniel   1379: comment(void *ctx, const xmlChar *value)
1.10      daniel   1380: {
1.11      daniel   1381:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.17      daniel   1382:     xmlNodePtr ret;
1.27      daniel   1383:     xmlNodePtr parent = ctxt->node;
1.17      daniel   1384: 
1.10      daniel   1385: #ifdef DEBUG_SAX
                   1386:     fprintf(stderr, "SAX.comment(%s)\n", value);
                   1387: #endif
1.17      daniel   1388:     ret = xmlNewDocComment(ctxt->myDoc, value);
1.27      daniel   1389:     if (ret == NULL) return;
                   1390: 
1.53      daniel   1391:     if (ctxt->inSubset == 1) {
                   1392:        xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
                   1393:        return;
                   1394:     } else if (ctxt->inSubset == 2) {
                   1395:        xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
                   1396:        return;
                   1397:     }
                   1398:     if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
1.27      daniel   1399: #ifdef DEBUG_SAX_TREE
                   1400:            fprintf(stderr, "Setting comment as root\n");
                   1401: #endif
1.45      daniel   1402:         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1.53      daniel   1403:        return;
1.27      daniel   1404:     }
1.53      daniel   1405:     if (parent->type == XML_ELEMENT_NODE) {
1.27      daniel   1406: #ifdef DEBUG_SAX_TREE
1.53      daniel   1407:        fprintf(stderr, "adding comment child to %s\n", parent->name);
1.27      daniel   1408: #endif
1.53      daniel   1409:        xmlAddChild(parent, ret);
                   1410:     } else {
1.27      daniel   1411: #ifdef DEBUG_SAX_TREE
1.53      daniel   1412:        fprintf(stderr, "adding comment sibling to ");
                   1413:        xmlDebugDumpOneNode(stderr, parent, 0);
1.27      daniel   1414: #endif
1.53      daniel   1415:        xmlAddSibling(parent, ret);
1.27      daniel   1416:     }
1.25      daniel   1417: }
                   1418: 
                   1419: /**
                   1420:  * cdataBlock:
                   1421:  * @ctx: the user data (XML parser context)
                   1422:  * @value:  The pcdata content
                   1423:  * @len:  the block length
                   1424:  *
                   1425:  * called when a pcdata block has been parsed
                   1426:  */
                   1427: void
1.34      daniel   1428: cdataBlock(void *ctx, const xmlChar *value, int len)
1.25      daniel   1429: {
                   1430:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.40      daniel   1431:     xmlNodePtr ret, lastChild;
1.25      daniel   1432: 
                   1433: #ifdef DEBUG_SAX
1.26      daniel   1434:     fprintf(stderr, "SAX.pcdata(%.10s, %d)\n", value, len);
1.25      daniel   1435: #endif
1.40      daniel   1436:     lastChild = xmlGetLastChild(ctxt->node);
                   1437: #ifdef DEBUG_SAX_TREE
                   1438:     fprintf(stderr, "add chars to %s \n", ctxt->node->name);
                   1439: #endif
                   1440:     if ((lastChild != NULL) &&
                   1441:         (lastChild->type == XML_CDATA_SECTION_NODE)) {
                   1442:        xmlTextConcat(lastChild, value, len);
                   1443:     } else {
                   1444:        ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
                   1445:        xmlAddChild(ctxt->node, ret);
                   1446:     }
1.10      daniel   1447: }
                   1448: 
1.18      daniel   1449: /*
                   1450:  * Default handler for XML, builds the DOM tree
                   1451:  */
1.1       daniel   1452: xmlSAXHandler xmlDefaultSAXHandler = {
1.10      daniel   1453:     internalSubset,
                   1454:     isStandalone,
                   1455:     hasInternalSubset,
                   1456:     hasExternalSubset,
1.1       daniel   1457:     resolveEntity,
1.10      daniel   1458:     getEntity,
                   1459:     entityDecl,
1.1       daniel   1460:     notationDecl,
1.10      daniel   1461:     attributeDecl,
                   1462:     elementDecl,
1.1       daniel   1463:     unparsedEntityDecl,
                   1464:     setDocumentLocator,
                   1465:     startDocument,
                   1466:     endDocument,
                   1467:     startElement,
                   1468:     endElement,
1.10      daniel   1469:     reference,
1.1       daniel   1470:     characters,
                   1471:     ignorableWhitespace,
                   1472:     processingInstruction,
1.10      daniel   1473:     comment,
1.1       daniel   1474:     xmlParserWarning,
                   1475:     xmlParserError,
1.2       daniel   1476:     xmlParserError,
1.20      daniel   1477:     getParameterEntity,
1.25      daniel   1478:     cdataBlock,
1.49      daniel   1479:     externalSubset,
1.1       daniel   1480: };
1.2       daniel   1481: 
1.5       daniel   1482: /**
                   1483:  * xmlDefaultSAXHandlerInit:
                   1484:  *
                   1485:  * Initialize the default SAX handler
                   1486:  */
                   1487: void
                   1488: xmlDefaultSAXHandlerInit(void)
                   1489: {
1.10      daniel   1490:     xmlDefaultSAXHandler.internalSubset = internalSubset;
1.49      daniel   1491:     xmlDefaultSAXHandler.externalSubset = externalSubset;
1.10      daniel   1492:     xmlDefaultSAXHandler.isStandalone = isStandalone;
                   1493:     xmlDefaultSAXHandler.hasInternalSubset = hasInternalSubset;
                   1494:     xmlDefaultSAXHandler.hasExternalSubset = hasExternalSubset;
1.2       daniel   1495:     xmlDefaultSAXHandler.resolveEntity = resolveEntity;
1.10      daniel   1496:     xmlDefaultSAXHandler.getEntity = getEntity;
1.20      daniel   1497:     xmlDefaultSAXHandler.getParameterEntity = getParameterEntity;
1.10      daniel   1498:     xmlDefaultSAXHandler.entityDecl = entityDecl;
                   1499:     xmlDefaultSAXHandler.attributeDecl = attributeDecl;
                   1500:     xmlDefaultSAXHandler.elementDecl = elementDecl;
1.2       daniel   1501:     xmlDefaultSAXHandler.notationDecl = notationDecl;
                   1502:     xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
                   1503:     xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
                   1504:     xmlDefaultSAXHandler.startDocument = startDocument;
                   1505:     xmlDefaultSAXHandler.endDocument = endDocument;
                   1506:     xmlDefaultSAXHandler.startElement = startElement;
                   1507:     xmlDefaultSAXHandler.endElement = endElement;
1.10      daniel   1508:     xmlDefaultSAXHandler.reference = reference;
1.2       daniel   1509:     xmlDefaultSAXHandler.characters = characters;
1.25      daniel   1510:     xmlDefaultSAXHandler.cdataBlock = cdataBlock;
1.2       daniel   1511:     xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
                   1512:     xmlDefaultSAXHandler.processingInstruction = processingInstruction;
1.10      daniel   1513:     xmlDefaultSAXHandler.comment = comment;
1.47      daniel   1514:     if (xmlGetWarningsDefaultValue == 0)
                   1515:        xmlDefaultSAXHandler.warning = NULL;
                   1516:     else
                   1517:        xmlDefaultSAXHandler.warning = xmlParserWarning;
1.2       daniel   1518:     xmlDefaultSAXHandler.error = xmlParserError;
                   1519:     xmlDefaultSAXHandler.fatalError = xmlParserError;
1.18      daniel   1520: }
                   1521: 
                   1522: /*
                   1523:  * Default handler for HTML, builds the DOM tree
                   1524:  */
                   1525: xmlSAXHandler htmlDefaultSAXHandler = {
1.66      daniel   1526:     internalSubset,
1.18      daniel   1527:     NULL,
                   1528:     NULL,
                   1529:     NULL,
                   1530:     NULL,
                   1531:     getEntity,
                   1532:     NULL,
                   1533:     NULL,
                   1534:     NULL,
                   1535:     NULL,
                   1536:     NULL,
                   1537:     setDocumentLocator,
                   1538:     startDocument,
                   1539:     endDocument,
                   1540:     startElement,
                   1541:     endElement,
                   1542:     NULL,
                   1543:     characters,
                   1544:     ignorableWhitespace,
                   1545:     NULL,
                   1546:     comment,
                   1547:     xmlParserWarning,
                   1548:     xmlParserError,
                   1549:     xmlParserError,
1.20      daniel   1550:     getParameterEntity,
1.25      daniel   1551:     NULL,
1.49      daniel   1552:     NULL,
1.18      daniel   1553: };
                   1554: 
                   1555: /**
                   1556:  * htmlDefaultSAXHandlerInit:
                   1557:  *
                   1558:  * Initialize the default SAX handler
                   1559:  */
                   1560: void
                   1561: htmlDefaultSAXHandlerInit(void)
                   1562: {
1.66      daniel   1563:     htmlDefaultSAXHandler.internalSubset = internalSubset;
1.49      daniel   1564:     htmlDefaultSAXHandler.externalSubset = NULL;
1.18      daniel   1565:     htmlDefaultSAXHandler.isStandalone = NULL;
                   1566:     htmlDefaultSAXHandler.hasInternalSubset = NULL;
                   1567:     htmlDefaultSAXHandler.hasExternalSubset = NULL;
                   1568:     htmlDefaultSAXHandler.resolveEntity = NULL;
                   1569:     htmlDefaultSAXHandler.getEntity = getEntity;
1.20      daniel   1570:     htmlDefaultSAXHandler.getParameterEntity = NULL;
1.18      daniel   1571:     htmlDefaultSAXHandler.entityDecl = NULL;
                   1572:     htmlDefaultSAXHandler.attributeDecl = NULL;
                   1573:     htmlDefaultSAXHandler.elementDecl = NULL;
                   1574:     htmlDefaultSAXHandler.notationDecl = NULL;
                   1575:     htmlDefaultSAXHandler.unparsedEntityDecl = NULL;
                   1576:     htmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
                   1577:     htmlDefaultSAXHandler.startDocument = startDocument;
                   1578:     htmlDefaultSAXHandler.endDocument = endDocument;
                   1579:     htmlDefaultSAXHandler.startElement = startElement;
                   1580:     htmlDefaultSAXHandler.endElement = endElement;
                   1581:     htmlDefaultSAXHandler.reference = NULL;
                   1582:     htmlDefaultSAXHandler.characters = characters;
1.25      daniel   1583:     htmlDefaultSAXHandler.cdataBlock = NULL;
1.18      daniel   1584:     htmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
                   1585:     htmlDefaultSAXHandler.processingInstruction = NULL;
                   1586:     htmlDefaultSAXHandler.comment = comment;
                   1587:     htmlDefaultSAXHandler.warning = xmlParserWarning;
                   1588:     htmlDefaultSAXHandler.error = xmlParserError;
                   1589:     htmlDefaultSAXHandler.fatalError = xmlParserError;
1.2       daniel   1590: }

Webmaster