Annotation of XML/SAX.c, revision 1.80

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

Webmaster