Annotation of XML/SAX.c, revision 1.73

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.73    ! veillard  398:     xmlEntityPtr ent;
1.11      daniel    399:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    400: 
                    401: #ifdef DEBUG_SAX
                    402:     fprintf(stderr, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
                    403:             name, type, publicId, systemId, content);
                    404: #endif
1.73    ! veillard  405:     if (ctxt->inSubset == 1) {
        !           406:        ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
1.51      daniel    407:                              systemId, content);
1.73    ! veillard  408:        if ((ent == NULL) && (ctxt->pedantic) &&
        !           409:            (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
        !           410:            ctxt->sax->warning(ctxt, 
        !           411:             "Entity(%s) already defined in the internal subset\n", name);
        !           412:     } else if (ctxt->inSubset == 2) {
        !           413:        ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
1.51      daniel    414:                              systemId, content);
1.73    ! veillard  415:        if ((ent == NULL) && (ctxt->pedantic) &&
        !           416:            (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
        !           417:            ctxt->sax->warning(ctxt, 
        !           418:             "Entity(%s) already defined in the external subset\n", name);
        !           419:     } else {
1.50      daniel    420:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    421:            ctxt->sax->error(ctxt, 
                    422:             "SAX.entityDecl(%s) called while not in subset\n", name);
                    423:     }
1.10      daniel    424: }
                    425: 
                    426: /**
                    427:  * attributeDecl:
1.16      daniel    428:  * @ctx: the user data (XML parser context)
1.58      daniel    429:  * @elem:  the name of the element
1.48      daniel    430:  * @fullname:  the attribute name 
1.10      daniel    431:  * @type:  the attribute type 
1.58      daniel    432:  * @def:  the type of default value
                    433:  * @defaultValue: the attribute default value
                    434:  * @tree:  the tree of enumerated value set
1.10      daniel    435:  *
                    436:  * An attribute definition has been parsed
                    437:  */
                    438: void
1.48      daniel    439: attributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
1.34      daniel    440:               int type, int def, const xmlChar *defaultValue,
1.10      daniel    441:              xmlEnumerationPtr tree)
                    442: {
1.11      daniel    443:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.21      daniel    444:     xmlAttributePtr attr;
1.48      daniel    445:     xmlChar *name = NULL, *prefix = NULL;
1.10      daniel    446: 
                    447: #ifdef DEBUG_SAX
                    448:     fprintf(stderr, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1.48      daniel    449:             elem, fullname, type, def, defaultValue);
1.10      daniel    450: #endif
1.48      daniel    451:     name = xmlSplitQName(ctxt, fullname, &prefix);
1.50      daniel    452:     if (ctxt->inSubset == 1)
                    453:        attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
1.68      veillard  454:               name, prefix, (xmlAttributeType) type,
                    455:               (xmlAttributeDefault) def, defaultValue, tree);
1.50      daniel    456:     else if (ctxt->inSubset == 2)
                    457:        attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
1.68      veillard  458:           name, prefix, (xmlAttributeType) type, 
                    459:           (xmlAttributeDefault) def, defaultValue, tree);
1.50      daniel    460:     else {
                    461:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    462:            ctxt->sax->error(ctxt, 
                    463:             "SAX.attributeDecl(%s) called while not in subset\n", name);
                    464:        return;
                    465:     }
1.21      daniel    466:     if (attr == 0) ctxt->valid = 0;
1.23      daniel    467:     if (ctxt->validate && ctxt->wellFormed &&
                    468:         ctxt->myDoc && ctxt->myDoc->intSubset)
1.21      daniel    469:        ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
                    470:                                                attr);
1.48      daniel    471:     if (prefix != NULL)
                    472:        xmlFree(prefix);
                    473:     if (name != NULL)
                    474:        xmlFree(name);
1.10      daniel    475: }
                    476: 
                    477: /**
                    478:  * elementDecl:
1.16      daniel    479:  * @ctx: the user data (XML parser context)
1.10      daniel    480:  * @name:  the element name 
                    481:  * @type:  the element type 
1.58      daniel    482:  * @content: the element value tree
1.10      daniel    483:  *
                    484:  * An element definition has been parsed
                    485:  */
                    486: void
1.34      daniel    487: elementDecl(void *ctx, const xmlChar *name, int type,
1.10      daniel    488:            xmlElementContentPtr content)
                    489: {
1.11      daniel    490:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.50      daniel    491:     xmlElementPtr elem = NULL;
1.10      daniel    492: 
                    493: #ifdef DEBUG_SAX
                    494:     fprintf(stderr, "SAX.elementDecl(%s, %d, ...)\n",
1.48      daniel    495:             fullname, type);
1.10      daniel    496: #endif
1.21      daniel    497:     
1.50      daniel    498:     if (ctxt->inSubset == 1)
                    499:        elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
1.68      veillard  500:                              name, (xmlElementTypeVal) type, content);
1.50      daniel    501:     else if (ctxt->inSubset == 2)
                    502:        elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
1.68      veillard  503:                              name, (xmlElementTypeVal) type, content);
1.50      daniel    504:     else {
                    505:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    506:            ctxt->sax->error(ctxt, 
                    507:             "SAX.elementDecl(%s) called while not in subset\n", name);
                    508:        return;
                    509:     }
                    510:     if (elem == NULL) ctxt->valid = 0;
1.23      daniel    511:     if (ctxt->validate && ctxt->wellFormed &&
                    512:         ctxt->myDoc && ctxt->myDoc->intSubset)
1.21      daniel    513:        ctxt->valid &= xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
1.10      daniel    514: }
                    515: 
                    516: /**
1.5       daniel    517:  * notationDecl:
1.16      daniel    518:  * @ctx: the user data (XML parser context)
1.5       daniel    519:  * @name: The name of the notation
                    520:  * @publicId: The public ID of the entity
                    521:  * @systemId: The system ID of the entity
                    522:  *
1.1       daniel    523:  * What to do when a notation declaration has been parsed.
                    524:  */
1.5       daniel    525: void
1.34      daniel    526: notationDecl(void *ctx, const xmlChar *name,
                    527:             const xmlChar *publicId, const xmlChar *systemId)
1.5       daniel    528: {
1.11      daniel    529:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.50      daniel    530:     xmlNotationPtr nota = NULL;
1.21      daniel    531: 
1.2       daniel    532: #ifdef DEBUG_SAX
                    533:     fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
                    534: #endif
1.21      daniel    535: 
1.50      daniel    536:     if (ctxt->inSubset == 1)
                    537:        nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
                    538:                               publicId, systemId);
                    539:     else if (ctxt->inSubset == 2)
                    540:        nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
1.21      daniel    541:                               publicId, systemId);
1.50      daniel    542:     else {
                    543:        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                    544:            ctxt->sax->error(ctxt, 
                    545:             "SAX.notationDecl(%s) called while not in subset\n", name);
                    546:        return;
                    547:     }
                    548:     if (nota == NULL) ctxt->valid = 0;
