Annotation of XML/SAX.c, revision 1.46

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

Webmaster