Annotation of XML/SAX.c, revision 1.64

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

Webmaster