Annotation of XML/SAX.c, revision 1.4

1.1       daniel      1: /*
                      2:  * SAX.c : Default SAX handler to build a tree.
                      3:  */
                      4: 
                      5: #include <stdio.h>
1.2       daniel      6: #include <malloc.h>
1.1       daniel      7: #include "tree.h"
                      8: #include "parser.h"
                      9: 
1.3       daniel     10: /* #define DEBUG_SAX */
1.2       daniel     11: 
1.1       daniel     12: /*
                     13:  * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
                     14:  */
1.2       daniel     15: const CHAR *getPublicId(xmlParserCtxtPtr ctxt) {
1.1       daniel     16:     return(NULL);
                     17: }
                     18: 
                     19: /*
                     20:  * Return the system ID, basically URI or filename e.g.
                     21:  *  http://www.sgmlsource.com/dtds/memo.dtd
                     22:  */
1.2       daniel     23: const CHAR *getSystemId(xmlParserCtxtPtr ctxt) {
                     24:     return(ctxt->input->filename); 
1.1       daniel     25: }
                     26: 
                     27: /*
                     28:  * Return the line number of the current parsing point.
                     29:  */
1.2       daniel     30: int getLineNumber(xmlParserCtxtPtr ctxt) {
1.1       daniel     31:     return(ctxt->input->line);
                     32: }
                     33: /*
                     34:  * Return the column number of the current parsing point.
                     35:  */
1.2       daniel     36: int getColumnNumber(xmlParserCtxtPtr ctxt) {
1.1       daniel     37:     return(ctxt->input->col);
                     38: }
                     39: 
                     40: /*
                     41:  * The default SAX Locator.
                     42:  */
                     43: 
                     44: xmlSAXLocator xmlDefaultSAXLocator = {
                     45:     getPublicId, getSystemId, getLineNumber, getColumnNumber
                     46: };
                     47: 
                     48: /*
                     49:  * Special entity resolver, better left to the parser, it has
                     50:  * more context than the application layer.
                     51:  */
1.2       daniel     52: xmlParserInputPtr resolveEntity(xmlParserCtxtPtr ctxt, 
1.1       daniel     53:                            const CHAR *publicId, const CHAR *systemId) {
1.2       daniel     54: 
                     55: #ifdef DEBUG_SAX
                     56:     fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
                     57: #endif
1.1       daniel     58:     return(NULL);
                     59: }
                     60: 
                     61: /*
                     62:  * What to do when a notation declaration has been parsed.
                     63:  * TODO Not handled currently.
                     64:  */
1.2       daniel     65: void notationDecl(xmlParserCtxtPtr ctxt, const CHAR *name,
1.1       daniel     66:                  const CHAR *publicId, const CHAR *systemId) {
1.2       daniel     67: #ifdef DEBUG_SAX
                     68:     fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
                     69: #endif
1.1       daniel     70: }
                     71: 
                     72: /*
                     73:  * What to do when an unparsed entity declaration is parsed
                     74:  * TODO Create an Entity node.
                     75:  */
1.2       daniel     76: void unparsedEntityDecl(xmlParserCtxtPtr ctxt, const CHAR *name,
1.1       daniel     77:                        const CHAR *publicId, const CHAR *systemId,
                     78:                        const CHAR *notationName) {
1.2       daniel     79: #ifdef DEBUG_SAX
                     80:     fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
                     81:             name, publicId, systemId, notationName);
                     82: #endif
1.1       daniel     83: }
                     84: 
                     85: /*
                     86:  * Receive the document locator at startup, actually xmlDefaultSAXLocator
                     87:  * Everything is available on the context, so this is useless in our case.
                     88:  */
1.2       daniel     89: void setDocumentLocator(xmlParserCtxtPtr ctxt, xmlSAXLocatorPtr loc) {
                     90: #ifdef DEBUG_SAX
                     91:     fprintf(stderr, "SAX.setDocumentLocator()\n");
                     92: #endif
1.1       daniel     93: }
                     94: 
                     95: /*
                     96:  * called when the document start being processed.
                     97:  */
1.2       daniel     98: void startDocument(xmlParserCtxtPtr ctxt) {
                     99: #ifdef DEBUG_SAX
                    100:     fprintf(stderr, "SAX.startDocument()\n");
                    101: #endif
1.1       daniel    102: }
                    103: 
                    104: /*
                    105:  * called when the document end has been detected.
                    106:  */
1.2       daniel    107: void endDocument(xmlParserCtxtPtr ctxt) {
                    108: #ifdef DEBUG_SAX
                    109:     fprintf(stderr, "SAX.endDocument()\n");
                    110: #endif
1.1       daniel    111: }
                    112: 
                    113: /*
                    114:  * called when an opening tag has been processed.
                    115:  * TODO We currently have a small pblm with the arguments ...
                    116:  */
