blob: 4732cd800840648d348980754092a9fc5e6df44a [file] [log] [blame]
Daniel Veillard260a68f1998-08-13 03:39:55 +00001/*
2 * SAX.c : Default SAX handler to build a tree.
Daniel Veillard97b58771998-10-20 06:14:16 +00003 *
4 * Daniel Veillard <Daniel.Veillard@w3.org>
Daniel Veillard260a68f1998-08-13 03:39:55 +00005 */
6
7#include <stdio.h>
Seth Alvese7f12e61998-10-01 20:51:15 +00008#include <stdlib.h>
Daniel Veillard260a68f1998-08-13 03:39:55 +00009#include "tree.h"
10#include "parser.h"
11#include "error.h"
12
13/* #define DEBUG_SAX */
14
Daniel Veillard97b58771998-10-20 06:14:16 +000015/**
16 * getPublicId:
17 * @ctxt: An XML parser context
18 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000019 * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
Daniel Veillard97b58771998-10-20 06:14:16 +000020 *
21 * return values: a CHAR *
Daniel Veillard260a68f1998-08-13 03:39:55 +000022 */
Daniel Veillard97b58771998-10-20 06:14:16 +000023const CHAR *
24getPublicId(xmlParserCtxtPtr ctxt)
25{
Daniel Veillard260a68f1998-08-13 03:39:55 +000026 return(NULL);
27}
28
Daniel Veillard97b58771998-10-20 06:14:16 +000029/**
30 * getSystemId:
31 * @ctxt: An XML parser context
32 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000033 * Return the system ID, basically URI or filename e.g.
Daniel Veillard97b58771998-10-20 06:14:16 +000034 * http://www.sgmlsource.com/dtds/memo.dtd
35 *
36 * return values: a CHAR *
Daniel Veillard260a68f1998-08-13 03:39:55 +000037 */
Daniel Veillard97b58771998-10-20 06:14:16 +000038const CHAR *
39getSystemId(xmlParserCtxtPtr ctxt)
40{
Daniel Veillard260a68f1998-08-13 03:39:55 +000041 return(ctxt->input->filename);
42}
43
Daniel Veillard97b58771998-10-20 06:14:16 +000044/**
45 * getLineNumber:
46 * @ctxt: An XML parser context
47 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000048 * Return the line number of the current parsing point.
Daniel Veillard97b58771998-10-20 06:14:16 +000049 *
50 * return values: an int
Daniel Veillard260a68f1998-08-13 03:39:55 +000051 */
Daniel Veillard97b58771998-10-20 06:14:16 +000052int
53getLineNumber(xmlParserCtxtPtr ctxt)
54{
Daniel Veillard260a68f1998-08-13 03:39:55 +000055 return(ctxt->input->line);
56}
Daniel Veillard97b58771998-10-20 06:14:16 +000057
58/**
59 * getColumnNumber:
60 * @ctxt: An XML parser context
61 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000062 * Return the column number of the current parsing point.
Daniel Veillard97b58771998-10-20 06:14:16 +000063 *
64 * return values: an int
Daniel Veillard260a68f1998-08-13 03:39:55 +000065 */
Daniel Veillard97b58771998-10-20 06:14:16 +000066int
67getColumnNumber(xmlParserCtxtPtr ctxt)
68{
Daniel Veillard260a68f1998-08-13 03:39:55 +000069 return(ctxt->input->col);
70}
71
72/*
73 * The default SAX Locator.
74 */
75
76xmlSAXLocator xmlDefaultSAXLocator = {
77 getPublicId, getSystemId, getLineNumber, getColumnNumber
78};
79
Daniel Veillard97b58771998-10-20 06:14:16 +000080/**
81 * resolveEntity:
82 * @ctxt: An XML parser context
83 * @publicId: The public ID of the entity
84 * @systemId: The system ID of the entity
85 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000086 * Special entity resolver, better left to the parser, it has
87 * more context than the application layer.
Daniel Veillard97b58771998-10-20 06:14:16 +000088 *
89 * return values: an int
Daniel Veillard260a68f1998-08-13 03:39:55 +000090 */
Daniel Veillard97b58771998-10-20 06:14:16 +000091xmlParserInputPtr
92resolveEntity(xmlParserCtxtPtr ctxt, const CHAR *publicId, const CHAR *systemId)
93{
Daniel Veillard260a68f1998-08-13 03:39:55 +000094
95#ifdef DEBUG_SAX
96 fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
97#endif
98 return(NULL);
99}
100
Daniel Veillard97b58771998-10-20 06:14:16 +0000101/**
102 * notationDecl:
103 * @ctxt: An XML parser context
104 * @name: The name of the notation
105 * @publicId: The public ID of the entity
106 * @systemId: The system ID of the entity
107 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000108 * What to do when a notation declaration has been parsed.
109 * TODO Not handled currently.
Daniel Veillard97b58771998-10-20 06:14:16 +0000110 *
111 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000112 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000113void
114notationDecl(xmlParserCtxtPtr ctxt, const CHAR *name,
115 const CHAR *publicId, const CHAR *systemId)
116{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000117#ifdef DEBUG_SAX
118 fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
119#endif
120}
121
Daniel Veillard97b58771998-10-20 06:14:16 +0000122/**
123 * unparsedEntityDecl:
124 * @ctxt: An XML parser context
125 * @name: The name of the entity
126 * @publicId: The public ID of the entity
127 * @systemId: The system ID of the entity
128 * @notationName: the name of the notation
129 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000130 * What to do when an unparsed entity declaration is parsed
131 * TODO Create an Entity node.
Daniel Veillard97b58771998-10-20 06:14:16 +0000132 *
133 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000134 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000135void
136unparsedEntityDecl(xmlParserCtxtPtr ctxt, const CHAR *name,
137 const CHAR *publicId, const CHAR *systemId,
138 const CHAR *notationName)
139{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000140#ifdef DEBUG_SAX
141 fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
142 name, publicId, systemId, notationName);
143#endif
144}
145
Daniel Veillard97b58771998-10-20 06:14:16 +0000146/**
147 * setDocumentLocator:
148 * @ctxt: An XML parser context
149 * @loc: A SAX Locator
150 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000151 * Receive the document locator at startup, actually xmlDefaultSAXLocator
152 * Everything is available on the context, so this is useless in our case.
Daniel Veillard97b58771998-10-20 06:14:16 +0000153 *
154 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000155 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000156void
157setDocumentLocator(xmlParserCtxtPtr ctxt, xmlSAXLocatorPtr loc)
158{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000159#ifdef DEBUG_SAX
160 fprintf(stderr, "SAX.setDocumentLocator()\n");
161#endif
162}
163
Daniel Veillard97b58771998-10-20 06:14:16 +0000164/**
165 * startDocument:
166 * @ctxt: An XML parser context
167 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000168 * called when the document start being processed.
Daniel Veillard97b58771998-10-20 06:14:16 +0000169 *
170 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000171 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000172void
173startDocument(xmlParserCtxtPtr ctxt)
174{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000175#ifdef DEBUG_SAX
176 fprintf(stderr, "SAX.startDocument()\n");
177#endif
178}
179
Daniel Veillard97b58771998-10-20 06:14:16 +0000180/**
181 * endDocument:
182 * @ctxt: An XML parser context
183 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000184 * called when the document end has been detected.
Daniel Veillard97b58771998-10-20 06:14:16 +0000185 *
186 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000187 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000188void
189endDocument(xmlParserCtxtPtr ctxt)
190{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000191#ifdef DEBUG_SAX
192 fprintf(stderr, "SAX.endDocument()\n");
193#endif
194}
195
Daniel Veillard97b58771998-10-20 06:14:16 +0000196/**
197 * startElement:
198 * @ctxt: An XML parser context
199 * @name: The element name
200 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000201 * called when an opening tag has been processed.
202 * TODO We currently have a small pblm with the arguments ...
Daniel Veillard97b58771998-10-20 06:14:16 +0000203 *
204 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000205 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000206void
207startElement(xmlParserCtxtPtr ctxt, const CHAR *name)
208{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000209 xmlNodePtr parent;
210
211#ifdef DEBUG_SAX
212 fprintf(stderr, "SAX.startElement(%s)\n", name);
213#endif
214 if (ctxt->nodeNr < 2) return;
215 parent = ctxt->nodeTab[ctxt->nodeNr - 2];
216 if (parent != NULL)
217 xmlAddChild(parent, ctxt->node);
218
219}
220
Daniel Veillard97b58771998-10-20 06:14:16 +0000221/**
222 * endElement:
223 * @ctxt: An XML parser context
224 * @name: The element name
225 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000226 * called when the end of an element has been detected.
Daniel Veillard97b58771998-10-20 06:14:16 +0000227 *
228 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000229 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000230void
231endElement(xmlParserCtxtPtr ctxt, const CHAR *name)
232{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000233#ifdef DEBUG_SAX
234 fprintf(stderr, "SAX.endElement(%s)\n", name);
235#endif
236}
237
Daniel Veillard97b58771998-10-20 06:14:16 +0000238/**
239 * characters:
240 * @ctxt: An XML parser context
241 * @ch: a CHAR string
242 * @start: the first char in the string
243 * @len: the number of CHAR
244 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000245 * receiving some chars from the parser.
246 * Question: how much at a time ???
Daniel Veillard97b58771998-10-20 06:14:16 +0000247 *
248 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000249 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000250void
251characters(xmlParserCtxtPtr ctxt, const CHAR *ch, int start, int len)
252{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000253 xmlNodePtr lastChild;
254
255#ifdef DEBUG_SAX
256 fprintf(stderr, "SAX.characters(%.30s, %d, %d)\n", ch, start, len);
257#endif
258 /*
259 * Handle the data if any. If there is no child
260 * add it as content, otherwise if the last child is text,
261 * concatenate it, else create a new node of type text.
262 */
263
264 lastChild = xmlGetLastChild(ctxt->node);
265 if (lastChild == NULL)
266 xmlNodeAddContentLen(ctxt->node, &ch[start], len);
267 else {
268 if (xmlNodeIsText(lastChild))
269 xmlTextConcat(lastChild, &ch[start], len);
270 else {
271 lastChild = xmlNewTextLen(&ch[start], len);
272 xmlAddChild(ctxt->node, lastChild);
273 }
274 }
275}
276
Daniel Veillard97b58771998-10-20 06:14:16 +0000277/**
278 * ignorableWhitespace:
279 * @ctxt: An XML parser context
280 * @ch: a CHAR string
281 * @start: the first char in the string
282 * @len: the number of CHAR
283 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000284 * receiving some ignorable whitespaces from the parser.
285 * Question: how much at a time ???
Daniel Veillard97b58771998-10-20 06:14:16 +0000286 *
287 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000288 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000289void
290ignorableWhitespace(xmlParserCtxtPtr ctxt, const CHAR *ch, int start, int len)
291{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000292#ifdef DEBUG_SAX
293 fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d, %d)\n", ch, start, len);
294#endif
295}
296
Daniel Veillard97b58771998-10-20 06:14:16 +0000297/**
298 * processingInstruction:
299 * @ctxt: An XML parser context
300 * @target: the target name
301 * @data: the PI data's
302 * @len: the number of CHAR
303 *
304 * A processing instruction has been parsed.
305 *
306 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000307 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000308void
309processingInstruction(xmlParserCtxtPtr ctxt, const CHAR *target,
310 const CHAR *data)
311{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000312#ifdef DEBUG_SAX
313 fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
314#endif
315}
316
317xmlSAXHandler xmlDefaultSAXHandler = {
318 resolveEntity,
319 notationDecl,
320 unparsedEntityDecl,
321 setDocumentLocator,
322 startDocument,
323 endDocument,
324 startElement,
325 endElement,
326 characters,
327 ignorableWhitespace,
328 processingInstruction,
329 xmlParserWarning,
330 xmlParserError,
331 xmlParserError,
332};
333
Daniel Veillard97b58771998-10-20 06:14:16 +0000334/**
335 * xmlDefaultSAXHandlerInit:
336 *
337 * Initialize the default SAX handler
338 *
339 * return values:
340 */
341void
342xmlDefaultSAXHandlerInit(void)
343{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000344 xmlDefaultSAXHandler.resolveEntity = resolveEntity;
345 xmlDefaultSAXHandler.notationDecl = notationDecl;
346 xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
347 xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
348 xmlDefaultSAXHandler.startDocument = startDocument;
349 xmlDefaultSAXHandler.endDocument = endDocument;
350 xmlDefaultSAXHandler.startElement = startElement;
351 xmlDefaultSAXHandler.endElement = endElement;
352 xmlDefaultSAXHandler.characters = characters;
353 xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
354 xmlDefaultSAXHandler.processingInstruction = processingInstruction;
355 xmlDefaultSAXHandler.warning = xmlParserWarning;
356 xmlDefaultSAXHandler.error = xmlParserError;
357 xmlDefaultSAXHandler.fatalError = xmlParserError;
358}