1.23      daniel    549:     if (ctxt->validate && ctxt->wellFormed &&
                    550:         ctxt->myDoc && ctxt->myDoc->intSubset)
1.21      daniel    551:        ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
                    552:                                               nota);
1.1       daniel    553: }
                    554: 
1.5       daniel    555: /**
                    556:  * unparsedEntityDecl:
1.16      daniel    557:  * @ctx: the user data (XML parser context)
1.5       daniel    558:  * @name: The name of the entity
                    559:  * @publicId: The public ID of the entity
                    560:  * @systemId: The system ID of the entity
                    561:  * @notationName: the name of the notation
                    562:  *
1.1       daniel    563:  * What to do when an unparsed entity declaration is parsed
                    564:  */
1.5       daniel    565: void
1.34      daniel    566: unparsedEntityDecl(void *ctx, const xmlChar *name,
                    567:                   const xmlChar *publicId, const xmlChar *systemId,
                    568:                   const xmlChar *notationName)
1.5       daniel    569: {
1.28      daniel    570:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2       daniel    571: #ifdef DEBUG_SAX
                    572:     fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
                    573:             name, publicId, systemId, notationName);
                    574: #endif
1.28      daniel    575:     if (ctxt->validate && ctxt->wellFormed &&
                    576:         ctxt->myDoc && ctxt->myDoc->intSubset)
                    577:        ctxt->valid &= xmlValidateNotationUse(&ctxt->vctxt, ctxt->myDoc,
                    578:                                              notationName);
                    579:     xmlAddDocEntity(ctxt->myDoc, name,
                    580:                     XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
                    581:                    publicId, systemId, notationName);
1.1       daniel    582: }
                    583: 
1.5       daniel    584: /**
                    585:  * setDocumentLocator:
1.16      daniel    586:  * @ctx: the user data (XML parser context)
1.5       daniel    587:  * @loc: A SAX Locator
                    588:  *
1.1       daniel    589:  * Receive the document locator at startup, actually xmlDefaultSAXLocator
                    590:  * Everything is available on the context, so this is useless in our case.
                    591:  */
1.5       daniel    592: void
1.11      daniel    593: setDocumentLocator(void *ctx, xmlSAXLocatorPtr loc)
1.5       daniel    594: {
1.11      daniel    595:     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2       daniel    596: #ifdef DEBUG_SAX
                    597:     fprintf(stderr, "SAX.setDocumentLocator()\n");
                    598: #endif
1.1       daniel    599: }
                    600: 
1.5       daniel    601: /**
                    602:  * startDocument:
1.16      daniel    603:  * @ctx: the user data (XML parser context)
1.5       daniel    604:  *
1.1       daniel    605:  * called when the document start being processed.
                    606:  */
1.5       daniel    607: void
1.11      daniel    608: startDocument(void *ctx)
1.5       daniel    609: {
1.11      daniel    610:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    611:     xmlDocPtr doc;
                    612: 
1.2       daniel    613: #ifdef DEBUG_SAX
                    614:     fprintf(stderr, "SAX.startDocument()\n");
                    615: #endif
1.66      daniel    616:     if (ctxt->html) {
                    617:        if (ctxt->myDoc == NULL)
1.69      veillard  618: #ifdef LIBXML_HTML_ENABLED
1.72      veillard  619:            ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
1.69      veillard  620: #else
                    621:         fprintf(stderr, "libxml2 built without HTML support\n");
                    622: #endif
1.66      daniel    623:     } else {
                    624:        doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
                    625:        if (doc != NULL) {
                    626:            if (ctxt->encoding != NULL)
                    627:                doc->encoding = xmlStrdup(ctxt->encoding);
                    628:            else
                    629:                doc->encoding = NULL;
                    630:            doc->standalone = ctxt->standalone;
                    631:        }
1.10      daniel    632:     }
1.70      veillard  633:     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
                    634:        (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
                    635:         ctxt->myDoc->URL = xmlStrdup((xmlChar *) ctxt->input->filename);
                    636:     }
1.1       daniel    637: }
                    638: 
1.5       daniel    639: /**
                    640:  * endDocument:
1.16      daniel    641:  * @ctx: the user data (XML parser context)
1.5       daniel    642:  *
1.1       daniel    643:  * called when the document end has been detected.
                    644:  */
1.5       daniel    645: void
1.11      daniel    646: endDocument(void *ctx)
1.5       daniel    647: {
1.31      daniel    648:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2       daniel    649: #ifdef DEBUG_SAX
                    650:     fprintf(stderr, "SAX.endDocument()\n");
                    651: #endif
1.31      daniel    652:     if (ctxt->validate && ctxt->wellFormed &&
                    653:         ctxt->myDoc && ctxt->myDoc->intSubset)
                    654:        ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
1.59      daniel    655: 
                    656:     /*
                    657:      * Grab the encoding if it was added on-the-fly
                    658:      */
                    659:     if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
                    660:        (ctxt->myDoc->encoding == NULL)) {
                    661:        ctxt->myDoc->encoding = ctxt->encoding;
                    662:        ctxt->encoding = NULL;
                    663:     }
1.62      daniel    664:     if ((ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
                    665:        (ctxt->myDoc->encoding == NULL)) {
                    666:        ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
                    667:     }
                    668:     if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
                    669:        (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
                    670:        ctxt->myDoc->charset = ctxt->charset;
                    671:     }
1.1       daniel    672: }
                    673: 
1.5       daniel    674: /**
1.10      daniel    675:  * attribute:
1.16      daniel    676:  * @ctx: the user data (XML parser context)
1.58      daniel    677:  * @fullname:  The attribute name, including namespace prefix
1.10      daniel    678:  * @value:  The attribute value
                    679:  *
                    680:  * Handle an attribute that has been read by the parser.
                    681:  * The default handling is to convert the attribute into an
                    682:  * DOM subtree and past it in a new xmlAttr element added to
                    683:  * the element.
                    684:  */
                    685: void