1.2       daniel    117: void startElement(xmlParserCtxtPtr ctxt, const CHAR *name) {
                    118:     xmlNodePtr parent;
                    119: 
                    120: #ifdef DEBUG_SAX
                    121:     fprintf(stderr, "SAX.startElement(%s)\n", name);
                    122: #endif
                    123:     if (ctxt->nodeNr < 2) return;
                    124:     parent = ctxt->nodeTab[ctxt->nodeNr - 2];
                    125:     if (parent != NULL)
                    126:        xmlAddChild(parent, ctxt->node);
                    127:     
1.1       daniel    128: }
                    129: 
                    130: /*
                    131:  * called when the end of an element has been detected.
                    132:  */
1.2       daniel    133: void endElement(xmlParserCtxtPtr ctxt, const CHAR *name) {
                    134: #ifdef DEBUG_SAX
                    135:     fprintf(stderr, "SAX.endElement(%s)\n", name);
                    136: #endif
1.1       daniel    137: }
                    138: 
                    139: /*
                    140:  * receiving some chars from the parser.
                    141:  * Question: how much at a time ???
                    142:  */
1.2       daniel    143: void characters(xmlParserCtxtPtr ctxt, const CHAR *ch,
1.1       daniel    144:                        int start, int len) {
1.2       daniel    145:     xmlNodePtr lastChild;
                    146: 
                    147: #ifdef DEBUG_SAX
                    148:     fprintf(stderr, "SAX.characters(%.30s, %d, %d)\n", ch, start, len);
                    149: #endif
                    150:     /*
                    151:      * Handle the data if any. If there is no child
                    152:      * add it as content, otherwise if the last child is text,
                    153:      * concatenate it, else create a new node of type text.
                    154:      */
                    155: 
                    156:     lastChild = xmlGetLastChild(ctxt->node);
                    157:     if (lastChild == NULL)
                    158:        xmlNodeAddContentLen(ctxt->node, &ch[start], len);
                    159:     else {
                    160:        if (xmlNodeIsText(lastChild))
                    161:            xmlTextConcat(lastChild, &ch[start], len);
                    162:        else {
                    163:            lastChild = xmlNewTextLen(&ch[start], len);
                    164:            xmlAddChild(ctxt->node, lastChild);
                    165:        }
                    166:     }
1.1       daniel    167: }
                    168: 
                    169: /*
                    170:  * receiving some ignorable whitespaces from the parser.
                    171:  * Question: how much at a time ???
                    172:  */
1.2       daniel    173: void ignorableWhitespace(xmlParserCtxtPtr ctxt, const CHAR *ch,
1.1       daniel    174:                          int start, int len) {
1.2       daniel    175: #ifdef DEBUG_SAX
                    176:     fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d, %d)\n", ch, start, len);
                    177: #endif
1.1       daniel    178: }
                    179: 
                    180: /*
                    181:  * A processing instruction has beem parsed.
                    182:  */
1.2       daniel    183: void processingInstruction(xmlParserCtxtPtr ctxt, const CHAR *target,
1.1       daniel    184:                           const CHAR *data) {
1.2       daniel    185: #ifdef DEBUG_SAX
                    186:     fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
                    187: #endif
1.1       daniel    188: }
                    189: 
                    190: xmlSAXHandler xmlDefaultSAXHandler = {
                    191:     resolveEntity,
                    192:     notationDecl,
                    193:     unparsedEntityDecl,
                    194:     setDocumentLocator,
                    195:     startDocument,
                    196:     endDocument,
                    197:     startElement,
                    198:     endElement,
                    199:     characters,
                    200:     ignorableWhitespace,
                    201:     processingInstruction,
                    202:     xmlParserWarning,
                    203:     xmlParserError,
1.2       daniel    204:     xmlParserError,
1.1       daniel    205: };
1.2       daniel    206: 
                    207: void xmlDefaultSAXHandlerInit(void) {
                    208:     xmlDefaultSAXHandler.resolveEntity = resolveEntity;
                    209:     xmlDefaultSAXHandler.notationDecl = notationDecl;
                    210:     xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
                    211:     xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
                    212:     xmlDefaultSAXHandler.startDocument = startDocument;
                    213:     xmlDefaultSAXHandler.endDocument = endDocument;
                    214:     xmlDefaultSAXHandler.startElement = startElement;
                    215:     xmlDefaultSAXHandler.endElement = endElement;
                    216:     xmlDefaultSAXHandler.characters = characters;
                    217:     xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
                    218:     xmlDefaultSAXHandler.processingInstruction = processingInstruction;
                    219:     xmlDefaultSAXHandler.warning = xmlParserWarning;
                    220:     xmlDefaultSAXHandler.error = xmlParserError;
                    221:     xmlDefaultSAXHandler.fatalError = xmlParserError;
                    222: }

Webmaster