Annotation of XML/SAX.c, revision 1.49

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

Webmaster