1.34      daniel    686: attribute(void *ctx, const xmlChar *fullname, const xmlChar *value)
1.10      daniel    687: {
1.11      daniel    688:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    689:     xmlAttrPtr ret;
1.34      daniel    690:     xmlChar *name;
                    691:     xmlChar *ns;
1.56      daniel    692:     xmlChar *nval;
1.29      daniel    693:     xmlNsPtr namespace;
1.10      daniel    694: 
                    695: /****************
                    696: #ifdef DEBUG_SAX
                    697:     fprintf(stderr, "SAX.attribute(%s, %s)\n", fullname, value);
                    698: #endif
                    699:  ****************/
                    700:     /*
                    701:      * Split the full name into a namespace prefix and the tag name
                    702:      */
1.48      daniel    703:     name = xmlSplitQName(ctxt, fullname, &ns);
1.10      daniel    704: 
                    705:     /*
1.55      daniel    706:      * Do the last stave of the attribute normalization
                    707:      */
1.65      daniel    708:     if (ctxt->html)
                    709:        nval = NULL;
                    710:     else
                    711:        nval = xmlValidNormalizeAttributeValue(ctxt->myDoc,
1.56      daniel    712:                               ctxt->node, fullname, value);
                    713:     if (nval != NULL)
                    714:        value = nval;
1.55      daniel    715: 
                    716:     /*
1.10      daniel    717:      * Check whether it's a namespace definition
                    718:      */
1.65      daniel    719:     if ((!ctxt->html) && (ns == NULL) &&
1.10      daniel    720:         (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
                    721:         (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
1.60      daniel    722:        xmlURIPtr uri;
                    723: 
                    724:        uri = xmlParseURI((const char *)value);
                    725:        if (uri == NULL) {
                    726:            if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
                    727:                ctxt->sax->warning(ctxt->userData, 
                    728:                     "nmlns: %s not a valid URI\n", value);
                    729:        } else {
1.61      daniel    730:            if (uri->scheme == NULL) {
1.60      daniel    731:                if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
                    732:                    ctxt->sax->warning(ctxt->userData, 
                    733:                         "nmlns: URI %s is not absolute\n", value);
                    734:            }
                    735:            xmlFreeURI(uri);
                    736:        }
                    737: 
1.10      daniel    738:        /* a default namespace definition */
                    739:        xmlNewNs(ctxt->node, value, NULL);
                    740:        if (name != NULL) 
1.30      daniel    741:            xmlFree(name);
1.55      daniel    742:        if (nval != NULL)
                    743:            xmlFree(nval);
1.10      daniel    744:        return;
                    745:     }
1.65      daniel    746:     if ((!ctxt->html) &&
                    747:        (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
1.10      daniel    748:         (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
1.54      daniel    749:        /*
                    750:         * Validate also for namespace decls, they are attributes from
                    751:         * an XML-1.0 perspective
                    752:         TODO ... doesn't map well with current API
                    753:         if (ctxt->validate && ctxt->wellFormed &&
                    754:            ctxt->myDoc && ctxt->myDoc->intSubset)
                    755:            ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
                    756:                                               ctxt->node, ret, value);
                    757:         */
1.10      daniel    758:        /* a standard namespace definition */
                    759:        xmlNewNs(ctxt->node, value, name);
1.30      daniel    760:        xmlFree(ns);
1.10      daniel    761:        if (name != NULL) 
1.30      daniel    762:            xmlFree(name);
1.55      daniel    763:        if (nval != NULL)
                    764:            xmlFree(nval);
1.10      daniel    765:        return;
                    766:     }
                    767: 
1.38      daniel    768:     if (ns != NULL)
                    769:        namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
                    770:     else {
                    771:        namespace = NULL;
                    772:     }
                    773: 
1.29      daniel    774:     /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
                    775:     ret = xmlNewNsProp(ctxt->node, namespace, name, NULL);
1.22      daniel    776: 
1.26      daniel    777:     if (ret != NULL) {
1.46      daniel    778:         if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
                    779:            xmlNodePtr tmp;
                    780: 
1.44      daniel    781:            ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
1.46      daniel    782:            tmp = ret->children;
                    783:            while (tmp != NULL) {
                    784:                tmp->parent = (xmlNodePtr) ret;
                    785:                if (tmp->next == NULL)
                    786:                    ret->last = tmp;
                    787:                tmp = tmp->next;
                    788:            }
1.65      daniel    789:        } else if (value != NULL) {
1.44      daniel    790:            ret->children = xmlNewDocText(ctxt->myDoc, value);
1.46      daniel    791:            ret->last = ret->children;
                    792:            if (ret->children != NULL)
                    793:                ret->children->parent = (xmlNodePtr) ret;
                    794:        }
1.26      daniel    795:     }
1.22      daniel    796: 
1.65      daniel    797:     if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
1.56      daniel    798:         ctxt->myDoc && ctxt->myDoc->intSubset) {
                    799:        
                    800:        /*
                    801:         * If we don't substitute entities, the validation should be
                    802:         * done on a value with replaced entities anyway.
                    803:         */
                    804:         if (!ctxt->replaceEntities) {
                    805:            xmlChar *val;
                    806: 
                    807:            ctxt->depth++;
                    808:            val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
                    809:                                          0,0,0);
                    810:            ctxt->depth--;
                    811:            if (val == NULL)
                    812:                ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
                    813:                                ctxt->myDoc, ctxt->node, ret, value);
                    814:            else {
                    815:                ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
                    816:                                ctxt->myDoc, ctxt->node, ret, val);
                    817:                 xmlFree(val);
                    818:            }
                    819:        } else {
                    820:            ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
1.22      daniel    821:                                               ctxt->node, ret, value);
1.56      daniel    822:        }
                    823:     } else {
1.26      daniel    824:         /*
                    825:         * when validating, the ID registration is done at the attribute
                    826:         * validation level. Otherwise we have to do specific handling here.
                    827:         */
                    828:        if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
                    829:            xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
1.31      daniel    830:        else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
                    831:            xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
1.26      daniel    832:     }
1.22      daniel    833: 
1.55      daniel    834:     if (nval != NULL)
                    835:        xmlFree(nval);
1.10      daniel    836:     if (name != NULL) 
1.30      daniel    837:        xmlFree(name);
1.10      daniel    838:     if (ns != NULL) 
1.30      daniel    839:        xmlFree(ns);
1.10      daniel    840: }
                    841: 
                    842: /**
1.5       daniel    843:  * startElement:
1.16      daniel    844:  * @ctx: the user data (XML parser context)
1.58      daniel    845:  * @fullname:  The element name, including namespace prefix
1.10      daniel    846:  * @atts:  An array of name/value attributes pairs, NULL terminated
1.5       daniel    847:  *
1.1       daniel    848:  * called when an opening tag has been processed.
                    849:  */
1.5       daniel    850: void
1.34      daniel    851: startElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
1.5       daniel    852: {
1.11      daniel    853:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel    854:     xmlNodePtr ret;
                    855:     xmlNodePtr parent = ctxt->node;
                    856:     xmlNsPtr ns;
1.34      daniel    857:     xmlChar *name;
                    858:     xmlChar *prefix;
                    859:     const xmlChar *att;
                    860:     const xmlChar *value;
1.10      daniel    861:     int i;
                    862: 
1.2       daniel    863: #ifdef DEBUG_SAX
1.10      daniel    864:     fprintf(stderr, "SAX.startElement(%s)\n", fullname);
1.2       daniel    865: #endif
1.33      daniel    866: 
                    867:     /*
                    868:      * First check on validity:
                    869:      */
                    870:     if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) && 
                    871:         ((ctxt->myDoc->intSubset == NULL) ||
                    872:         ((ctxt->myDoc->intSubset->notations == NULL) && 
                    873:          (ctxt->myDoc->intSubset->elements == NULL) &&
                    874:          (ctxt->myDoc->intSubset->attributes == NULL) && 
                    875:          (ctxt->myDoc->intSubset->entities == NULL)))) {
                    876:        if (ctxt->vctxt.error != NULL) {
                    877:             ctxt->vctxt.error(ctxt->vctxt.userData,
                    878:              "Validation failed: no DTD found !\n");
                    879:        }
                    880:        ctxt->validate = 0;
                    881:     }
                    882:        
                    883: 
