Annotation of XML/SAX.c, revision 1.67

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

Webmaster