blob: 28bf0c2fe0160088f76d2183f25e8e5137647df0 [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 *
Daniel Veillard39a1f9a1999-01-17 19:11:59 +00004 * See Copyright for the status of this software.
5 *
Daniel Veillard97b58771998-10-20 06:14:16 +00006 * Daniel Veillard <Daniel.Veillard@w3.org>
Daniel Veillard260a68f1998-08-13 03:39:55 +00007 */
8
9#include <stdio.h>
Seth Alvese7f12e61998-10-01 20:51:15 +000010#include <stdlib.h>
Daniel Veillard260a68f1998-08-13 03:39:55 +000011#include "tree.h"
12#include "parser.h"
Daniel Veillard517752b1999-04-05 12:20:10 +000013#include "parserInternals.h"
14#include "valid.h"
Daniel Veillardccb09631998-10-27 06:21:04 +000015#include "entities.h"
Daniel Veillardd109e371999-03-05 06:26:45 +000016#include "xml-error.h"
Daniel Veillard260a68f1998-08-13 03:39:55 +000017
18/* #define DEBUG_SAX */
19
Daniel Veillard97b58771998-10-20 06:14:16 +000020/**
21 * getPublicId:
Daniel Veillard011b63c1999-06-02 17:44:04 +000022 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +000023 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000024 * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
Daniel Veillard97b58771998-10-20 06:14:16 +000025 *
Daniel Veillard1e346af1999-02-22 10:33:01 +000026 * Returns a CHAR *
Daniel Veillard260a68f1998-08-13 03:39:55 +000027 */
Daniel Veillard97b58771998-10-20 06:14:16 +000028const CHAR *
Daniel Veillard27d88741999-05-29 11:51:49 +000029getPublicId(void *ctx)
Daniel Veillard97b58771998-10-20 06:14:16 +000030{
Daniel Veillard27d88741999-05-29 11:51:49 +000031 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillard260a68f1998-08-13 03:39:55 +000032 return(NULL);
33}
34
Daniel Veillard97b58771998-10-20 06:14:16 +000035/**
36 * getSystemId:
Daniel Veillard011b63c1999-06-02 17:44:04 +000037 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +000038 *
Daniel Veillard011b63c1999-06-02 17:44:04 +000039 * Return the system ID, basically URL or filename e.g.
Daniel Veillard97b58771998-10-20 06:14:16 +000040 * http://www.sgmlsource.com/dtds/memo.dtd
41 *
Daniel Veillard1e346af1999-02-22 10:33:01 +000042 * Returns a CHAR *
Daniel Veillard260a68f1998-08-13 03:39:55 +000043 */
Daniel Veillard97b58771998-10-20 06:14:16 +000044const CHAR *
Daniel Veillard27d88741999-05-29 11:51:49 +000045getSystemId(void *ctx)
Daniel Veillard97b58771998-10-20 06:14:16 +000046{
Daniel Veillard27d88741999-05-29 11:51:49 +000047 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard260a68f1998-08-13 03:39:55 +000048 return(ctxt->input->filename);
49}
50
Daniel Veillard97b58771998-10-20 06:14:16 +000051/**
52 * getLineNumber:
Daniel Veillard011b63c1999-06-02 17:44:04 +000053 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +000054 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000055 * Return the line number of the current parsing point.
Daniel Veillard97b58771998-10-20 06:14:16 +000056 *
Daniel Veillard1e346af1999-02-22 10:33:01 +000057 * Returns an int
Daniel Veillard260a68f1998-08-13 03:39:55 +000058 */
Daniel Veillard97b58771998-10-20 06:14:16 +000059int
Daniel Veillard27d88741999-05-29 11:51:49 +000060getLineNumber(void *ctx)
Daniel Veillard97b58771998-10-20 06:14:16 +000061{
Daniel Veillard27d88741999-05-29 11:51:49 +000062 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard260a68f1998-08-13 03:39:55 +000063 return(ctxt->input->line);
64}
Daniel Veillard97b58771998-10-20 06:14:16 +000065
66/**
67 * getColumnNumber:
Daniel Veillard011b63c1999-06-02 17:44:04 +000068 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +000069 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000070 * Return the column number of the current parsing point.
Daniel Veillard97b58771998-10-20 06:14:16 +000071 *
Daniel Veillard1e346af1999-02-22 10:33:01 +000072 * Returns an int
Daniel Veillard260a68f1998-08-13 03:39:55 +000073 */
Daniel Veillard97b58771998-10-20 06:14:16 +000074int
Daniel Veillard27d88741999-05-29 11:51:49 +000075getColumnNumber(void *ctx)
Daniel Veillard97b58771998-10-20 06:14:16 +000076{
Daniel Veillard27d88741999-05-29 11:51:49 +000077 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard260a68f1998-08-13 03:39:55 +000078 return(ctxt->input->col);
79}
80
81/*
82 * The default SAX Locator.
83 */
84
85xmlSAXLocator xmlDefaultSAXLocator = {
86 getPublicId, getSystemId, getLineNumber, getColumnNumber
87};
88
Daniel Veillard97b58771998-10-20 06:14:16 +000089/**
Daniel Veillard517752b1999-04-05 12:20:10 +000090 * isStandalone:
Daniel Veillard011b63c1999-06-02 17:44:04 +000091 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +000092 *
93 * Is this document tagged standalone ?
94 *
95 * Returns 1 if true
96 */
97int
Daniel Veillard27d88741999-05-29 11:51:49 +000098isStandalone(void *ctx)
Daniel Veillard517752b1999-04-05 12:20:10 +000099{
Daniel Veillard27d88741999-05-29 11:51:49 +0000100 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000101 return(ctxt->myDoc->standalone == 1);
102}
103
104/**
105 * hasInternalSubset:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000106 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000107 *
108 * Does this document has an internal subset
109 *
110 * Returns 1 if true
111 */
112int
Daniel Veillard27d88741999-05-29 11:51:49 +0000113hasInternalSubset(void *ctx)
Daniel Veillard517752b1999-04-05 12:20:10 +0000114{
Daniel Veillard27d88741999-05-29 11:51:49 +0000115 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000116 return(ctxt->myDoc->intSubset != NULL);
117}
118
119/**
120 * hasExternalSubset:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000121 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000122 *
123 * Does this document has an external subset
124 *
125 * Returns 1 if true
126 */
127int
Daniel Veillard27d88741999-05-29 11:51:49 +0000128hasExternalSubset(void *ctx)
Daniel Veillard517752b1999-04-05 12:20:10 +0000129{
Daniel Veillard27d88741999-05-29 11:51:49 +0000130 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000131 return(ctxt->myDoc->extSubset != NULL);
132}
133
134/**
Daniel Veillardb05deb71999-08-10 19:04:08 +0000135 * internalSubset:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000136 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000137 *
138 * Does this document has an internal subset
139 */
140void
Daniel Veillard27d88741999-05-29 11:51:49 +0000141internalSubset(void *ctx, const CHAR *name,
Daniel Veillard517752b1999-04-05 12:20:10 +0000142 const CHAR *ExternalID, const CHAR *SystemID)
143{
Daniel Veillard27d88741999-05-29 11:51:49 +0000144 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000145#ifdef DEBUG_SAX
146 fprintf(stderr, "SAX.internalSubset(%s, %s, %s)\n",
147 name, ExternalID, SystemID);
148#endif
149 xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000150 if (((ExternalID != NULL) || (SystemID != NULL)) &&
151 (ctxt->validate && ctxt->wellFormed && ctxt->myDoc)) {
152 /*
153 * Try to fetch and parse the external subset.
154 */
155 xmlDtdPtr ret = NULL;
156 xmlParserCtxtPtr dtdCtxt;
157 xmlParserInputPtr input = NULL;
158 xmlCharEncoding enc;
159
160 dtdCtxt = xmlNewParserCtxt();
161 if (dtdCtxt == NULL) return;
162
163 /*
164 * Ask the Entity resolver to load the damn thing
165 */
166 if ((ctxt->directory != NULL) && (dtdCtxt->directory == NULL))
167 dtdCtxt->directory = xmlStrdup(ctxt->directory);
168
169 if ((dtdCtxt->sax != NULL) && (dtdCtxt->sax->resolveEntity != NULL))
170 input = dtdCtxt->sax->resolveEntity(dtdCtxt->userData, ExternalID,
171 SystemID);
172 if (input == NULL) {
173 xmlFreeParserCtxt(dtdCtxt);
174 return;
175 }
176
177 /*
178 * plug some encoding conversion routines here. !!!
179 */
180 xmlPushInput(dtdCtxt, input);
181 enc = xmlDetectCharEncoding(dtdCtxt->input->cur);
182 xmlSwitchEncoding(dtdCtxt, enc);
183
184 if (input->filename == NULL)
185 input->filename = xmlStrdup(SystemID);
186 input->line = 1;
187 input->col = 1;
188 input->base = dtdCtxt->input->cur;
189 input->cur = dtdCtxt->input->cur;
190 input->free = NULL;
191
192 /*
193 * let's parse that entity knowing it's an external subset.
194 */
195 xmlParseExternalSubset(dtdCtxt, ExternalID, SystemID);
196
197 if (dtdCtxt->myDoc != NULL) {
198 if (dtdCtxt->wellFormed) {
199 ret = dtdCtxt->myDoc->intSubset;
200 dtdCtxt->myDoc->intSubset = NULL;
201 } else {
202 ret = NULL;
203 }
204 xmlFreeDoc(dtdCtxt->myDoc);
205 dtdCtxt->myDoc = NULL;
206 }
207 xmlFreeParserCtxt(dtdCtxt);
208
209 ctxt->myDoc->extSubset = ret;
Daniel Veillard011b63c1999-06-02 17:44:04 +0000210 }
Daniel Veillard517752b1999-04-05 12:20:10 +0000211}
212
213/**
Daniel Veillard97b58771998-10-20 06:14:16 +0000214 * resolveEntity:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000215 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000216 * @publicId: The public ID of the entity
217 * @systemId: The system ID of the entity
218 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000219 * Special entity resolver, better left to the parser, it has
220 * more context than the application layer.
Daniel Veillardccb09631998-10-27 06:21:04 +0000221 * The default behaviour is to NOT resolve the entities, in that case
222 * the ENTITY_REF nodes are built in the structure (and the parameter
223 * values).
Daniel Veillard97b58771998-10-20 06:14:16 +0000224 *
Daniel Veillard1e346af1999-02-22 10:33:01 +0000225 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000226 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000227xmlParserInputPtr
Daniel Veillard27d88741999-05-29 11:51:49 +0000228resolveEntity(void *ctx, const CHAR *publicId, const CHAR *systemId)
Daniel Veillard97b58771998-10-20 06:14:16 +0000229{
Daniel Veillard011b63c1999-06-02 17:44:04 +0000230 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000231
232#ifdef DEBUG_SAX
233 fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
234#endif
Daniel Veillardccb09631998-10-27 06:21:04 +0000235
Daniel Veillard517752b1999-04-05 12:20:10 +0000236 /*
237 * TODO : not 100% sure that the appropriate handling in that case.
238 */
Daniel Veillard011b63c1999-06-02 17:44:04 +0000239 if (systemId != NULL) {
Daniel Veillard5233ffc1999-07-06 22:25:25 +0000240 if (!xmlStrncmp(systemId, "http://", 7)) {
241 /* !!!!!!!!! TODO */
242 } else if (!xmlStrncmp(systemId, "ftp://", 6)) {
243 /* !!!!!!!!! TODO */
244 } else {
245 return(xmlNewInputFromFile(ctxt, systemId));
246 }
Daniel Veillard011b63c1999-06-02 17:44:04 +0000247 }
Daniel Veillard260a68f1998-08-13 03:39:55 +0000248 return(NULL);
249}
250
Daniel Veillard97b58771998-10-20 06:14:16 +0000251/**
Daniel Veillard517752b1999-04-05 12:20:10 +0000252 * getEntity:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000253 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000254 * @name: The entity name
255 *
256 * Get an entity by name
257 *
Daniel Veillard011b63c1999-06-02 17:44:04 +0000258 * Returns the xmlEntityPtr if found.
Daniel Veillard517752b1999-04-05 12:20:10 +0000259 */
260xmlEntityPtr
Daniel Veillard27d88741999-05-29 11:51:49 +0000261getEntity(void *ctx, const CHAR *name)
Daniel Veillard517752b1999-04-05 12:20:10 +0000262{
Daniel Veillard27d88741999-05-29 11:51:49 +0000263 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000264 xmlEntityPtr ret;
265
266#ifdef DEBUG_SAX
267 fprintf(stderr, "SAX.getEntity(%s)\n", name);
268#endif
269
270 ret = xmlGetDocEntity(ctxt->myDoc, name);
271 return(ret);
272}
273
Daniel Veillardb05deb71999-08-10 19:04:08 +0000274/**
275 * getParameterEntity:
276 * @ctx: the user data (XML parser context)
277 * @name: The entity name
278 *
279 * Get a parameter entity by name
280 *
281 * Returns the xmlEntityPtr if found.
282 */
283xmlEntityPtr
284getParameterEntity(void *ctx, const CHAR *name)
285{
286 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
287 xmlEntityPtr ret;
288
289#ifdef DEBUG_SAX
290 fprintf(stderr, "SAX.getParameterEntity(%s)\n", name);
291#endif
292
293 ret = xmlGetParameterEntity(ctxt->myDoc, name);
294 return(ret);
295}
296
Daniel Veillard517752b1999-04-05 12:20:10 +0000297
298/**
299 * entityDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000300 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000301 * @name: the entity name
302 * @type: the entity type
303 * @publicId: The public ID of the entity
304 * @systemId: The system ID of the entity
305 * @content: the entity value (without processing).
306 *
307 * An entity definition has been parsed
308 */
309void
Daniel Veillard27d88741999-05-29 11:51:49 +0000310entityDecl(void *ctx, const CHAR *name, int type,
Daniel Veillard517752b1999-04-05 12:20:10 +0000311 const CHAR *publicId, const CHAR *systemId, CHAR *content)
312{
Daniel Veillard27d88741999-05-29 11:51:49 +0000313 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000314
315#ifdef DEBUG_SAX
316 fprintf(stderr, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
317 name, type, publicId, systemId, content);
318#endif
319 xmlAddDocEntity(ctxt->myDoc, name, type, publicId, systemId, content);
320}
321
322/**
323 * attributeDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000324 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000325 * @name: the attribute name
326 * @type: the attribute type
327 * @publicId: The public ID of the attribute
328 * @systemId: The system ID of the attribute
329 * @content: the attribute value (without processing).
330 *
331 * An attribute definition has been parsed
332 */
333void
Daniel Veillard27d88741999-05-29 11:51:49 +0000334attributeDecl(void *ctx, const CHAR *elem, const CHAR *name,
Daniel Veillard517752b1999-04-05 12:20:10 +0000335 int type, int def, const CHAR *defaultValue,
336 xmlEnumerationPtr tree)
337{
Daniel Veillard27d88741999-05-29 11:51:49 +0000338 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000339 xmlAttributePtr attr;
Daniel Veillard517752b1999-04-05 12:20:10 +0000340
341#ifdef DEBUG_SAX
342 fprintf(stderr, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
343 elem, name, type, def, defaultValue);
344#endif
Daniel Veillardb05deb71999-08-10 19:04:08 +0000345 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
346 name, type, def, defaultValue, tree);
347 if (attr == 0) ctxt->valid = 0;
348 if (ctxt->validate && ctxt->wellFormed &&
349 ctxt->myDoc && ctxt->myDoc->intSubset)
350 ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
351 attr);
Daniel Veillard517752b1999-04-05 12:20:10 +0000352}
353
354/**
355 * elementDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000356 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000357 * @name: the element name
358 * @type: the element type
359 * @publicId: The public ID of the element
360 * @systemId: The system ID of the element
361 * @content: the element value (without processing).
362 *
363 * An element definition has been parsed
364 */
365void
Daniel Veillard27d88741999-05-29 11:51:49 +0000366elementDecl(void *ctx, const CHAR *name, int type,
Daniel Veillard517752b1999-04-05 12:20:10 +0000367 xmlElementContentPtr content)
368{
Daniel Veillard27d88741999-05-29 11:51:49 +0000369 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000370 xmlElementPtr elem;
Daniel Veillard517752b1999-04-05 12:20:10 +0000371
372#ifdef DEBUG_SAX
373 fprintf(stderr, "SAX.elementDecl(%s, %d, ...)\n",
374 name, type);
375#endif
Daniel Veillardb05deb71999-08-10 19:04:08 +0000376
377 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
378 name, type, content);
379 if (elem == 0) ctxt->valid = 0;
380 if (ctxt->validate && ctxt->wellFormed &&
381 ctxt->myDoc && ctxt->myDoc->intSubset)
382 ctxt->valid &= xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
Daniel Veillard517752b1999-04-05 12:20:10 +0000383}
384
385/**
Daniel Veillard97b58771998-10-20 06:14:16 +0000386 * notationDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000387 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000388 * @name: The name of the notation
389 * @publicId: The public ID of the entity
390 * @systemId: The system ID of the entity
391 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000392 * What to do when a notation declaration has been parsed.
393 * TODO Not handled currently.
394 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000395void
Daniel Veillard27d88741999-05-29 11:51:49 +0000396notationDecl(void *ctx, const CHAR *name,
Daniel Veillard97b58771998-10-20 06:14:16 +0000397 const CHAR *publicId, const CHAR *systemId)
398{
Daniel Veillard27d88741999-05-29 11:51:49 +0000399 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000400 xmlNotationPtr nota;
401
Daniel Veillard260a68f1998-08-13 03:39:55 +0000402#ifdef DEBUG_SAX
403 fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
404#endif
Daniel Veillardb05deb71999-08-10 19:04:08 +0000405
406 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
407 publicId, systemId);
408 if (nota == 0) ctxt->valid = 0;
409 if (ctxt->validate && ctxt->wellFormed &&
410 ctxt->myDoc && ctxt->myDoc->intSubset)
411 ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
412 nota);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000413}
414
Daniel Veillard97b58771998-10-20 06:14:16 +0000415/**
416 * unparsedEntityDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000417 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000418 * @name: The name of the entity
419 * @publicId: The public ID of the entity
420 * @systemId: The system ID of the entity
421 * @notationName: the name of the notation
422 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000423 * What to do when an unparsed entity declaration is parsed
424 * TODO Create an Entity node.
425 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000426void
Daniel Veillard27d88741999-05-29 11:51:49 +0000427unparsedEntityDecl(void *ctx, const CHAR *name,
Daniel Veillard97b58771998-10-20 06:14:16 +0000428 const CHAR *publicId, const CHAR *systemId,
429 const CHAR *notationName)
430{
Daniel Veillard27d88741999-05-29 11:51:49 +0000431 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillard260a68f1998-08-13 03:39:55 +0000432#ifdef DEBUG_SAX
433 fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
434 name, publicId, systemId, notationName);
435#endif
436}
437
Daniel Veillard97b58771998-10-20 06:14:16 +0000438/**
439 * setDocumentLocator:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000440 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000441 * @loc: A SAX Locator
442 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000443 * Receive the document locator at startup, actually xmlDefaultSAXLocator
444 * Everything is available on the context, so this is useless in our case.
445 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000446void
Daniel Veillard27d88741999-05-29 11:51:49 +0000447setDocumentLocator(void *ctx, xmlSAXLocatorPtr loc)
Daniel Veillard97b58771998-10-20 06:14:16 +0000448{
Daniel Veillard27d88741999-05-29 11:51:49 +0000449 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillard260a68f1998-08-13 03:39:55 +0000450#ifdef DEBUG_SAX
451 fprintf(stderr, "SAX.setDocumentLocator()\n");
452#endif
453}
454
Daniel Veillard97b58771998-10-20 06:14:16 +0000455/**
456 * startDocument:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000457 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000458 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000459 * called when the document start being processed.
460 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000461void
Daniel Veillard27d88741999-05-29 11:51:49 +0000462startDocument(void *ctx)
Daniel Veillard97b58771998-10-20 06:14:16 +0000463{
Daniel Veillard27d88741999-05-29 11:51:49 +0000464 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000465 xmlDocPtr doc;
466
Daniel Veillard260a68f1998-08-13 03:39:55 +0000467#ifdef DEBUG_SAX
468 fprintf(stderr, "SAX.startDocument()\n");
469#endif
Daniel Veillard517752b1999-04-05 12:20:10 +0000470 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
471 if (doc != NULL) {
472 if (ctxt->encoding != NULL)
473 doc->encoding = xmlStrdup(ctxt->encoding);
474 else
475 doc->encoding = NULL;
476 doc->standalone = ctxt->standalone;
477 }
Daniel Veillard260a68f1998-08-13 03:39:55 +0000478}
479
Daniel Veillard97b58771998-10-20 06:14:16 +0000480/**
481 * endDocument:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000482 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000483 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000484 * called when the document end has been detected.
485 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000486void
Daniel Veillard27d88741999-05-29 11:51:49 +0000487endDocument(void *ctx)
Daniel Veillard97b58771998-10-20 06:14:16 +0000488{
Daniel Veillard27d88741999-05-29 11:51:49 +0000489 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillard260a68f1998-08-13 03:39:55 +0000490#ifdef DEBUG_SAX
491 fprintf(stderr, "SAX.endDocument()\n");
492#endif
493}
494
Daniel Veillard97b58771998-10-20 06:14:16 +0000495/**
Daniel Veillard517752b1999-04-05 12:20:10 +0000496 * attribute:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000497 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000498 * @name: The attribute name
499 * @value: The attribute value
500 *
501 * Handle an attribute that has been read by the parser.
502 * The default handling is to convert the attribute into an
503 * DOM subtree and past it in a new xmlAttr element added to
504 * the element.
505 */
506void
Daniel Veillard27d88741999-05-29 11:51:49 +0000507attribute(void *ctx, const CHAR *fullname, const CHAR *value)
Daniel Veillard517752b1999-04-05 12:20:10 +0000508{
Daniel Veillard27d88741999-05-29 11:51:49 +0000509 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000510 xmlAttrPtr ret;
511 CHAR *name;
512 CHAR *ns;
513
514/****************
515#ifdef DEBUG_SAX
516 fprintf(stderr, "SAX.attribute(%s, %s)\n", fullname, value);
517#endif
518 ****************/
519 /*
520 * Split the full name into a namespace prefix and the tag name
521 */
522 name = xmlSplitQName(fullname, &ns);
523
524 /*
525 * Check whether it's a namespace definition
526 */
527 if ((ns == NULL) &&
528 (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
529 (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
530 /* a default namespace definition */
531 xmlNewNs(ctxt->node, value, NULL);
532 if (name != NULL)
533 free(name);
534 return;
535 }
536 if ((ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
537 (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
538 /* a standard namespace definition */
539 xmlNewNs(ctxt->node, value, name);
540 free(ns);
541 if (name != NULL)
542 free(name);
543 return;
544 }
545
546 ret = xmlNewProp(ctxt->node, name, NULL);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000547
Daniel Veillard011b63c1999-06-02 17:44:04 +0000548 if ((ret != NULL) && (ctxt->replaceEntities == 0))
Daniel Veillard517752b1999-04-05 12:20:10 +0000549 ret->val = xmlStringGetNodeList(ctxt->myDoc, value);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000550
551 if (ctxt->validate && ctxt->wellFormed &&
552 ctxt->myDoc && ctxt->myDoc->intSubset)
553 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
554 ctxt->node, ret, value);
555
Daniel Veillard517752b1999-04-05 12:20:10 +0000556 if (name != NULL)
557 free(name);
558 if (ns != NULL)
559 free(ns);
560}
561
562/**
Daniel Veillard97b58771998-10-20 06:14:16 +0000563 * startElement:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000564 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000565 * @name: The element name
Daniel Veillard517752b1999-04-05 12:20:10 +0000566 * @atts: An array of name/value attributes pairs, NULL terminated
Daniel Veillard97b58771998-10-20 06:14:16 +0000567 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000568 * called when an opening tag has been processed.
569 * TODO We currently have a small pblm with the arguments ...
570 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000571void
Daniel Veillard27d88741999-05-29 11:51:49 +0000572startElement(void *ctx, const CHAR *fullname, const CHAR **atts)
Daniel Veillard97b58771998-10-20 06:14:16 +0000573{
Daniel Veillard27d88741999-05-29 11:51:49 +0000574 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000575 xmlNodePtr ret;
576 xmlNodePtr parent = ctxt->node;
577 xmlNsPtr ns;
578 CHAR *name;
579 CHAR *prefix;
580 const CHAR *att;
581 const CHAR *value;
582
583 int i;
584
Daniel Veillard260a68f1998-08-13 03:39:55 +0000585#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +0000586 fprintf(stderr, "SAX.startElement(%s)\n", fullname);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000587#endif
Daniel Veillard517752b1999-04-05 12:20:10 +0000588 /*
589 * Split the full name into a namespace prefix and the tag name
590 */
591 name = xmlSplitQName(fullname, &prefix);
592
593
594 /*
595 * Note : the namespace resolution is deferred until the end of the
596 * attributes parsing, since local namespace can be defined as
597 * an attribute at this level.
598 */
599 ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
600 if (ret == NULL) return;
601 if (ctxt->myDoc->root == NULL)
602 ctxt->myDoc->root = ret;
603
604 /*
605 * We are parsing a new node.
606 */
607 nodePush(ctxt, ret);
608
609 /*
610 * Link the child element
611 */
612 if (parent != NULL)
613 xmlAddChild(parent, ctxt->node);
614
615 /*
616 * process all the attributes.
617 */
618 if (atts != NULL) {
619 i = 0;
620 att = atts[i++];
621 value = atts[i++];
622 while ((att != NULL) && (value != NULL)) {
623 /*
624 * Handle one pair of attribute/value
625 */
626 attribute(ctxt, att, value);
627
628 /*
629 * Next ones
630 */
631 att = atts[i++];
632 value = atts[i++];
633 }
634 }
635
636 /*
637 * Search the namespace, note that since the attributes have been
638 * processed, the local namespaces are available.
639 */
640 ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
641 if ((ns == NULL) && (parent != NULL))
642 ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
643 xmlSetNs(ret, ns);
644
645 if (prefix != NULL)
646 free(prefix);
647 if (name != NULL)
648 free(name);
649
Daniel Veillard260a68f1998-08-13 03:39:55 +0000650}
651
Daniel Veillard97b58771998-10-20 06:14:16 +0000652/**
653 * endElement:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000654 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000655 * @name: The element name
656 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000657 * called when the end of an element has been detected.
658 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000659void
Daniel Veillard27d88741999-05-29 11:51:49 +0000660endElement(void *ctx, const CHAR *name)
Daniel Veillard97b58771998-10-20 06:14:16 +0000661{
Daniel Veillard27d88741999-05-29 11:51:49 +0000662 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000663 xmlParserNodeInfo node_info;
664 xmlNodePtr cur = ctxt->node;
665
Daniel Veillard260a68f1998-08-13 03:39:55 +0000666#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +0000667 if (name == NULL)
668 fprintf(stderr, "SAX.endElement(NULL)\n");
669 else
670 fprintf(stderr, "SAX.endElement(%s)\n", name);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000671#endif
Daniel Veillard517752b1999-04-05 12:20:10 +0000672
673 /* Capture end position and add node */
674 if (cur != NULL && ctxt->record_info) {
675 node_info.end_pos = ctxt->input->cur - ctxt->input->base;
676 node_info.end_line = ctxt->input->line;
677 node_info.node = cur;
678 xmlParserAddNodeInfo(ctxt, &node_info);
679 }
680
Daniel Veillardb05deb71999-08-10 19:04:08 +0000681 if (ctxt->validate && ctxt->wellFormed &&
682 ctxt->myDoc && ctxt->myDoc->intSubset)
683 ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
684 cur);
685
686
Daniel Veillard517752b1999-04-05 12:20:10 +0000687 /*
688 * end of parsing of this node.
689 */
690 nodePop(ctxt);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000691}
692
Daniel Veillard97b58771998-10-20 06:14:16 +0000693/**
Daniel Veillard517752b1999-04-05 12:20:10 +0000694 * reference:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000695 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000696 * @name: The entity name
Daniel Veillard11e00581998-10-24 18:27:49 +0000697 *
Daniel Veillard517752b1999-04-05 12:20:10 +0000698 * called when an entity reference is detected.
Daniel Veillard11e00581998-10-24 18:27:49 +0000699 */
700void
Daniel Veillard27d88741999-05-29 11:51:49 +0000701reference(void *ctx, const CHAR *name)
Daniel Veillard11e00581998-10-24 18:27:49 +0000702{
Daniel Veillard27d88741999-05-29 11:51:49 +0000703 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000704 xmlNodePtr ret;
705
Daniel Veillard11e00581998-10-24 18:27:49 +0000706#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +0000707 fprintf(stderr, "SAX.reference(%s)\n", name);
Daniel Veillard11e00581998-10-24 18:27:49 +0000708#endif
Daniel Veillard517752b1999-04-05 12:20:10 +0000709 ret = xmlNewReference(ctxt->myDoc, name);
710 xmlAddChild(ctxt->node, ret);
Daniel Veillard11e00581998-10-24 18:27:49 +0000711}
712
713/**
Daniel Veillard97b58771998-10-20 06:14:16 +0000714 * characters:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000715 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000716 * @ch: a CHAR string
Daniel Veillard97b58771998-10-20 06:14:16 +0000717 * @len: the number of CHAR
718 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000719 * receiving some chars from the parser.
720 * Question: how much at a time ???
721 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000722void
Daniel Veillard27d88741999-05-29 11:51:49 +0000723characters(void *ctx, const CHAR *ch, int len)
Daniel Veillard97b58771998-10-20 06:14:16 +0000724{
Daniel Veillard27d88741999-05-29 11:51:49 +0000725 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000726 xmlNodePtr lastChild;
727
728#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +0000729 fprintf(stderr, "SAX.characters(%.30s, %d)\n", ch, len);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000730#endif
731 /*
732 * Handle the data if any. If there is no child
733 * add it as content, otherwise if the last child is text,
734 * concatenate it, else create a new node of type text.
735 */
736
737 lastChild = xmlGetLastChild(ctxt->node);
738 if (lastChild == NULL)
Daniel Veillard517752b1999-04-05 12:20:10 +0000739 xmlNodeAddContentLen(ctxt->node, ch, len);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000740 else {
741 if (xmlNodeIsText(lastChild))
Daniel Veillard517752b1999-04-05 12:20:10 +0000742 xmlTextConcat(lastChild, ch, len);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000743 else {
Daniel Veillard517752b1999-04-05 12:20:10 +0000744 lastChild = xmlNewTextLen(ch, len);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000745 xmlAddChild(ctxt->node, lastChild);
746 }
747 }
748}
749
Daniel Veillard97b58771998-10-20 06:14:16 +0000750/**
751 * ignorableWhitespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000752 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000753 * @ch: a CHAR string
Daniel Veillard97b58771998-10-20 06:14:16 +0000754 * @len: the number of CHAR
755 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000756 * receiving some ignorable whitespaces from the parser.
757 * Question: how much at a time ???
758 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000759void
Daniel Veillard27d88741999-05-29 11:51:49 +0000760ignorableWhitespace(void *ctx, const CHAR *ch, int len)
Daniel Veillard97b58771998-10-20 06:14:16 +0000761{
Daniel Veillard27d88741999-05-29 11:51:49 +0000762 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillard260a68f1998-08-13 03:39:55 +0000763#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +0000764 fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000765#endif
766}
767
Daniel Veillard97b58771998-10-20 06:14:16 +0000768/**
769 * processingInstruction:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000770 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000771 * @target: the target name
772 * @data: the PI data's
773 * @len: the number of CHAR
774 *
775 * A processing instruction has been parsed.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000776 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000777void
Daniel Veillard27d88741999-05-29 11:51:49 +0000778processingInstruction(void *ctx, const CHAR *target,
Daniel Veillard97b58771998-10-20 06:14:16 +0000779 const CHAR *data)
780{
Daniel Veillard27d88741999-05-29 11:51:49 +0000781 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillard260a68f1998-08-13 03:39:55 +0000782#ifdef DEBUG_SAX
783 fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
784#endif
785}
786
Daniel Veillard517752b1999-04-05 12:20:10 +0000787/**
788 * globalNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000789 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000790 * @href: the namespace associated URN
791 * @prefix: the namespace prefix
792 *
793 * An old global namespace has been parsed.
794 */
795void
Daniel Veillard27d88741999-05-29 11:51:49 +0000796globalNamespace(void *ctx, const CHAR *href, const CHAR *prefix)
Daniel Veillard517752b1999-04-05 12:20:10 +0000797{
Daniel Veillard27d88741999-05-29 11:51:49 +0000798 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000799#ifdef DEBUG_SAX
800 fprintf(stderr, "SAX.globalNamespace(%s, %s)\n", href, prefix);
801#endif
802 xmlNewGlobalNs(ctxt->myDoc, href, prefix);
803}
804
805/**
806 * setNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000807 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000808 * @name: the namespace prefix
809 *
810 * Set the current element namespace.
811 */
812void
Daniel Veillard27d88741999-05-29 11:51:49 +0000813setNamespace(void *ctx, const CHAR *name)
Daniel Veillard517752b1999-04-05 12:20:10 +0000814{
Daniel Veillard27d88741999-05-29 11:51:49 +0000815 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000816 xmlNsPtr ns;
817 xmlNodePtr parent;
818
819#ifdef DEBUG_SAX
820 fprintf(stderr, "SAX.setNamespace(%s)\n", name);
821#endif
822 ns = xmlSearchNs(ctxt->myDoc, ctxt->node, name);
823 if (ns == NULL) { /* ctxt->node may not have a parent yet ! */
824 if (ctxt->nodeNr >= 2) {
825 parent = ctxt->nodeTab[ctxt->nodeNr - 2];
826 if (parent != NULL)
827 ns = xmlSearchNs(ctxt->myDoc, parent, name);
828 }
829 }
830 xmlSetNs(ctxt->node, ns);
831}
832
833/**
834 * getNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000835 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000836 *
837 * Get the current element namespace.
838 */
839xmlNsPtr
Daniel Veillard27d88741999-05-29 11:51:49 +0000840getNamespace(void *ctx)
Daniel Veillard517752b1999-04-05 12:20:10 +0000841{
Daniel Veillard27d88741999-05-29 11:51:49 +0000842 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000843 xmlNsPtr ret;
844
845#ifdef DEBUG_SAX
846 fprintf(stderr, "SAX.getNamespace()\n");
847#endif
848 ret = ctxt->node->ns;
849 return(ret);
850}
851
852/**
853 * checkNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000854 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000855 * @namespace: the namespace to check against
856 *
857 * Check that the current element namespace is the same as the
858 * one read upon parsing.
859 */
860int
Daniel Veillard27d88741999-05-29 11:51:49 +0000861checkNamespace(void *ctx, CHAR *namespace)
Daniel Veillard517752b1999-04-05 12:20:10 +0000862{
Daniel Veillard27d88741999-05-29 11:51:49 +0000863 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000864 xmlNodePtr cur = ctxt->node;
865
866#ifdef DEBUG_SAX
867 fprintf(stderr, "SAX.checkNamespace(%s)\n", namespace);
868#endif
869
870 /*
871 * Check that the Name in the ETag is the same as in the STag.
872 */
873 if (namespace == NULL) {
874 if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
875 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
876 ctxt->sax->error(ctxt,
877 "End tags for %s don't hold the namespace %s\n",
878 cur->name, cur->ns->prefix);
879 ctxt->wellFormed = 0;
880 }
881 } else {
882 if ((cur->ns == NULL) || (cur->ns->prefix == NULL)) {
883 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
884 ctxt->sax->error(ctxt,
885 "End tags %s holds a prefix %s not used by the open tag\n",
886 cur->name, namespace);
887 ctxt->wellFormed = 0;
888 } else if (strcmp(namespace, cur->ns->prefix)) {
889 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
890 ctxt->sax->error(ctxt,
891 "Start and End tags for %s don't use the same namespaces: %s and %s\n",
892 cur->name, cur->ns->prefix, namespace);
893 ctxt->wellFormed = 0;
894 } else
895 return(1);
896 }
897 return(0);
898}
899
900/**
901 * namespaceDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000902 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000903 * @href: the namespace associated URN
904 * @prefix: the namespace prefix
905 *
906 * A namespace has been parsed.
907 */
908void
Daniel Veillard27d88741999-05-29 11:51:49 +0000909namespaceDecl(void *ctx, const CHAR *href, const CHAR *prefix)
Daniel Veillard517752b1999-04-05 12:20:10 +0000910{
Daniel Veillard27d88741999-05-29 11:51:49 +0000911 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000912#ifdef DEBUG_SAX
913 if (prefix == NULL)
914 fprintf(stderr, "SAX.namespaceDecl(%s, NULL)\n", href);
915 else
916 fprintf(stderr, "SAX.namespaceDecl(%s, %s)\n", href, prefix);
917#endif
918 xmlNewNs(ctxt->node, href, prefix);
919}
920
921/**
922 * comment:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000923 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000924 * @value: the comment content
925 *
926 * A comment has been parsed.
927 */
928void
Daniel Veillard27d88741999-05-29 11:51:49 +0000929comment(void *ctx, const CHAR *value)
Daniel Veillard517752b1999-04-05 12:20:10 +0000930{
Daniel Veillard27d88741999-05-29 11:51:49 +0000931 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard14fff061999-06-22 21:49:07 +0000932 xmlNodePtr ret;
933
Daniel Veillard517752b1999-04-05 12:20:10 +0000934#ifdef DEBUG_SAX
935 fprintf(stderr, "SAX.comment(%s)\n", value);
936#endif
Daniel Veillard14fff061999-06-22 21:49:07 +0000937 ret = xmlNewDocComment(ctxt->myDoc, value);
938 xmlAddChild(ctxt->node, ret);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000939 /* !!!!! merges */
940}
941
942/**
943 * cdataBlock:
944 * @ctx: the user data (XML parser context)
945 * @value: The pcdata content
946 * @len: the block length
947 *
948 * called when a pcdata block has been parsed
949 */
950void
951cdataBlock(void *ctx, const CHAR *value, int len)
952{
953 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
954 xmlNodePtr ret;
955
956#ifdef DEBUG_SAX
957 fprintf(stderr, "SAX.pcdata(%s, %d)\n", name, len);
958#endif
959 ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
960 xmlAddChild(ctxt->node, ret);
961 /* !!!!! merges */
Daniel Veillard517752b1999-04-05 12:20:10 +0000962}
963
Daniel Veillardbe70ff71999-07-05 16:50:46 +0000964/*
965 * Default handler for XML, builds the DOM tree
966 */
Daniel Veillard260a68f1998-08-13 03:39:55 +0000967xmlSAXHandler xmlDefaultSAXHandler = {
Daniel Veillard517752b1999-04-05 12:20:10 +0000968 internalSubset,
969 isStandalone,
970 hasInternalSubset,
971 hasExternalSubset,
Daniel Veillard260a68f1998-08-13 03:39:55 +0000972 resolveEntity,
Daniel Veillard517752b1999-04-05 12:20:10 +0000973 getEntity,
974 entityDecl,
Daniel Veillard260a68f1998-08-13 03:39:55 +0000975 notationDecl,
Daniel Veillard517752b1999-04-05 12:20:10 +0000976 attributeDecl,
977 elementDecl,
Daniel Veillard260a68f1998-08-13 03:39:55 +0000978 unparsedEntityDecl,
979 setDocumentLocator,
980 startDocument,
981 endDocument,
982 startElement,
983 endElement,
Daniel Veillard517752b1999-04-05 12:20:10 +0000984 reference,
Daniel Veillard260a68f1998-08-13 03:39:55 +0000985 characters,
986 ignorableWhitespace,
987 processingInstruction,
Daniel Veillard517752b1999-04-05 12:20:10 +0000988 comment,
Daniel Veillard260a68f1998-08-13 03:39:55 +0000989 xmlParserWarning,
990 xmlParserError,
991 xmlParserError,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000992 getParameterEntity,
993 cdataBlock,
Daniel Veillard260a68f1998-08-13 03:39:55 +0000994};
995
Daniel Veillard97b58771998-10-20 06:14:16 +0000996/**
997 * xmlDefaultSAXHandlerInit:
998 *
999 * Initialize the default SAX handler
Daniel Veillard97b58771998-10-20 06:14:16 +00001000 */
1001void
1002xmlDefaultSAXHandlerInit(void)
1003{
Daniel Veillard517752b1999-04-05 12:20:10 +00001004 xmlDefaultSAXHandler.internalSubset = internalSubset;
1005 xmlDefaultSAXHandler.isStandalone = isStandalone;
1006 xmlDefaultSAXHandler.hasInternalSubset = hasInternalSubset;
1007 xmlDefaultSAXHandler.hasExternalSubset = hasExternalSubset;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001008 xmlDefaultSAXHandler.resolveEntity = resolveEntity;
Daniel Veillard517752b1999-04-05 12:20:10 +00001009 xmlDefaultSAXHandler.getEntity = getEntity;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001010 xmlDefaultSAXHandler.getParameterEntity = getParameterEntity;
Daniel Veillard517752b1999-04-05 12:20:10 +00001011 xmlDefaultSAXHandler.entityDecl = entityDecl;
1012 xmlDefaultSAXHandler.attributeDecl = attributeDecl;
1013 xmlDefaultSAXHandler.elementDecl = elementDecl;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001014 xmlDefaultSAXHandler.notationDecl = notationDecl;
1015 xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
1016 xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1017 xmlDefaultSAXHandler.startDocument = startDocument;
1018 xmlDefaultSAXHandler.endDocument = endDocument;
1019 xmlDefaultSAXHandler.startElement = startElement;
1020 xmlDefaultSAXHandler.endElement = endElement;
Daniel Veillard517752b1999-04-05 12:20:10 +00001021 xmlDefaultSAXHandler.reference = reference;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001022 xmlDefaultSAXHandler.characters = characters;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001023 xmlDefaultSAXHandler.cdataBlock = cdataBlock;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001024 xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1025 xmlDefaultSAXHandler.processingInstruction = processingInstruction;
Daniel Veillard517752b1999-04-05 12:20:10 +00001026 xmlDefaultSAXHandler.comment = comment;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001027 xmlDefaultSAXHandler.warning = xmlParserWarning;
1028 xmlDefaultSAXHandler.error = xmlParserError;
1029 xmlDefaultSAXHandler.fatalError = xmlParserError;
1030}
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001031
1032/*
1033 * Default handler for HTML, builds the DOM tree
1034 */
1035xmlSAXHandler htmlDefaultSAXHandler = {
1036 NULL,
1037 NULL,
1038 NULL,
1039 NULL,
1040 NULL,
1041 getEntity,
1042 NULL,
1043 NULL,
1044 NULL,
1045 NULL,
1046 NULL,
1047 setDocumentLocator,
1048 startDocument,
1049 endDocument,
1050 startElement,
1051 endElement,
1052 NULL,
1053 characters,
1054 ignorableWhitespace,
1055 NULL,
1056 comment,
1057 xmlParserWarning,
1058 xmlParserError,
1059 xmlParserError,
Daniel Veillardb05deb71999-08-10 19:04:08 +00001060 getParameterEntity,
1061 NULL,
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001062};
1063
1064/**
1065 * htmlDefaultSAXHandlerInit:
1066 *
1067 * Initialize the default SAX handler
1068 */
1069void
1070htmlDefaultSAXHandlerInit(void)
1071{
1072 htmlDefaultSAXHandler.internalSubset = NULL;
1073 htmlDefaultSAXHandler.isStandalone = NULL;
1074 htmlDefaultSAXHandler.hasInternalSubset = NULL;
1075 htmlDefaultSAXHandler.hasExternalSubset = NULL;
1076 htmlDefaultSAXHandler.resolveEntity = NULL;
1077 htmlDefaultSAXHandler.getEntity = getEntity;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001078 htmlDefaultSAXHandler.getParameterEntity = NULL;
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001079 htmlDefaultSAXHandler.entityDecl = NULL;
1080 htmlDefaultSAXHandler.attributeDecl = NULL;
1081 htmlDefaultSAXHandler.elementDecl = NULL;
1082 htmlDefaultSAXHandler.notationDecl = NULL;
1083 htmlDefaultSAXHandler.unparsedEntityDecl = NULL;
1084 htmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1085 htmlDefaultSAXHandler.startDocument = startDocument;
1086 htmlDefaultSAXHandler.endDocument = endDocument;
1087 htmlDefaultSAXHandler.startElement = startElement;
1088 htmlDefaultSAXHandler.endElement = endElement;
1089 htmlDefaultSAXHandler.reference = NULL;
1090 htmlDefaultSAXHandler.characters = characters;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001091 htmlDefaultSAXHandler.cdataBlock = NULL;
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001092 htmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1093 htmlDefaultSAXHandler.processingInstruction = NULL;
1094 htmlDefaultSAXHandler.comment = comment;
1095 htmlDefaultSAXHandler.warning = xmlParserWarning;
1096 htmlDefaultSAXHandler.error = xmlParserError;
1097 htmlDefaultSAXHandler.fatalError = xmlParserError;
1098}