1.10      daniel    884:     /*
                    885:      * Split the full name into a namespace prefix and the tag name
                    886:      */
1.48      daniel    887:     name = xmlSplitQName(ctxt, fullname, &prefix);
1.10      daniel    888: 
                    889: 
                    890:     /*
                    891:      * Note : the namespace resolution is deferred until the end of the
                    892:      *        attributes parsing, since local namespace can be defined as
                    893:      *        an attribute at this level.
                    894:      */
                    895:     ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
                    896:     if (ret == NULL) return;
1.44      daniel    897:     if (ctxt->myDoc->children == NULL) {
1.26      daniel    898: #ifdef DEBUG_SAX_TREE
                    899:        fprintf(stderr, "Setting %s as root\n", name);
                    900: #endif
1.45      daniel    901:         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1.26      daniel    902:     } else if (parent == NULL) {
1.44      daniel    903:         parent = ctxt->myDoc->children;
1.26      daniel    904:     }
1.63      daniel    905:     ctxt->nodemem = -1;
1.10      daniel    906: 
                    907:     /*
                    908:      * We are parsing a new node.
                    909:      */
1.26      daniel    910: #ifdef DEBUG_SAX_TREE
                    911:     fprintf(stderr, "pushing(%s)\n", name);
                    912: #endif
1.10      daniel    913:     nodePush(ctxt, ret);
                    914: 
                    915:     /*
                    916:      * Link the child element
                    917:      */
1.26      daniel    918:     if (parent != NULL) {
                    919:         if (parent->type == XML_ELEMENT_NODE) {
                    920: #ifdef DEBUG_SAX_TREE
                    921:            fprintf(stderr, "adding child %s to %s\n", name, parent->name);
                    922: #endif
                    923:            xmlAddChild(parent, ret);
                    924:        } else {
                    925: #ifdef DEBUG_SAX_TREE
                    926:            fprintf(stderr, "adding sibling %s to ", name);
                    927:            xmlDebugDumpOneNode(stderr, parent, 0);
                    928: #endif
                    929:            xmlAddSibling(parent, ret);
                    930:        }
                    931:     }
1.10      daniel    932: 
1.54      daniel    933:     /*
1.29      daniel    934:      * process all the attributes whose name start with "xml"
1.10      daniel    935:      */
                    936:     if (atts != NULL) {
                    937:         i = 0;
                    938:        att = atts[i++];
                    939:        value = atts[i++];
1.65      daniel    940:        if (!ctxt->html) {
                    941:            while ((att != NULL) && (value != NULL)) {
                    942:                if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l'))
                    943:                    attribute(ctxt, att, value);
1.29      daniel    944: 
1.65      daniel    945:                att = atts[i++];
                    946:                value = atts[i++];
                    947:            }
1.29      daniel    948:        }
                    949:     }
                    950: 
                    951:     /*
1.64      daniel    952:      * Search the namespace, note that since the attributes have been
                    953:      * processed, the local namespaces are available.
                    954:      */
                    955:     ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
                    956:     if ((ns == NULL) && (parent != NULL))
                    957:        ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
                    958:     xmlSetNs(ret, ns);
                    959: 
                    960:     /*
1.29      daniel    961:      * process all the other attributes
                    962:      */
                    963:     if (atts != NULL) {
                    964:         i = 0;
                    965:        att = atts[i++];
                    966:        value = atts[i++];
1.65      daniel    967:        if (ctxt->html) {
                    968:            while (att != NULL) {
1.29      daniel    969:                attribute(ctxt, att, value);
1.65      daniel    970:                att = atts[i++];
                    971:                value = atts[i++];
                    972:            }
                    973:        } else {
                    974:            while ((att != NULL) && (value != NULL)) {
                    975:                if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l'))
                    976:                    attribute(ctxt, att, value);
                    977: 
                    978:                /*
                    979:                 * Next ones
                    980:                 */
                    981:                att = atts[i++];
                    982:                value = atts[i++];
                    983:            }
1.10      daniel    984:        }
                    985:     }
                    986: 
                    987:     /*
1.64      daniel    988:      * If it's the Document root, finish the Dtd validation and
                    989:      * check the document root element for validity
1.10      daniel    990:      */
1.64      daniel    991:     if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) {
                    992:        ctxt->valid &= xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
                    993:        ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
                    994:        ctxt->vctxt.finishDtd = 1;
                    995:     }
1.10      daniel    996: 
                    997:     if (prefix != NULL)
1.30      daniel    998:        xmlFree(prefix);
1.10      daniel    999:     if (name != NULL)
1.30      daniel   1000:        xmlFree(name);
1.10      daniel   1001: 
1.1       daniel   1002: }
                   1003: 
1.5       daniel   1004: /**
                   1005:  * endElement:
1.16      daniel   1006:  * @ctx: the user data (XML parser context)
1.5       daniel   1007:  * @name:  The element name
                   1008:  *
1.1       daniel   1009:  * called when the end of an element has been detected.
                   1010:  */
1.5       daniel   1011: void
1.34      daniel   1012: endElement(void *ctx, const xmlChar *name)
1.5       daniel   1013: {
1.11      daniel   1014:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel   1015:     xmlParserNodeInfo node_info;
                   1016:     xmlNodePtr cur = ctxt->node;
                   1017: 
1.2       daniel   1018: #ifdef DEBUG_SAX
1.10      daniel   1019:     if (name == NULL)
                   1020:         fprintf(stderr, "SAX.endElement(NULL)\n");
                   1021:     else
                   1022:        fprintf(stderr, "SAX.endElement(%s)\n", name);
                   1023: #endif
                   1024:     
                   1025:     /* Capture end position and add node */
                   1026:     if (cur != NULL && ctxt->record_info) {
                   1027:       node_info.end_pos = ctxt->input->cur - ctxt->input->base;
                   1028:       node_info.end_line = ctxt->input->line;
                   1029:       node_info.node = cur;
                   1030:       xmlParserAddNodeInfo(ctxt, &node_info);
                   1031:     }
1.63      daniel   1032:     ctxt->nodemem = -1;
1.10      daniel   1033: 
1.23      daniel   1034:     if (ctxt->validate && ctxt->wellFormed &&
                   1035:         ctxt->myDoc && ctxt->myDoc->intSubset)
1.22      daniel   1036:         ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
                   1037:                                             cur);
                   1038: 
                   1039:     
