blob: 9b7e504f2734b85048299082d97bb2456c9b0642 [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"
Daniel Veillardccb09631998-10-27 06:21:04 +000011#include "entities.h"
Daniel Veillard260a68f1998-08-13 03:39:55 +000012#include "error.h"
13
14/* #define DEBUG_SAX */
15
Daniel Veillard97b58771998-10-20 06:14:16 +000016/**
17 * getPublicId:
18 * @ctxt: An XML parser context
19 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000020 * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
Daniel Veillard97b58771998-10-20 06:14:16 +000021 *
22 * return values: a CHAR *
Daniel Veillard260a68f1998-08-13 03:39:55 +000023 */
Daniel Veillard97b58771998-10-20 06:14:16 +000024const CHAR *
25getPublicId(xmlParserCtxtPtr ctxt)
26{
Daniel Veillard260a68f1998-08-13 03:39:55 +000027 return(NULL);
28}
29
Daniel Veillard97b58771998-10-20 06:14:16 +000030/**
31 * getSystemId:
32 * @ctxt: An XML parser context
33 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000034 * Return the system ID, basically URI or filename e.g.
Daniel Veillard97b58771998-10-20 06:14:16 +000035 * http://www.sgmlsource.com/dtds/memo.dtd
36 *
37 * return values: a CHAR *
Daniel Veillard260a68f1998-08-13 03:39:55 +000038 */
Daniel Veillard97b58771998-10-20 06:14:16 +000039const CHAR *
40getSystemId(xmlParserCtxtPtr ctxt)
41{
Daniel Veillard260a68f1998-08-13 03:39:55 +000042 return(ctxt->input->filename);
43}
44
Daniel Veillard97b58771998-10-20 06:14:16 +000045/**
46 * getLineNumber:
47 * @ctxt: An XML parser context
48 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000049 * Return the line number of the current parsing point.
Daniel Veillard97b58771998-10-20 06:14:16 +000050 *
51 * return values: an int
Daniel Veillard260a68f1998-08-13 03:39:55 +000052 */
Daniel Veillard97b58771998-10-20 06:14:16 +000053int
54getLineNumber(xmlParserCtxtPtr ctxt)
55{
Daniel Veillard260a68f1998-08-13 03:39:55 +000056 return(ctxt->input->line);
57}
Daniel Veillard97b58771998-10-20 06:14:16 +000058
59/**
60 * getColumnNumber:
61 * @ctxt: An XML parser context
62 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000063 * Return the column number of the current parsing point.
Daniel Veillard97b58771998-10-20 06:14:16 +000064 *
65 * return values: an int
Daniel Veillard260a68f1998-08-13 03:39:55 +000066 */
Daniel Veillard97b58771998-10-20 06:14:16 +000067int
68getColumnNumber(xmlParserCtxtPtr ctxt)
69{
Daniel Veillard260a68f1998-08-13 03:39:55 +000070 return(ctxt->input->col);
71}
72
73/*
74 * The default SAX Locator.
75 */
76
77xmlSAXLocator xmlDefaultSAXLocator = {
78 getPublicId, getSystemId, getLineNumber, getColumnNumber
79};
80
Daniel Veillard97b58771998-10-20 06:14:16 +000081/**
82 * resolveEntity:
83 * @ctxt: An XML parser context
84 * @publicId: The public ID of the entity
85 * @systemId: The system ID of the entity
86 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000087 * Special entity resolver, better left to the parser, it has
88 * more context than the application layer.
Daniel Veillardccb09631998-10-27 06:21:04 +000089 * The default behaviour is to NOT resolve the entities, in that case
90 * the ENTITY_REF nodes are built in the structure (and the parameter
91 * values).
Daniel Veillard97b58771998-10-20 06:14:16 +000092 *
Daniel Veillardccb09631998-10-27 06:21:04 +000093 * return values: the xmlParserInputPtr if inlined or NULL for DOM behaviour.
Daniel Veillard260a68f1998-08-13 03:39:55 +000094 */
Daniel Veillard97b58771998-10-20 06:14:16 +000095xmlParserInputPtr
96resolveEntity(xmlParserCtxtPtr ctxt, const CHAR *publicId, const CHAR *systemId)
97{
Daniel Veillard260a68f1998-08-13 03:39:55 +000098
99#ifdef DEBUG_SAX
100 fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
101#endif
Daniel Veillardccb09631998-10-27 06:21:04 +0000102
Daniel Veillard260a68f1998-08-13 03:39:55 +0000103 return(NULL);
104}
105
Daniel Veillard97b58771998-10-20 06:14:16 +0000106/**
107 * notationDecl:
108 * @ctxt: An XML parser context
109 * @name: The name of the notation
110 * @publicId: The public ID of the entity
111 * @systemId: The system ID of the entity
112 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000113 * What to do when a notation declaration has been parsed.
114 * TODO Not handled currently.
Daniel Veillard97b58771998-10-20 06:14:16 +0000115 *
116 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000117 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000118void
119notationDecl(xmlParserCtxtPtr ctxt, const CHAR *name,
120 const CHAR *publicId, const CHAR *systemId)
121{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000122#ifdef DEBUG_SAX
123 fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
124#endif
125}
126
Daniel Veillard97b58771998-10-20 06:14:16 +0000127/**
128 * unparsedEntityDecl:
129 * @ctxt: An XML parser context
130 * @name: The name of the entity
131 * @publicId: The public ID of the entity
132 * @systemId: The system ID of the entity
133 * @notationName: the name of the notation
134 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000135 * What to do when an unparsed entity declaration is parsed
136 * TODO Create an Entity node.
Daniel Veillard97b58771998-10-20 06:14:16 +0000137 *
138 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000139 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000140void
141unparsedEntityDecl(xmlParserCtxtPtr ctxt, const CHAR *name,
142 const CHAR *publicId, const CHAR *systemId,
143 const CHAR *notationName)
144{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000145#ifdef DEBUG_SAX
146 fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
147 name, publicId, systemId, notationName);
148#endif
149}
150
Daniel Veillard97b58771998-10-20 06:14:16 +0000151/**
152 * setDocumentLocator:
153 * @ctxt: An XML parser context
154 * @loc: A SAX Locator
155 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000156 * Receive the document locator at startup, actually xmlDefaultSAXLocator
157 * Everything is available on the context, so this is useless in our case.
Daniel Veillard97b58771998-10-20 06:14:16 +0000158 *
159 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000160 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000161void
162setDocumentLocator(xmlParserCtxtPtr ctxt, xmlSAXLocatorPtr loc)
163{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000164#ifdef DEBUG_SAX
165 fprintf(stderr, "SAX.setDocumentLocator()\n");
166#endif
167}
168
Daniel Veillard97b58771998-10-20 06:14:16 +0000169/**
170 * startDocument:
171 * @ctxt: An XML parser context
172 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000173 * called when the document start being processed.
Daniel Veillard97b58771998-10-20 06:14:16 +0000174 *
175 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000176 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000177void
178startDocument(xmlParserCtxtPtr ctxt)
179{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000180#ifdef DEBUG_SAX
181 fprintf(stderr, "SAX.startDocument()\n");
182#endif
183}
184
Daniel Veillard97b58771998-10-20 06:14:16 +0000185/**
186 * endDocument:
187 * @ctxt: An XML parser context
188 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000189 * called when the document end has been detected.
Daniel Veillard97b58771998-10-20 06:14:16 +0000190 *
191 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000192 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000193void
194endDocument(xmlParserCtxtPtr ctxt)
195{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000196#ifdef DEBUG_SAX
197 fprintf(stderr, "SAX.endDocument()\n");
198#endif
199}
200
Daniel Veillard97b58771998-10-20 06:14:16 +0000201/**
202 * startElement:
203 * @ctxt: An XML parser context
204 * @name: The element name
205 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000206 * called when an opening tag has been processed.
207 * TODO We currently have a small pblm with the arguments ...
Daniel Veillard97b58771998-10-20 06:14:16 +0000208 *
209 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000210 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000211void
212startElement(xmlParserCtxtPtr ctxt, const CHAR *name)
213{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000214#ifdef DEBUG_SAX
215 fprintf(stderr, "SAX.startElement(%s)\n", name);
216#endif
Daniel Veillard260a68f1998-08-13 03:39:55 +0000217}
218
Daniel Veillard97b58771998-10-20 06:14:16 +0000219/**
220 * endElement:
221 * @ctxt: An XML parser context
222 * @name: The element name
223 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000224 * called when the end of an element has been detected.
Daniel Veillard97b58771998-10-20 06:14:16 +0000225 *
226 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000227 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000228void
229endElement(xmlParserCtxtPtr ctxt, const CHAR *name)
230{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000231#ifdef DEBUG_SAX
232 fprintf(stderr, "SAX.endElement(%s)\n", name);
233#endif
234}
235
Daniel Veillard97b58771998-10-20 06:14:16 +0000236/**
Daniel Veillard11e00581998-10-24 18:27:49 +0000237 * attribute:
238 * @ctxt: An XML parser context
239 * @name: The attribute name
240 * @value: The attribute value
241 *
242 * called when an attribute has been read by the parser.
243 * The default handling is to convert the attribute into an
244 * DOM subtree and past it in a new xmlAttr element added to
245 * the element.
246 *
247 * return values:
248 */
249void
250attribute(xmlParserCtxtPtr ctxt, const CHAR *name, const CHAR *value)
251{
252#ifdef DEBUG_SAX
253 fprintf(stderr, "SAX.attribute(%s, %s)\n", name, value);
254#endif
Daniel Veillard11e00581998-10-24 18:27:49 +0000255}
256
257/**
Daniel Veillard97b58771998-10-20 06:14:16 +0000258 * characters:
259 * @ctxt: An XML parser context
260 * @ch: a CHAR string
261 * @start: the first char in the string
262 * @len: the number of CHAR
263 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000264 * receiving some chars from the parser.
265 * Question: how much at a time ???
Daniel Veillard97b58771998-10-20 06:14:16 +0000266 *
267 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000268 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000269void
270characters(xmlParserCtxtPtr ctxt, const CHAR *ch, int start, int len)
271{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000272 xmlNodePtr lastChild;
273
274#ifdef DEBUG_SAX
275 fprintf(stderr, "SAX.characters(%.30s, %d, %d)\n", ch, start, len);
276#endif
277 /*
278 * Handle the data if any. If there is no child
279 * add it as content, otherwise if the last child is text,
280 * concatenate it, else create a new node of type text.
281 */
282
283 lastChild = xmlGetLastChild(ctxt->node);
284 if (lastChild == NULL)
285 xmlNodeAddContentLen(ctxt->node, &ch[start], len);
286 else {
287 if (xmlNodeIsText(lastChild))
288 xmlTextConcat(lastChild, &ch[start], len);
289 else {
290 lastChild = xmlNewTextLen(&ch[start], len);
291 xmlAddChild(ctxt->node, lastChild);
292 }
293 }
294}
295
Daniel Veillard97b58771998-10-20 06:14:16 +0000296/**
297 * ignorableWhitespace:
298 * @ctxt: An XML parser context
299 * @ch: a CHAR string
300 * @start: the first char in the string
301 * @len: the number of CHAR
302 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000303 * receiving some ignorable whitespaces from the parser.
304 * Question: how much at a time ???
Daniel Veillard97b58771998-10-20 06:14:16 +0000305 *
306 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000307 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000308void
309ignorableWhitespace(xmlParserCtxtPtr ctxt, const CHAR *ch, int start, int len)
310{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000311#ifdef DEBUG_SAX
312 fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d, %d)\n", ch, start, len);
313#endif
314}
315
Daniel Veillard97b58771998-10-20 06:14:16 +0000316/**
317 * processingInstruction:
318 * @ctxt: An XML parser context
319 * @target: the target name
320 * @data: the PI data's
321 * @len: the number of CHAR
322 *
323 * A processing instruction has been parsed.
324 *
325 * return values:
Daniel Veillard260a68f1998-08-13 03:39:55 +0000326 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000327void
328processingInstruction(xmlParserCtxtPtr ctxt, const CHAR *target,
329 const CHAR *data)
330{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000331#ifdef DEBUG_SAX
332 fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
333#endif
334}
335
336xmlSAXHandler xmlDefaultSAXHandler = {
337 resolveEntity,
338 notationDecl,
339 unparsedEntityDecl,
340 setDocumentLocator,
341 startDocument,
342 endDocument,
343 startElement,
344 endElement,
Daniel Veillard11e00581998-10-24 18:27:49 +0000345 attribute,
Daniel Veillard260a68f1998-08-13 03:39:55 +0000346 characters,
347 ignorableWhitespace,
348 processingInstruction,
349 xmlParserWarning,
350 xmlParserError,
351 xmlParserError,
352};
353
Daniel Veillard97b58771998-10-20 06:14:16 +0000354/**
355 * xmlDefaultSAXHandlerInit:
356 *
357 * Initialize the default SAX handler
Daniel Veillard97b58771998-10-20 06:14:16 +0000358 */
359void
360xmlDefaultSAXHandlerInit(void)
361{
Daniel Veillard260a68f1998-08-13 03:39:55 +0000362 xmlDefaultSAXHandler.resolveEntity = resolveEntity;
363 xmlDefaultSAXHandler.notationDecl = notationDecl;
364 xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
365 xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
366 xmlDefaultSAXHandler.startDocument = startDocument;
367 xmlDefaultSAXHandler.endDocument = endDocument;
368 xmlDefaultSAXHandler.startElement = startElement;
369 xmlDefaultSAXHandler.endElement = endElement;
Daniel Veillard11e00581998-10-24 18:27:49 +0000370 xmlDefaultSAXHandler.attribute = attribute;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000371 xmlDefaultSAXHandler.characters = characters;
372 xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
373 xmlDefaultSAXHandler.processingInstruction = processingInstruction;
374 xmlDefaultSAXHandler.warning = xmlParserWarning;
375 xmlDefaultSAXHandler.error = xmlParserError;
376 xmlDefaultSAXHandler.fatalError = xmlParserError;
377}