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