1.10      daniel   1040:     /*
                   1041:      * end of parsing of this node.
                   1042:      */
1.26      daniel   1043: #ifdef DEBUG_SAX_TREE
                   1044:     fprintf(stderr, "popping(%s)\n", cur->name);
                   1045: #endif
1.10      daniel   1046:     nodePop(ctxt);
1.1       daniel   1047: }
                   1048: 
1.5       daniel   1049: /**
1.10      daniel   1050:  * reference:
1.16      daniel   1051:  * @ctx: the user data (XML parser context)
1.10      daniel   1052:  * @name:  The entity name
1.5       daniel   1053:  *
1.10      daniel   1054:  * called when an entity reference is detected. 
1.5       daniel   1055:  */
                   1056: void
1.34      daniel   1057: reference(void *ctx, const xmlChar *name)
1.5       daniel   1058: {
1.11      daniel   1059:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel   1060:     xmlNodePtr ret;
                   1061: 
1.5       daniel   1062: #ifdef DEBUG_SAX
1.10      daniel   1063:     fprintf(stderr, "SAX.reference(%s)\n", name);
1.5       daniel   1064: #endif
1.42      daniel   1065:     if (name[0] == '#')
                   1066:        ret = xmlNewCharRef(ctxt->myDoc, name);
                   1067:     else
                   1068:        ret = xmlNewReference(ctxt->myDoc, name);
1.26      daniel   1069: #ifdef DEBUG_SAX_TREE
                   1070:     fprintf(stderr, "add reference %s to %s \n", name, ctxt->node->name);
                   1071: #endif
1.10      daniel   1072:     xmlAddChild(ctxt->node, ret);
1.5       daniel   1073: }
                   1074: 
                   1075: /**
                   1076:  * characters:
1.16      daniel   1077:  * @ctx: the user data (XML parser context)
1.34      daniel   1078:  * @ch:  a xmlChar string
                   1079:  * @len: the number of xmlChar
1.5       daniel   1080:  *
1.1       daniel   1081:  * receiving some chars from the parser.
                   1082:  * Question: how much at a time ???
                   1083:  */
1.5       daniel   1084: void
1.34      daniel   1085: characters(void *ctx, const xmlChar *ch, int len)
1.5       daniel   1086: {
1.11      daniel   1087:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2       daniel   1088:     xmlNodePtr lastChild;
                   1089: 
                   1090: #ifdef DEBUG_SAX
1.10      daniel   1091:     fprintf(stderr, "SAX.characters(%.30s, %d)\n", ch, len);
1.2       daniel   1092: #endif
                   1093:     /*
                   1094:      * Handle the data if any. If there is no child
                   1095:      * add it as content, otherwise if the last child is text,
                   1096:      * concatenate it, else create a new node of type text.
                   1097:      */
                   1098: 
1.36      daniel   1099:     if (ctxt->node == NULL) {
                   1100: #ifdef DEBUG_SAX_TREE
                   1101:        fprintf(stderr, "add chars: ctxt->node == NULL !\n");
                   1102: #endif
                   1103:         return;
                   1104:     }
1.2       daniel   1105:     lastChild = xmlGetLastChild(ctxt->node);
1.26      daniel   1106: #ifdef DEBUG_SAX_TREE
                   1107:     fprintf(stderr, "add chars to %s \n", ctxt->node->name);
                   1108: #endif
1.62      daniel   1109: 
                   1110:     /*
                   1111:      * Here we needed an accelerator mechanism in case of very large
                   1112:      * elements. Use an attribute in the structure !!!
                   1113:      */
1.63      daniel   1114:     if (lastChild == NULL) {
                   1115:        /* first node, first time */
1.10      daniel   1116:        xmlNodeAddContentLen(ctxt->node, ch, len);
1.63      daniel   1117: #ifndef XML_USE_BUFFER_CONTENT
                   1118:        if (ctxt->node->children != NULL) {
                   1119:            ctxt->nodelen = len;
                   1120:            ctxt->nodemem = len + 1;
                   1121:        }
                   1122: #endif
                   1123:     } else {
1.62      daniel   1124:        if (xmlNodeIsText(lastChild)) {
1.63      daniel   1125: #ifndef XML_USE_BUFFER_CONTENT
                   1126:            /*
                   1127:             * The whole point of maintaining nodelen and nodemem,
                   1128:             * xmlTextConcat is too costly, i.e. compute lenght,
                   1129:             * reallocate a new buffer, move data, append ch. Here
                   1130:             * We try to minimaze realloc() uses and avoid copying
                   1131:             * and recomputing lenght over and over.
                   1132:             */
                   1133:            if (ctxt->nodelen + len >= ctxt->nodemem) {
                   1134:                xmlChar *newbuf;
                   1135:                int size;
                   1136: 
                   1137:                size = ctxt->nodemem + len;
                   1138:                size *= 2;
                   1139:                 newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
                   1140:                if (newbuf == NULL) {
                   1141:                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1142:                        ctxt->sax->error(ctxt->userData, 
                   1143:                             "SAX.characters(): out of memory\n");
                   1144:                    return;
                   1145:                }
                   1146:                ctxt->nodemem = size;
                   1147:                lastChild->content = newbuf;
                   1148:            }
                   1149:            memcpy(&lastChild->content[ctxt->nodelen], ch, len);
                   1150:            ctxt->nodelen += len;
                   1151:            lastChild->content[ctxt->nodelen] = 0;
                   1152: #else
1.10      daniel   1153:            xmlTextConcat(lastChild, ch, len);
1.63      daniel   1154: #endif
1.62      daniel   1155:        } else {
1.63      daniel   1156:            /* Mixed content, first time */
1.10      daniel   1157:            lastChild = xmlNewTextLen(ch, len);
1.2       daniel   1158:            xmlAddChild(ctxt->node, lastChild);
1.63      daniel   1159: #ifndef XML_USE_BUFFER_CONTENT
                   1160:            if (ctxt->node->children != NULL) {
                   1161:                ctxt->nodelen = len;
                   1162:                ctxt->nodemem = len + 1;
                   1163:            }
                   1164: #endif
1.2       daniel   1165:        }
                   1166:     }
1.1       daniel   1167: }
                   1168: 
1.5       daniel   1169: /**
                   1170:  * ignorableWhitespace:
1.16      daniel   1171:  * @ctx: the user data (XML parser context)
1.34      daniel   1172:  * @ch:  a xmlChar string
                   1173:  * @len: the number of xmlChar
1.5       daniel   1174:  *
1.1       daniel   1175:  * receiving some ignorable whitespaces from the parser.
                   1176:  * Question: how much at a time ???
                   1177:  */
