Annotation of XML/SAX.c, revision 1.84

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

Webmaster