Annotation of XML/SAX.c, revision 1.48

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

Webmaster