1.5       daniel   1178: void
1.34      daniel   1179: ignorableWhitespace(void *ctx, const xmlChar *ch, int len)
1.5       daniel   1180: {
1.11      daniel   1181:     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2       daniel   1182: #ifdef DEBUG_SAX
1.10      daniel   1183:     fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
1.2       daniel   1184: #endif
1.1       daniel   1185: }
                   1186: 
1.5       daniel   1187: /**
                   1188:  * processingInstruction:
1.16      daniel   1189:  * @ctx: the user data (XML parser context)
1.5       daniel   1190:  * @target:  the target name
                   1191:  * @data: the PI data's
                   1192:  *
                   1193:  * A processing instruction has been parsed.
                   1194:  */
                   1195: void
1.34      daniel   1196: processingInstruction(void *ctx, const xmlChar *target,
                   1197:                       const xmlChar *data)
1.5       daniel   1198: {
1.26      daniel   1199:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
                   1200:     xmlNodePtr ret;
                   1201:     xmlNodePtr parent = ctxt->node;
                   1202: 
1.2       daniel   1203: #ifdef DEBUG_SAX
                   1204:     fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
                   1205: #endif
1.26      daniel   1206: 
                   1207:     ret = xmlNewPI(target, data);
                   1208:     if (ret == NULL) return;
1.53      daniel   1209:     parent = ctxt->node;
                   1210: 
                   1211:     if (ctxt->inSubset == 1) {
                   1212:        xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
                   1213:        return;
                   1214:     } else if (ctxt->inSubset == 2) {
                   1215:        xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
                   1216:        return;
                   1217:     }
                   1218:     if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
1.26      daniel   1219: #ifdef DEBUG_SAX_TREE
                   1220:            fprintf(stderr, "Setting PI %s as root\n", target);
                   1221: #endif
1.45      daniel   1222:         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1.53      daniel   1223:        return;
1.26      daniel   1224:     }
1.53      daniel   1225:     if (parent->type == XML_ELEMENT_NODE) {
1.26      daniel   1226: #ifdef DEBUG_SAX_TREE
1.53      daniel   1227:        fprintf(stderr, "adding PI %s child to %s\n", target, parent->name);
1.26      daniel   1228: #endif
1.53      daniel   1229:        xmlAddChild(parent, ret);
                   1230:     } else {
1.26      daniel   1231: #ifdef DEBUG_SAX_TREE
1.53      daniel   1232:        fprintf(stderr, "adding PI %s sibling to ", target);
                   1233:        xmlDebugDumpOneNode(stderr, parent, 0);
1.26      daniel   1234: #endif
1.53      daniel   1235:        xmlAddSibling(parent, ret);
1.26      daniel   1236:     }
1.1       daniel   1237: }
                   1238: 
1.10      daniel   1239: /**
                   1240:  * globalNamespace:
1.16      daniel   1241:  * @ctx: the user data (XML parser context)
1.10      daniel   1242:  * @href:  the namespace associated URN
                   1243:  * @prefix: the namespace prefix
                   1244:  *
                   1245:  * An old global namespace has been parsed.
                   1246:  */
                   1247: void
1.34      daniel   1248: globalNamespace(void *ctx, const xmlChar *href, const xmlChar *prefix)
1.10      daniel   1249: {
1.11      daniel   1250:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel   1251: #ifdef DEBUG_SAX
                   1252:     fprintf(stderr, "SAX.globalNamespace(%s, %s)\n", href, prefix);
                   1253: #endif
                   1254:     xmlNewGlobalNs(ctxt->myDoc, href, prefix);
                   1255: }
                   1256: 
                   1257: /**
                   1258:  * setNamespace:
1.16      daniel   1259:  * @ctx: the user data (XML parser context)
1.10      daniel   1260:  * @name:  the namespace prefix
                   1261:  *
                   1262:  * Set the current element namespace.
                   1263:  */
1.58      daniel   1264: 
1.10      daniel   1265: void
1.34      daniel   1266: setNamespace(void *ctx, const xmlChar *name)
1.10      daniel   1267: {
1.11      daniel   1268:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel   1269:     xmlNsPtr ns;
                   1270:     xmlNodePtr parent;
                   1271: 
                   1272: #ifdef DEBUG_SAX
                   1273:     fprintf(stderr, "SAX.setNamespace(%s)\n", name);
                   1274: #endif
                   1275:     ns = xmlSearchNs(ctxt->myDoc, ctxt->node, name);
                   1276:     if (ns == NULL) { /* ctxt->node may not have a parent yet ! */
                   1277:         if (ctxt->nodeNr >= 2) {
                   1278:            parent = ctxt->nodeTab[ctxt->nodeNr - 2];
                   1279:            if (parent != NULL)
                   1280:                ns = xmlSearchNs(ctxt->myDoc, parent, name);
                   1281:        }
                   1282:     }
                   1283:     xmlSetNs(ctxt->node, ns);
                   1284: }
                   1285: 
                   1286: /**
                   1287:  * getNamespace:
1.16      daniel   1288:  * @ctx: the user data (XML parser context)
1.10      daniel   1289:  *
                   1290:  * Get the current element namespace.
1.58      daniel   1291:  *
                   1292:  * Returns the xmlNsPtr or NULL if none
1.10      daniel   1293:  */
1.58      daniel   1294: 
1.10      daniel   1295: xmlNsPtr
1.11      daniel   1296: getNamespace(void *ctx)
1.10      daniel   1297: {
1.11      daniel   1298:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel   1299:     xmlNsPtr ret;
                   1300: 
                   1301: #ifdef DEBUG_SAX
                   1302:     fprintf(stderr, "SAX.getNamespace()\n");
                   1303: #endif
                   1304:     ret = ctxt->node->ns;
                   1305:     return(ret);
                   1306: }
                   1307: 
                   1308: /**
                   1309:  * checkNamespace:
1.16      daniel   1310:  * @ctx: the user data (XML parser context)
1.10      daniel   1311:  * @namespace: the namespace to check against
                   1312:  *
                   1313:  * Check that the current element namespace is the same as the
                   1314:  * one read upon parsing.
1.58      daniel   1315:  *
                   1316:  * Returns 1 if true 0 otherwise
1.10      daniel   1317:  */
1.58      daniel   1318: 
1.10      daniel   1319: int
1.34      daniel   1320: checkNamespace(void *ctx, xmlChar *namespace)
1.10      daniel   1321: {
1.11      daniel   1322:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel   1323:     xmlNodePtr cur = ctxt->node;
                   1324: 
                   1325: #ifdef DEBUG_SAX
                   1326:     fprintf(stderr, "SAX.checkNamespace(%s)\n", namespace);
                   1327: #endif
                   1328: 
                   1329:     /*
                   1330:      * Check that the Name in the ETag is the same as in the STag.
                   1331:      */
                   1332:     if (namespace == NULL) {
                   1333:         if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
                   1334:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1335:                ctxt->sax->error(ctxt, 
                   1336:                 "End tags for %s don't hold the namespace %s\n",
                   1337:                                 cur->name, cur->ns->prefix);
                   1338:            ctxt->wellFormed = 0;
                   1339:        }
                   1340:     } else {
                   1341:         if ((cur->ns == NULL) || (cur->ns->prefix == NULL)) {
                   1342:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1343:                ctxt->sax->error(ctxt, 
                   1344:                 "End tags %s holds a prefix %s not used by the open tag\n",
                   1345:                                 cur->name, namespace);
                   1346:            ctxt->wellFormed = 0;
1.28      daniel   1347:        } else if (xmlStrcmp(namespace, cur->ns->prefix)) {
1.10      daniel   1348:            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                   1349:                ctxt->sax->error(ctxt, 
                   1350:     "Start and End tags for %s don't use the same namespaces: %s and %s\n",
                   1351:                                 cur->name, cur->ns->prefix, namespace);
                   1352:            ctxt->wellFormed = 0;
                   1353:        } else
                   1354:            return(1);
                   1355:     }
                   1356:     return(0);
                   1357: }
                   1358: 
                   1359: /**
                   1360:  * namespaceDecl:
1.16      daniel   1361:  * @ctx: the user data (XML parser context)
1.10      daniel   1362:  * @href:  the namespace associated URN
                   1363:  * @prefix: the namespace prefix
                   1364:  *
                   1365:  * A namespace has been parsed.
                   1366:  */
                   1367: void
