Annotation of XML/SAX.c, revision 1.38

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

Webmaster