Annotation of XML/SAX.c, revision 1.32

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

Webmaster