Annotation of XML/SAX.c, revision 1.66

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

Webmaster