1.34      daniel   1368: namespaceDecl(void *ctx, const xmlChar *href, const xmlChar *prefix)
1.10      daniel   1369: {
1.11      daniel   1370:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10      daniel   1371: #ifdef DEBUG_SAX
                   1372:     if (prefix == NULL)
                   1373:        fprintf(stderr, "SAX.namespaceDecl(%s, NULL)\n", href);
                   1374:     else
                   1375:        fprintf(stderr, "SAX.namespaceDecl(%s, %s)\n", href, prefix);
                   1376: #endif
                   1377:     xmlNewNs(ctxt->node, href, prefix);
                   1378: }
                   1379: 
                   1380: /**
                   1381:  * comment:
1.16      daniel   1382:  * @ctx: the user data (XML parser context)
1.10      daniel   1383:  * @value:  the comment content
                   1384:  *
                   1385:  * A comment has been parsed.
                   1386:  */
                   1387: void
1.34      daniel   1388: comment(void *ctx, const xmlChar *value)
1.10      daniel   1389: {
1.11      daniel   1390:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.17      daniel   1391:     xmlNodePtr ret;
1.27      daniel   1392:     xmlNodePtr parent = ctxt->node;
1.17      daniel   1393: 
1.10      daniel   1394: #ifdef DEBUG_SAX
                   1395:     fprintf(stderr, "SAX.comment(%s)\n", value);
                   1396: #endif
1.17      daniel   1397:     ret = xmlNewDocComment(ctxt->myDoc, value);
1.27      daniel   1398:     if (ret == NULL) return;
                   1399: 
1.53      daniel   1400:     if (ctxt->inSubset == 1) {
                   1401:        xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
                   1402:        return;
                   1403:     } else if (ctxt->inSubset == 2) {
                   1404:        xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
                   1405:        return;
                   1406:     }
                   1407:     if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
1.27      daniel   1408: #ifdef DEBUG_SAX_TREE
                   1409:            fprintf(stderr, "Setting comment as root\n");
                   1410: #endif
1.45      daniel   1411:         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1.53      daniel   1412:        return;
1.27      daniel   1413:     }
1.53      daniel   1414:     if (parent->type == XML_ELEMENT_NODE) {
1.27      daniel   1415: #ifdef DEBUG_SAX_TREE
1.53      daniel   1416:        fprintf(stderr, "adding comment child to %s\n", parent->name);
1.27      daniel   1417: #endif
1.53      daniel   1418:        xmlAddChild(parent, ret);
                   1419:     } else {
1.27      daniel   1420: #ifdef DEBUG_SAX_TREE
1.53      daniel   1421:        fprintf(stderr, "adding comment sibling to ");
                   1422:        xmlDebugDumpOneNode(stderr, parent, 0);
1.27      daniel   1423: #endif
1.53      daniel   1424:        xmlAddSibling(parent, ret);
1.27      daniel   1425:     }
1.25      daniel   1426: }
                   1427: 
                   1428: /**
                   1429:  * cdataBlock:
                   1430:  * @ctx: the user data (XML parser context)
                   1431:  * @value:  The pcdata content
                   1432:  * @len:  the block length
                   1433:  *
                   1434:  * called when a pcdata block has been parsed
                   1435:  */
                   1436: void
1.34      daniel   1437: cdataBlock(void *ctx, const xmlChar *value, int len)
1.25      daniel   1438: {
                   1439:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.40      daniel   1440:     xmlNodePtr ret, lastChild;
1.25      daniel   1441: 
                   1442: #ifdef DEBUG_SAX
1.26      daniel   1443:     fprintf(stderr, "SAX.pcdata(%.10s, %d)\n", value, len);
1.25      daniel   1444: #endif
1.40      daniel   1445:     lastChild = xmlGetLastChild(ctxt->node);
                   1446: #ifdef DEBUG_SAX_TREE
                   1447:     fprintf(stderr, "add chars to %s \n", ctxt->node->name);
                   1448: #endif
                   1449:     if ((lastChild != NULL) &&
                   1450:         (lastChild->type == XML_CDATA_SECTION_NODE)) {
                   1451:        xmlTextConcat(lastChild, value, len);
                   1452:     } else {
                   1453:        ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
                   1454:        xmlAddChild(ctxt->node, ret);
                   1455:     }
1.10      daniel   1456: }
                   1457: 
1.18      daniel   1458: /*
                   1459:  * Default handler for XML, builds the DOM tree
                   1460:  */
