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