1.1       daniel   1461: xmlSAXHandler xmlDefaultSAXHandler = {
1.10      daniel   1462:     internalSubset,
                   1463:     isStandalone,
                   1464:     hasInternalSubset,
                   1465:     hasExternalSubset,
1.1       daniel   1466:     resolveEntity,
1.10      daniel   1467:     getEntity,
                   1468:     entityDecl,
1.1       daniel   1469:     notationDecl,
1.10      daniel   1470:     attributeDecl,
                   1471:     elementDecl,
1.1       daniel   1472:     unparsedEntityDecl,
                   1473:     setDocumentLocator,
                   1474:     startDocument,
                   1475:     endDocument,
                   1476:     startElement,
                   1477:     endElement,
1.10      daniel   1478:     reference,
1.1       daniel   1479:     characters,
                   1480:     ignorableWhitespace,
                   1481:     processingInstruction,
1.10      daniel   1482:     comment,
1.1       daniel   1483:     xmlParserWarning,
                   1484:     xmlParserError,
1.2       daniel   1485:     xmlParserError,
1.20      daniel   1486:     getParameterEntity,
1.25      daniel   1487:     cdataBlock,
1.49      daniel   1488:     externalSubset,
1.1       daniel   1489: };
1.2       daniel   1490: 
1.5       daniel   1491: /**
                   1492:  * xmlDefaultSAXHandlerInit:
                   1493:  *
                   1494:  * Initialize the default SAX handler
                   1495:  */
                   1496: void
                   1497: xmlDefaultSAXHandlerInit(void)
                   1498: {
1.10      daniel   1499:     xmlDefaultSAXHandler.internalSubset = internalSubset;
1.49      daniel   1500:     xmlDefaultSAXHandler.externalSubset = externalSubset;
1.10      daniel   1501:     xmlDefaultSAXHandler.isStandalone = isStandalone;
                   1502:     xmlDefaultSAXHandler.hasInternalSubset = hasInternalSubset;
                   1503:     xmlDefaultSAXHandler.hasExternalSubset = hasExternalSubset;
1.2       daniel   1504:     xmlDefaultSAXHandler.resolveEntity = resolveEntity;
1.10      daniel   1505:     xmlDefaultSAXHandler.getEntity = getEntity;
1.20      daniel   1506:     xmlDefaultSAXHandler.getParameterEntity = getParameterEntity;
1.10      daniel   1507:     xmlDefaultSAXHandler.entityDecl = entityDecl;
                   1508:     xmlDefaultSAXHandler.attributeDecl = attributeDecl;
                   1509:     xmlDefaultSAXHandler.elementDecl = elementDecl;
1.2       daniel   1510:     xmlDefaultSAXHandler.notationDecl = notationDecl;
                   1511:     xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
                   1512:     xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
                   1513:     xmlDefaultSAXHandler.startDocument = startDocument;
                   1514:     xmlDefaultSAXHandler.endDocument = endDocument;
                   1515:     xmlDefaultSAXHandler.startElement = startElement;
                   1516:     xmlDefaultSAXHandler.endElement = endElement;
1.10      daniel   1517:     xmlDefaultSAXHandler.reference = reference;
1.2       daniel   1518:     xmlDefaultSAXHandler.characters = characters;
1.25      daniel   1519:     xmlDefaultSAXHandler.cdataBlock = cdataBlock;
1.2       daniel   1520:     xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
                   1521:     xmlDefaultSAXHandler.processingInstruction = processingInstruction;
1.10      daniel   1522:     xmlDefaultSAXHandler.comment = comment;
1.47      daniel   1523:     if (xmlGetWarningsDefaultValue == 0)
                   1524:        xmlDefaultSAXHandler.warning = NULL;
                   1525:     else
                   1526:        xmlDefaultSAXHandler.warning = xmlParserWarning;
1.2       daniel   1527:     xmlDefaultSAXHandler.error = xmlParserError;
                   1528:     xmlDefaultSAXHandler.fatalError = xmlParserError;
1.18      daniel   1529: }
                   1530: 
                   1531: /*
                   1532:  * Default handler for HTML, builds the DOM tree
                   1533:  */
                   1534: xmlSAXHandler htmlDefaultSAXHandler = {
1.66      daniel   1535:     internalSubset,
1.18      daniel   1536:     NULL,
                   1537:     NULL,
                   1538:     NULL,
                   1539:     NULL,
                   1540:     getEntity,
                   1541:     NULL,
                   1542:     NULL,
                   1543:     NULL,
                   1544:     NULL,
                   1545:     NULL,
                   1546:     setDocumentLocator,
                   1547:     startDocument,
                   1548:     endDocument,
                   1549:     startElement,
                   1550:     endElement,
                   1551:     NULL,
                   1552:     characters,
                   1553:     ignorableWhitespace,
                   1554:     NULL,
                   1555:     comment,
                   1556:     xmlParserWarning,
                   1557:     xmlParserError,
                   1558:     xmlParserError,
1.20      daniel   1559:     getParameterEntity,
1.25      daniel   1560:     NULL,
1.49      daniel   1561:     NULL,
1.18      daniel   1562: };
                   1563: 
                   1564: /**
                   1565:  * htmlDefaultSAXHandlerInit:
                   1566:  *
                   1567:  * Initialize the default SAX handler
                   1568:  */
                   1569: void
                   1570: htmlDefaultSAXHandlerInit(void)
                   1571: {
1.66      daniel   1572:     htmlDefaultSAXHandler.internalSubset = internalSubset;
1.49      daniel   1573:     htmlDefaultSAXHandler.externalSubset = NULL;
1.18      daniel   1574:     htmlDefaultSAXHandler.isStandalone = NULL;
                   1575:     htmlDefaultSAXHandler.hasInternalSubset = NULL;
                   1576:     htmlDefaultSAXHandler.hasExternalSubset = NULL;
                   1577:     htmlDefaultSAXHandler.resolveEntity = NULL;
                   1578:     htmlDefaultSAXHandler.getEntity = getEntity;
1.20      daniel   1579:     htmlDefaultSAXHandler.getParameterEntity = NULL;
1.18      daniel   1580:     htmlDefaultSAXHandler.entityDecl = NULL;
                   1581:     htmlDefaultSAXHandler.attributeDecl = NULL;
                   1582:     htmlDefaultSAXHandler.elementDecl = NULL;
                   1583:     htmlDefaultSAXHandler.notationDecl = NULL;
                   1584:     htmlDefaultSAXHandler.unparsedEntityDecl = NULL;
                   1585:     htmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
                   1586:     htmlDefaultSAXHandler.startDocument = startDocument;
                   1587:     htmlDefaultSAXHandler.endDocument = endDocument;
                   1588:     htmlDefaultSAXHandler.startElement = startElement;
                   1589:     htmlDefaultSAXHandler.endElement = endElement;
                   1590:     htmlDefaultSAXHandler.reference = NULL;
                   1591:     htmlDefaultSAXHandler.characters = characters;
1.25      daniel   1592:     htmlDefaultSAXHandler.cdataBlock = NULL;
1.18      daniel   1593:     htmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
                   1594:     htmlDefaultSAXHandler.processingInstruction = NULL;
                   1595:     htmlDefaultSAXHandler.comment = comment;
                   1596:     htmlDefaultSAXHandler.warning = xmlParserWarning;
                   1597:     htmlDefaultSAXHandler.error = xmlParserError;
                   1598:     htmlDefaultSAXHandler.fatalError = xmlParserError;
1.2       daniel   1599: }

Webmaster