blob: 99283e598c880d5cdf9ca713b3810a8d56457d85 [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
Daniel Veillard7f7d1111999-09-22 09:46:25 +00009
Daniel Veillard3c558c31999-12-22 11:30:41 +000010#ifdef WIN32
11#include "win32config.h"
12#else
13#include "config.h"
14#endif
Daniel Veillard260a68f1998-08-13 03:39:55 +000015#include <stdio.h>
Seth Alvese7f12e61998-10-01 20:51:15 +000016#include <stdlib.h>
Daniel Veillard32bc74e2000-07-14 14:49:25 +000017#include <string.h>
Daniel Veillard361d8452000-04-03 19:48:13 +000018#include <libxml/xmlmemory.h>
19#include <libxml/tree.h>
20#include <libxml/parser.h>
21#include <libxml/parserInternals.h>
22#include <libxml/valid.h>
23#include <libxml/entities.h>
Daniel Veillard32bc74e2000-07-14 14:49:25 +000024#include <libxml/xml-error.h>
Daniel Veillard361d8452000-04-03 19:48:13 +000025#include <libxml/debugXML.h>
26#include <libxml/xmlIO.h>
27#include <libxml/SAX.h>
Daniel Veillardbe803962000-06-28 23:40:59 +000028#include <libxml/uri.h>
Daniel Veillardd83eb822000-06-30 18:39:56 +000029#include <libxml/HTMLtree.h>
Daniel Veillard260a68f1998-08-13 03:39:55 +000030
31/* #define DEBUG_SAX */
Daniel Veillardb96e6431999-08-29 21:02:19 +000032/* #define DEBUG_SAX_TREE */
Daniel Veillard260a68f1998-08-13 03:39:55 +000033
Daniel Veillard97b58771998-10-20 06:14:16 +000034/**
35 * getPublicId:
Daniel Veillard011b63c1999-06-02 17:44:04 +000036 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +000037 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000038 * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
Daniel Veillard97b58771998-10-20 06:14:16 +000039 *
Daniel Veillarddd6b3671999-09-23 22:19:22 +000040 * Returns a xmlChar *
Daniel Veillard260a68f1998-08-13 03:39:55 +000041 */
Daniel Veillarddd6b3671999-09-23 22:19:22 +000042const xmlChar *
Daniel Veillard27d88741999-05-29 11:51:49 +000043getPublicId(void *ctx)
Daniel Veillard97b58771998-10-20 06:14:16 +000044{
Daniel Veillard27d88741999-05-29 11:51:49 +000045 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillard260a68f1998-08-13 03:39:55 +000046 return(NULL);
47}
48
Daniel Veillard97b58771998-10-20 06:14:16 +000049/**
50 * getSystemId:
Daniel Veillard011b63c1999-06-02 17:44:04 +000051 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +000052 *
Daniel Veillard011b63c1999-06-02 17:44:04 +000053 * Return the system ID, basically URL or filename e.g.
Daniel Veillard97b58771998-10-20 06:14:16 +000054 * http://www.sgmlsource.com/dtds/memo.dtd
55 *
Daniel Veillarddd6b3671999-09-23 22:19:22 +000056 * Returns a xmlChar *
Daniel Veillard260a68f1998-08-13 03:39:55 +000057 */
Daniel Veillarddd6b3671999-09-23 22:19:22 +000058const xmlChar *
Daniel Veillard27d88741999-05-29 11:51:49 +000059getSystemId(void *ctx)
Daniel Veillard97b58771998-10-20 06:14:16 +000060{
Daniel Veillard27d88741999-05-29 11:51:49 +000061 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillardb96e6431999-08-29 21:02:19 +000062 return(BAD_CAST ctxt->input->filename);
Daniel Veillard260a68f1998-08-13 03:39:55 +000063}
64
Daniel Veillard97b58771998-10-20 06:14:16 +000065/**
66 * getLineNumber:
Daniel Veillard011b63c1999-06-02 17:44:04 +000067 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +000068 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000069 * Return the line number of the current parsing point.
Daniel Veillard97b58771998-10-20 06:14:16 +000070 *
Daniel Veillard1e346af1999-02-22 10:33:01 +000071 * Returns an int
Daniel Veillard260a68f1998-08-13 03:39:55 +000072 */
Daniel Veillard97b58771998-10-20 06:14:16 +000073int
Daniel Veillard27d88741999-05-29 11:51:49 +000074getLineNumber(void *ctx)
Daniel Veillard97b58771998-10-20 06:14:16 +000075{
Daniel Veillard27d88741999-05-29 11:51:49 +000076 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard260a68f1998-08-13 03:39:55 +000077 return(ctxt->input->line);
78}
Daniel Veillard97b58771998-10-20 06:14:16 +000079
80/**
81 * getColumnNumber:
Daniel Veillard011b63c1999-06-02 17:44:04 +000082 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +000083 *
Daniel Veillard260a68f1998-08-13 03:39:55 +000084 * Return the column number of the current parsing point.
Daniel Veillard97b58771998-10-20 06:14:16 +000085 *
Daniel Veillard1e346af1999-02-22 10:33:01 +000086 * Returns an int
Daniel Veillard260a68f1998-08-13 03:39:55 +000087 */
Daniel Veillard97b58771998-10-20 06:14:16 +000088int
Daniel Veillard27d88741999-05-29 11:51:49 +000089getColumnNumber(void *ctx)
Daniel Veillard97b58771998-10-20 06:14:16 +000090{
Daniel Veillard27d88741999-05-29 11:51:49 +000091 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard260a68f1998-08-13 03:39:55 +000092 return(ctxt->input->col);
93}
94
95/*
96 * The default SAX Locator.
97 */
98
99xmlSAXLocator xmlDefaultSAXLocator = {
100 getPublicId, getSystemId, getLineNumber, getColumnNumber
101};
102
Daniel Veillard97b58771998-10-20 06:14:16 +0000103/**
Daniel Veillard517752b1999-04-05 12:20:10 +0000104 * isStandalone:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000105 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000106 *
107 * Is this document tagged standalone ?
108 *
109 * Returns 1 if true
110 */
111int
Daniel Veillard27d88741999-05-29 11:51:49 +0000112isStandalone(void *ctx)
Daniel Veillard517752b1999-04-05 12:20:10 +0000113{
Daniel Veillard27d88741999-05-29 11:51:49 +0000114 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000115 return(ctxt->myDoc->standalone == 1);
116}
117
118/**
119 * hasInternalSubset:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000120 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000121 *
122 * Does this document has an internal subset
123 *
124 * Returns 1 if true
125 */
126int
Daniel Veillard27d88741999-05-29 11:51:49 +0000127hasInternalSubset(void *ctx)
Daniel Veillard517752b1999-04-05 12:20:10 +0000128{
Daniel Veillard27d88741999-05-29 11:51:49 +0000129 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000130 return(ctxt->myDoc->intSubset != NULL);
131}
132
133/**
134 * hasExternalSubset:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000135 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000136 *
137 * Does this document has an external subset
138 *
139 * Returns 1 if true
140 */
141int
Daniel Veillard27d88741999-05-29 11:51:49 +0000142hasExternalSubset(void *ctx)
Daniel Veillard517752b1999-04-05 12:20:10 +0000143{
Daniel Veillard27d88741999-05-29 11:51:49 +0000144 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000145 return(ctxt->myDoc->extSubset != NULL);
146}
147
148/**
Daniel Veillardb05deb71999-08-10 19:04:08 +0000149 * internalSubset:
Daniel Veillard06047432000-04-24 11:33:38 +0000150 * @ctx: the user data (XML parser context)
151 * @name: the root element name
152 * @ExternalID: the external ID
153 * @SystemID: the SYSTEM ID (e.g. filename or URL)
Daniel Veillard517752b1999-04-05 12:20:10 +0000154 *
Daniel Veillard686d6b62000-01-03 11:08:02 +0000155 * Callback on internal subset declaration.
Daniel Veillard517752b1999-04-05 12:20:10 +0000156 */
157void
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000158internalSubset(void *ctx, const xmlChar *name,
159 const xmlChar *ExternalID, const xmlChar *SystemID)
Daniel Veillard517752b1999-04-05 12:20:10 +0000160{
Daniel Veillard27d88741999-05-29 11:51:49 +0000161 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillardd83eb822000-06-30 18:39:56 +0000162 xmlDtdPtr dtd;
Daniel Veillard517752b1999-04-05 12:20:10 +0000163#ifdef DEBUG_SAX
164 fprintf(stderr, "SAX.internalSubset(%s, %s, %s)\n",
165 name, ExternalID, SystemID);
166#endif
Daniel Veillardd83eb822000-06-30 18:39:56 +0000167
168 if (ctxt->myDoc == NULL)
169 return;
170 dtd = xmlGetIntSubset(ctxt->myDoc);
171 if (dtd != NULL) {
Daniel Veillardb8f25c92000-08-19 19:52:36 +0000172 if (ctxt->html)
173 return;
Daniel Veillardd83eb822000-06-30 18:39:56 +0000174 xmlUnlinkNode((xmlNodePtr) dtd);
175 xmlFreeDtd(dtd);
176 ctxt->myDoc->intSubset = NULL;
177 }
178 ctxt->myDoc->intSubset =
179 xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
Daniel Veillardcf461992000-03-14 18:30:20 +0000180}
181
182/**
183 * externalSubset:
184 * @ctx: the user data (XML parser context)
Daniel Veillard06047432000-04-24 11:33:38 +0000185 * @name: the root element name
186 * @ExternalID: the external ID
187 * @SystemID: the SYSTEM ID (e.g. filename or URL)
Daniel Veillardcf461992000-03-14 18:30:20 +0000188 *
189 * Callback on external subset declaration.
190 */
191void
192externalSubset(void *ctx, const xmlChar *name,
193 const xmlChar *ExternalID, const xmlChar *SystemID)
194{
195 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
196#ifdef DEBUG_SAX
197 fprintf(stderr, "SAX.externalSubset(%s, %s, %s)\n",
198 name, ExternalID, SystemID);
199#endif
Daniel Veillardb05deb71999-08-10 19:04:08 +0000200 if (((ExternalID != NULL) || (SystemID != NULL)) &&
201 (ctxt->validate && ctxt->wellFormed && ctxt->myDoc)) {
202 /*
203 * Try to fetch and parse the external subset.
204 */
Daniel Veillardcf461992000-03-14 18:30:20 +0000205 xmlParserInputPtr oldinput;
206 int oldinputNr;
207 int oldinputMax;
208 xmlParserInputPtr *oldinputTab;
209 int oldwellFormed;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000210 xmlParserInputPtr input = NULL;
211 xmlCharEncoding enc;
Daniel Veillard32bc74e2000-07-14 14:49:25 +0000212 int oldcharset;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000213
Daniel Veillardb05deb71999-08-10 19:04:08 +0000214 /*
215 * Ask the Entity resolver to load the damn thing
216 */
Daniel Veillardcf461992000-03-14 18:30:20 +0000217 if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
218 input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000219 SystemID);
220 if (input == NULL) {
Daniel Veillardb05deb71999-08-10 19:04:08 +0000221 return;
222 }
223
Daniel Veillardcf461992000-03-14 18:30:20 +0000224 xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
225
Daniel Veillardb05deb71999-08-10 19:04:08 +0000226 /*
Daniel Veillardcf461992000-03-14 18:30:20 +0000227 * make sure we won't destroy the main document context
Daniel Veillardb05deb71999-08-10 19:04:08 +0000228 */
Daniel Veillardcf461992000-03-14 18:30:20 +0000229 oldinput = ctxt->input;
230 oldinputNr = ctxt->inputNr;
231 oldinputMax = ctxt->inputMax;
232 oldinputTab = ctxt->inputTab;
233 oldwellFormed = ctxt->wellFormed;
Daniel Veillardbe803962000-06-28 23:40:59 +0000234 oldcharset = ctxt->charset;
Daniel Veillardcf461992000-03-14 18:30:20 +0000235
236 ctxt->inputTab = (xmlParserInputPtr *)
237 xmlMalloc(5 * sizeof(xmlParserInputPtr));
238 if (ctxt->inputTab == NULL) {
239 ctxt->errNo = XML_ERR_NO_MEMORY;
240 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
241 ctxt->sax->error(ctxt->userData,
242 "externalSubset: out of memory\n");
243 ctxt->errNo = XML_ERR_NO_MEMORY;
244 ctxt->input = oldinput;
245 ctxt->inputNr = oldinputNr;
246 ctxt->inputMax = oldinputMax;
247 ctxt->inputTab = oldinputTab;
Daniel Veillardbe803962000-06-28 23:40:59 +0000248 ctxt->charset = oldcharset;
Daniel Veillardcf461992000-03-14 18:30:20 +0000249 return;
250 }
251 ctxt->inputNr = 0;
252 ctxt->inputMax = 5;
253 ctxt->input = NULL;
254 xmlPushInput(ctxt, input);
255
256 /*
257 * On the fly encoding conversion if needed
258 */
259 enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
260 xmlSwitchEncoding(ctxt, enc);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000261
262 if (input->filename == NULL)
Daniel Veillardb96e6431999-08-29 21:02:19 +0000263 input->filename = (char *) xmlStrdup(SystemID);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000264 input->line = 1;
265 input->col = 1;
Daniel Veillardcf461992000-03-14 18:30:20 +0000266 input->base = ctxt->input->cur;
267 input->cur = ctxt->input->cur;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000268 input->free = NULL;
269
270 /*
271 * let's parse that entity knowing it's an external subset.
272 */
Daniel Veillardcf461992000-03-14 18:30:20 +0000273 xmlParseExternalSubset(ctxt, ExternalID, SystemID);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000274
Daniel Veillardcf461992000-03-14 18:30:20 +0000275 /*
276 * Free up the external entities
277 */
278
279 while (ctxt->inputNr > 1)
280 xmlPopInput(ctxt);
281 xmlFreeInputStream(ctxt->input);
282 xmlFree(ctxt->inputTab);
283
284 /*
285 * Restore the parsing context of the main entity
286 */
287 ctxt->input = oldinput;
288 ctxt->inputNr = oldinputNr;
289 ctxt->inputMax = oldinputMax;
290 ctxt->inputTab = oldinputTab;
Daniel Veillardbe803962000-06-28 23:40:59 +0000291 ctxt->charset = oldcharset;
Daniel Veillardcf461992000-03-14 18:30:20 +0000292 /* ctxt->wellFormed = oldwellFormed; */
Daniel Veillard011b63c1999-06-02 17:44:04 +0000293 }
Daniel Veillard517752b1999-04-05 12:20:10 +0000294}
295
296/**
Daniel Veillard97b58771998-10-20 06:14:16 +0000297 * resolveEntity:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000298 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000299 * @publicId: The public ID of the entity
300 * @systemId: The system ID of the entity
301 *
Daniel Veillard686d6b62000-01-03 11:08:02 +0000302 * The entity loader, to control the loading of external entities,
303 * the application can either:
304 * - override this resolveEntity() callback in the SAX block
305 * - or better use the xmlSetExternalEntityLoader() function to
306 * set up it's own entity resolution routine
Daniel Veillard97b58771998-10-20 06:14:16 +0000307 *
Daniel Veillard1e346af1999-02-22 10:33:01 +0000308 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000309 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000310xmlParserInputPtr
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000311resolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard97b58771998-10-20 06:14:16 +0000312{
Daniel Veillard011b63c1999-06-02 17:44:04 +0000313 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000314 xmlParserInputPtr ret;
Daniel Veillard04698d92000-09-17 16:00:22 +0000315 xmlChar *URI;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000316 const char *base = NULL;
317
318 if (ctxt->input != NULL)
319 base = ctxt->input->filename;
320 if (base == NULL)
321 base = ctxt->directory;
322
Daniel Veillard04698d92000-09-17 16:00:22 +0000323 URI = xmlBuildURI(systemId, (const xmlChar *) base);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000324
325#ifdef DEBUG_SAX
326 fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
327#endif
Daniel Veillardccb09631998-10-27 06:21:04 +0000328
Daniel Veillard39c7d712000-09-10 16:14:55 +0000329 ret = xmlLoadExternalEntity((const char *) URI,
330 (const char *) publicId, ctxt);
331 if (URI != NULL)
332 xmlFree(URI);
333 return(ret);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000334}
335
Daniel Veillard97b58771998-10-20 06:14:16 +0000336/**
Daniel Veillard517752b1999-04-05 12:20:10 +0000337 * getEntity:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000338 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000339 * @name: The entity name
340 *
341 * Get an entity by name
342 *
Daniel Veillard011b63c1999-06-02 17:44:04 +0000343 * Returns the xmlEntityPtr if found.
Daniel Veillard517752b1999-04-05 12:20:10 +0000344 */
345xmlEntityPtr
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000346getEntity(void *ctx, const xmlChar *name)
Daniel Veillard517752b1999-04-05 12:20:10 +0000347{
Daniel Veillard27d88741999-05-29 11:51:49 +0000348 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000349 xmlEntityPtr ret;
350
351#ifdef DEBUG_SAX
352 fprintf(stderr, "SAX.getEntity(%s)\n", name);
353#endif
354
355 ret = xmlGetDocEntity(ctxt->myDoc, name);
Daniel Veillard87b95392000-08-12 21:12:04 +0000356 if ((ret != NULL) && (ctxt->validate) && (ret->children == NULL) &&
357 (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
358 /*
359 * for validation purposes we really need to fetch and
360 * parse the external entity
361 */
362 int parse;
363 xmlNodePtr children;
364
365 parse = xmlParseCtxtExternalEntity(ctxt,
366 ret->SystemID, ret->ExternalID, &children);
367 xmlAddChildList((xmlNodePtr) ret, children);
368 }
Daniel Veillard517752b1999-04-05 12:20:10 +0000369 return(ret);
370}
371
Daniel Veillardb05deb71999-08-10 19:04:08 +0000372/**
373 * getParameterEntity:
374 * @ctx: the user data (XML parser context)
375 * @name: The entity name
376 *
377 * Get a parameter entity by name
378 *
379 * Returns the xmlEntityPtr if found.
380 */
381xmlEntityPtr
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000382getParameterEntity(void *ctx, const xmlChar *name)
Daniel Veillardb05deb71999-08-10 19:04:08 +0000383{
384 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
385 xmlEntityPtr ret;
386
387#ifdef DEBUG_SAX
388 fprintf(stderr, "SAX.getParameterEntity(%s)\n", name);
389#endif
390
391 ret = xmlGetParameterEntity(ctxt->myDoc, name);
392 return(ret);
393}
394
Daniel Veillard517752b1999-04-05 12:20:10 +0000395
396/**
397 * entityDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000398 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000399 * @name: the entity name
400 * @type: the entity type
401 * @publicId: The public ID of the entity
402 * @systemId: The system ID of the entity
403 * @content: the entity value (without processing).
404 *
405 * An entity definition has been parsed
406 */
407void
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000408entityDecl(void *ctx, const xmlChar *name, int type,
409 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
Daniel Veillard517752b1999-04-05 12:20:10 +0000410{
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000411 xmlEntityPtr ent;
Daniel Veillard27d88741999-05-29 11:51:49 +0000412 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000413
414#ifdef DEBUG_SAX
415 fprintf(stderr, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
416 name, type, publicId, systemId, content);
417#endif
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000418 if (ctxt->inSubset == 1) {
419 ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
Daniel Veillardcf461992000-03-14 18:30:20 +0000420 systemId, content);
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000421 if ((ent == NULL) && (ctxt->pedantic) &&
422 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
423 ctxt->sax->warning(ctxt,
424 "Entity(%s) already defined in the internal subset\n", name);
Daniel Veillard39c7d712000-09-10 16:14:55 +0000425 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
Daniel Veillard04698d92000-09-17 16:00:22 +0000426 xmlChar *URI;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000427 const char *base = NULL;
428
429 if (ctxt->input != NULL)
430 base = ctxt->input->filename;
431 if (base == NULL)
432 base = ctxt->directory;
433
Daniel Veillard04698d92000-09-17 16:00:22 +0000434 URI = xmlBuildURI(systemId, (const xmlChar *) base);
Daniel Veillard39c7d712000-09-10 16:14:55 +0000435 ent->URI = URI;
436 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000437 } else if (ctxt->inSubset == 2) {
438 ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
Daniel Veillardcf461992000-03-14 18:30:20 +0000439 systemId, content);
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000440 if ((ent == NULL) && (ctxt->pedantic) &&
441 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
442 ctxt->sax->warning(ctxt,
443 "Entity(%s) already defined in the external subset\n", name);
Daniel Veillard39c7d712000-09-10 16:14:55 +0000444 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
Daniel Veillard04698d92000-09-17 16:00:22 +0000445 xmlChar *URI;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000446 const char *base = NULL;
447
448 if (ctxt->input != NULL)
449 base = ctxt->input->filename;
450 if (base == NULL)
451 base = ctxt->directory;
452
Daniel Veillard04698d92000-09-17 16:00:22 +0000453 URI = xmlBuildURI(systemId, (const xmlChar *) base);
Daniel Veillard39c7d712000-09-10 16:14:55 +0000454 ent->URI = URI;
455 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000456 } else {
Daniel Veillardcf461992000-03-14 18:30:20 +0000457 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
458 ctxt->sax->error(ctxt,
459 "SAX.entityDecl(%s) called while not in subset\n", name);
460 }
Daniel Veillard517752b1999-04-05 12:20:10 +0000461}
462
463/**
464 * attributeDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000465 * @ctx: the user data (XML parser context)
Daniel Veillard06047432000-04-24 11:33:38 +0000466 * @elem: the name of the element
Daniel Veillardcf461992000-03-14 18:30:20 +0000467 * @fullname: the attribute name
Daniel Veillard517752b1999-04-05 12:20:10 +0000468 * @type: the attribute type
Daniel Veillard06047432000-04-24 11:33:38 +0000469 * @def: the type of default value
470 * @defaultValue: the attribute default value
471 * @tree: the tree of enumerated value set
Daniel Veillard517752b1999-04-05 12:20:10 +0000472 *
473 * An attribute definition has been parsed
474 */
475void
Daniel Veillardcf461992000-03-14 18:30:20 +0000476attributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000477 int type, int def, const xmlChar *defaultValue,
Daniel Veillard517752b1999-04-05 12:20:10 +0000478 xmlEnumerationPtr tree)
479{
Daniel Veillard27d88741999-05-29 11:51:49 +0000480 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000481 xmlAttributePtr attr;
Daniel Veillardcf461992000-03-14 18:30:20 +0000482 xmlChar *name = NULL, *prefix = NULL;
Daniel Veillard517752b1999-04-05 12:20:10 +0000483
484#ifdef DEBUG_SAX
485 fprintf(stderr, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000486 elem, fullname, type, def, defaultValue);
Daniel Veillard517752b1999-04-05 12:20:10 +0000487#endif
Daniel Veillardcf461992000-03-14 18:30:20 +0000488 name = xmlSplitQName(ctxt, fullname, &prefix);
489 if (ctxt->inSubset == 1)
490 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
Daniel Veillard32bc74e2000-07-14 14:49:25 +0000491 name, prefix, (xmlAttributeType) type,
492 (xmlAttributeDefault) def, defaultValue, tree);
Daniel Veillardcf461992000-03-14 18:30:20 +0000493 else if (ctxt->inSubset == 2)
494 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
Daniel Veillard32bc74e2000-07-14 14:49:25 +0000495 name, prefix, (xmlAttributeType) type,
496 (xmlAttributeDefault) def, defaultValue, tree);
Daniel Veillardcf461992000-03-14 18:30:20 +0000497 else {
498 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
499 ctxt->sax->error(ctxt,
500 "SAX.attributeDecl(%s) called while not in subset\n", name);
501 return;
502 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000503 if (attr == 0) ctxt->valid = 0;
504 if (ctxt->validate && ctxt->wellFormed &&
505 ctxt->myDoc && ctxt->myDoc->intSubset)
506 ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
507 attr);
Daniel Veillardcf461992000-03-14 18:30:20 +0000508 if (prefix != NULL)
509 xmlFree(prefix);
510 if (name != NULL)
511 xmlFree(name);
Daniel Veillard517752b1999-04-05 12:20:10 +0000512}
513
514/**
515 * elementDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000516 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000517 * @name: the element name
518 * @type: the element type
Daniel Veillard06047432000-04-24 11:33:38 +0000519 * @content: the element value tree
Daniel Veillard517752b1999-04-05 12:20:10 +0000520 *
521 * An element definition has been parsed
522 */
523void
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000524elementDecl(void *ctx, const xmlChar *name, int type,
Daniel Veillard517752b1999-04-05 12:20:10 +0000525 xmlElementContentPtr content)
526{
Daniel Veillard27d88741999-05-29 11:51:49 +0000527 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillardcf461992000-03-14 18:30:20 +0000528 xmlElementPtr elem = NULL;
Daniel Veillard517752b1999-04-05 12:20:10 +0000529
530#ifdef DEBUG_SAX
531 fprintf(stderr, "SAX.elementDecl(%s, %d, ...)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000532 fullname, type);
Daniel Veillard517752b1999-04-05 12:20:10 +0000533#endif
Daniel Veillardb05deb71999-08-10 19:04:08 +0000534
Daniel Veillardcf461992000-03-14 18:30:20 +0000535 if (ctxt->inSubset == 1)
536 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
Daniel Veillard32bc74e2000-07-14 14:49:25 +0000537 name, (xmlElementTypeVal) type, content);
Daniel Veillardcf461992000-03-14 18:30:20 +0000538 else if (ctxt->inSubset == 2)
539 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
Daniel Veillard32bc74e2000-07-14 14:49:25 +0000540 name, (xmlElementTypeVal) type, content);
Daniel Veillardcf461992000-03-14 18:30:20 +0000541 else {
542 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
543 ctxt->sax->error(ctxt,
544 "SAX.elementDecl(%s) called while not in subset\n", name);
545 return;
546 }
547 if (elem == NULL) ctxt->valid = 0;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000548 if (ctxt->validate && ctxt->wellFormed &&
549 ctxt->myDoc && ctxt->myDoc->intSubset)
550 ctxt->valid &= xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
Daniel Veillard517752b1999-04-05 12:20:10 +0000551}
552
553/**
Daniel Veillard97b58771998-10-20 06:14:16 +0000554 * notationDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000555 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000556 * @name: The name of the notation
557 * @publicId: The public ID of the entity
558 * @systemId: The system ID of the entity
559 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000560 * What to do when a notation declaration has been parsed.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000561 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000562void
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000563notationDecl(void *ctx, const xmlChar *name,
564 const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard97b58771998-10-20 06:14:16 +0000565{
Daniel Veillard27d88741999-05-29 11:51:49 +0000566 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillardcf461992000-03-14 18:30:20 +0000567 xmlNotationPtr nota = NULL;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000568
Daniel Veillard260a68f1998-08-13 03:39:55 +0000569#ifdef DEBUG_SAX
570 fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
571#endif
Daniel Veillardb05deb71999-08-10 19:04:08 +0000572
Daniel Veillardcf461992000-03-14 18:30:20 +0000573 if (ctxt->inSubset == 1)
574 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000575 publicId, systemId);
Daniel Veillardcf461992000-03-14 18:30:20 +0000576 else if (ctxt->inSubset == 2)
577 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
578 publicId, systemId);
579 else {
580 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
581 ctxt->sax->error(ctxt,
582 "SAX.notationDecl(%s) called while not in subset\n", name);
583 return;
584 }
585 if (nota == NULL) ctxt->valid = 0;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000586 if (ctxt->validate && ctxt->wellFormed &&
587 ctxt->myDoc && ctxt->myDoc->intSubset)
588 ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
589 nota);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000590}
591
Daniel Veillard97b58771998-10-20 06:14:16 +0000592/**
593 * unparsedEntityDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000594 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000595 * @name: The name of the entity
596 * @publicId: The public ID of the entity
597 * @systemId: The system ID of the entity
598 * @notationName: the name of the notation
599 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000600 * What to do when an unparsed entity declaration is parsed
Daniel Veillard260a68f1998-08-13 03:39:55 +0000601 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000602void
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000603unparsedEntityDecl(void *ctx, const xmlChar *name,
604 const xmlChar *publicId, const xmlChar *systemId,
605 const xmlChar *notationName)
Daniel Veillard97b58771998-10-20 06:14:16 +0000606{
Daniel Veillardb96e6431999-08-29 21:02:19 +0000607 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000608#ifdef DEBUG_SAX
609 fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
610 name, publicId, systemId, notationName);
611#endif
Daniel Veillardb96e6431999-08-29 21:02:19 +0000612 if (ctxt->validate && ctxt->wellFormed &&
613 ctxt->myDoc && ctxt->myDoc->intSubset)
614 ctxt->valid &= xmlValidateNotationUse(&ctxt->vctxt, ctxt->myDoc,
615 notationName);
616 xmlAddDocEntity(ctxt->myDoc, name,
617 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
618 publicId, systemId, notationName);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000619}
620
Daniel Veillard97b58771998-10-20 06:14:16 +0000621/**
622 * setDocumentLocator:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000623 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000624 * @loc: A SAX Locator
625 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000626 * Receive the document locator at startup, actually xmlDefaultSAXLocator
627 * Everything is available on the context, so this is useless in our case.
628 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000629void
Daniel Veillard27d88741999-05-29 11:51:49 +0000630setDocumentLocator(void *ctx, xmlSAXLocatorPtr loc)
Daniel Veillard97b58771998-10-20 06:14:16 +0000631{
Daniel Veillard27d88741999-05-29 11:51:49 +0000632 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillard260a68f1998-08-13 03:39:55 +0000633#ifdef DEBUG_SAX
634 fprintf(stderr, "SAX.setDocumentLocator()\n");
635#endif
636}
637
Daniel Veillard97b58771998-10-20 06:14:16 +0000638/**
639 * startDocument:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000640 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000641 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000642 * called when the document start being processed.
643 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000644void
Daniel Veillard27d88741999-05-29 11:51:49 +0000645startDocument(void *ctx)
Daniel Veillard97b58771998-10-20 06:14:16 +0000646{
Daniel Veillard27d88741999-05-29 11:51:49 +0000647 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000648 xmlDocPtr doc;
649
Daniel Veillard260a68f1998-08-13 03:39:55 +0000650#ifdef DEBUG_SAX
651 fprintf(stderr, "SAX.startDocument()\n");
652#endif
Daniel Veillard3f6f7f62000-06-30 17:58:25 +0000653 if (ctxt->html) {
654 if (ctxt->myDoc == NULL)
Daniel Veillard87b95392000-08-12 21:12:04 +0000655#ifdef LIBXML_HTML_ENABLED
Daniel Veillardb8f25c92000-08-19 19:52:36 +0000656 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
Daniel Veillard87b95392000-08-12 21:12:04 +0000657#else
658 fprintf(stderr, "libxml2 built without HTML support\n");
659#endif
Daniel Veillard3f6f7f62000-06-30 17:58:25 +0000660 } else {
661 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
662 if (doc != NULL) {
663 if (ctxt->encoding != NULL)
664 doc->encoding = xmlStrdup(ctxt->encoding);
665 else
666 doc->encoding = NULL;
667 doc->standalone = ctxt->standalone;
668 }
Daniel Veillard517752b1999-04-05 12:20:10 +0000669 }
Daniel Veillard87b95392000-08-12 21:12:04 +0000670 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
671 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
672 ctxt->myDoc->URL = xmlStrdup((xmlChar *) ctxt->input->filename);
673 }
Daniel Veillard260a68f1998-08-13 03:39:55 +0000674}
675
Daniel Veillard97b58771998-10-20 06:14:16 +0000676/**
677 * endDocument:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000678 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000679 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000680 * called when the document end has been detected.
681 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000682void
Daniel Veillard27d88741999-05-29 11:51:49 +0000683endDocument(void *ctx)
Daniel Veillard97b58771998-10-20 06:14:16 +0000684{
Daniel Veillardc08a2c61999-09-08 21:35:25 +0000685 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000686#ifdef DEBUG_SAX
687 fprintf(stderr, "SAX.endDocument()\n");
688#endif
Daniel Veillardc08a2c61999-09-08 21:35:25 +0000689 if (ctxt->validate && ctxt->wellFormed &&
690 ctxt->myDoc && ctxt->myDoc->intSubset)
691 ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
Daniel Veillard496a1cf2000-05-03 14:20:55 +0000692
693 /*
694 * Grab the encoding if it was added on-the-fly
695 */
696 if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
697 (ctxt->myDoc->encoding == NULL)) {
698 ctxt->myDoc->encoding = ctxt->encoding;
699 ctxt->encoding = NULL;
700 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000701 if ((ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
702 (ctxt->myDoc->encoding == NULL)) {
703 ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
704 }
705 if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
706 (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
707 ctxt->myDoc->charset = ctxt->charset;
708 }
Daniel Veillard260a68f1998-08-13 03:39:55 +0000709}
710
Daniel Veillard97b58771998-10-20 06:14:16 +0000711/**
Daniel Veillard517752b1999-04-05 12:20:10 +0000712 * attribute:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000713 * @ctx: the user data (XML parser context)
Daniel Veillard06047432000-04-24 11:33:38 +0000714 * @fullname: The attribute name, including namespace prefix
Daniel Veillard517752b1999-04-05 12:20:10 +0000715 * @value: The attribute value
716 *
717 * Handle an attribute that has been read by the parser.
718 * The default handling is to convert the attribute into an
719 * DOM subtree and past it in a new xmlAttr element added to
720 * the element.
721 */
722void
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000723attribute(void *ctx, const xmlChar *fullname, const xmlChar *value)
Daniel Veillard517752b1999-04-05 12:20:10 +0000724{
Daniel Veillard27d88741999-05-29 11:51:49 +0000725 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000726 xmlAttrPtr ret;
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000727 xmlChar *name;
728 xmlChar *ns;
Daniel Veillardcf461992000-03-14 18:30:20 +0000729 xmlChar *nval;
Daniel Veillardb96e6431999-08-29 21:02:19 +0000730 xmlNsPtr namespace;
Daniel Veillard517752b1999-04-05 12:20:10 +0000731
732/****************
733#ifdef DEBUG_SAX
734 fprintf(stderr, "SAX.attribute(%s, %s)\n", fullname, value);
735#endif
736 ****************/
737 /*
738 * Split the full name into a namespace prefix and the tag name
739 */
Daniel Veillardcf461992000-03-14 18:30:20 +0000740 name = xmlSplitQName(ctxt, fullname, &ns);
741
742 /*
743 * Do the last stave of the attribute normalization
744 */
Daniel Veillardbe803962000-06-28 23:40:59 +0000745 if (ctxt->html)
746 nval = NULL;
747 else
748 nval = xmlValidNormalizeAttributeValue(ctxt->myDoc,
Daniel Veillardcf461992000-03-14 18:30:20 +0000749 ctxt->node, fullname, value);
750 if (nval != NULL)
751 value = nval;
Daniel Veillard517752b1999-04-05 12:20:10 +0000752
753 /*
754 * Check whether it's a namespace definition
755 */
Daniel Veillardbe803962000-06-28 23:40:59 +0000756 if ((!ctxt->html) && (ns == NULL) &&
Daniel Veillard517752b1999-04-05 12:20:10 +0000757 (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
758 (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
Daniel Veillardbe803962000-06-28 23:40:59 +0000759 xmlURIPtr uri;
760
761 uri = xmlParseURI((const char *)value);
762 if (uri == NULL) {
763 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
764 ctxt->sax->warning(ctxt->userData,
765 "nmlns: %s not a valid URI\n", value);
766 } else {
767 if (uri->scheme == NULL) {
768 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
769 ctxt->sax->warning(ctxt->userData,
770 "nmlns: URI %s is not absolute\n", value);
771 }
772 xmlFreeURI(uri);
773 }
774
Daniel Veillard517752b1999-04-05 12:20:10 +0000775 /* a default namespace definition */
776 xmlNewNs(ctxt->node, value, NULL);
777 if (name != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +0000778 xmlFree(name);
Daniel Veillardcf461992000-03-14 18:30:20 +0000779 if (nval != NULL)
780 xmlFree(nval);
Daniel Veillard517752b1999-04-05 12:20:10 +0000781 return;
782 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000783 if ((!ctxt->html) &&
784 (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
Daniel Veillard517752b1999-04-05 12:20:10 +0000785 (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
Daniel Veillardcf461992000-03-14 18:30:20 +0000786 /*
787 * Validate also for namespace decls, they are attributes from
788 * an XML-1.0 perspective
789 TODO ... doesn't map well with current API
790 if (ctxt->validate && ctxt->wellFormed &&
791 ctxt->myDoc && ctxt->myDoc->intSubset)
792 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
793 ctxt->node, ret, value);
794 */
Daniel Veillard517752b1999-04-05 12:20:10 +0000795 /* a standard namespace definition */
796 xmlNewNs(ctxt->node, value, name);
Daniel Veillard6454aec1999-09-02 22:04:43 +0000797 xmlFree(ns);
Daniel Veillard517752b1999-04-05 12:20:10 +0000798 if (name != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +0000799 xmlFree(name);
Daniel Veillardcf461992000-03-14 18:30:20 +0000800 if (nval != NULL)
801 xmlFree(nval);
Daniel Veillard517752b1999-04-05 12:20:10 +0000802 return;
803 }
804
Daniel Veillard5cb5ab81999-12-21 15:35:29 +0000805 if (ns != NULL)
806 namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
807 else {
808 namespace = NULL;
809 }
810
Daniel Veillardb96e6431999-08-29 21:02:19 +0000811 /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
812 ret = xmlNewNsProp(ctxt->node, namespace, name, NULL);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000813
Daniel Veillardb96e6431999-08-29 21:02:19 +0000814 if (ret != NULL) {
Daniel Veillardcf461992000-03-14 18:30:20 +0000815 if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
816 xmlNodePtr tmp;
817
818 ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
819 tmp = ret->children;
820 while (tmp != NULL) {
821 tmp->parent = (xmlNodePtr) ret;
822 if (tmp->next == NULL)
823 ret->last = tmp;
824 tmp = tmp->next;
825 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000826 } else if (value != NULL) {
Daniel Veillardcf461992000-03-14 18:30:20 +0000827 ret->children = xmlNewDocText(ctxt->myDoc, value);
828 ret->last = ret->children;
829 if (ret->children != NULL)
830 ret->children->parent = (xmlNodePtr) ret;
831 }
Daniel Veillardb96e6431999-08-29 21:02:19 +0000832 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000833
Daniel Veillardbe803962000-06-28 23:40:59 +0000834 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
Daniel Veillardcf461992000-03-14 18:30:20 +0000835 ctxt->myDoc && ctxt->myDoc->intSubset) {
836
837 /*
838 * If we don't substitute entities, the validation should be
839 * done on a value with replaced entities anyway.
840 */
841 if (!ctxt->replaceEntities) {
842 xmlChar *val;
843
844 ctxt->depth++;
845 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
846 0,0,0);
847 ctxt->depth--;
848 if (val == NULL)
849 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
850 ctxt->myDoc, ctxt->node, ret, value);
851 else {
852 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
853 ctxt->myDoc, ctxt->node, ret, val);
854 xmlFree(val);
855 }
856 } else {
857 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000858 ctxt->node, ret, value);
Daniel Veillardcf461992000-03-14 18:30:20 +0000859 }
860 } else {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000861 /*
862 * when validating, the ID registration is done at the attribute
863 * validation level. Otherwise we have to do specific handling here.
864 */
865 if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
866 xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
Daniel Veillardc08a2c61999-09-08 21:35:25 +0000867 else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
868 xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000869 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000870
Daniel Veillardcf461992000-03-14 18:30:20 +0000871 if (nval != NULL)
872 xmlFree(nval);
Daniel Veillard517752b1999-04-05 12:20:10 +0000873 if (name != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +0000874 xmlFree(name);
Daniel Veillard517752b1999-04-05 12:20:10 +0000875 if (ns != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +0000876 xmlFree(ns);
Daniel Veillard517752b1999-04-05 12:20:10 +0000877}
878
879/**
Daniel Veillard97b58771998-10-20 06:14:16 +0000880 * startElement:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000881 * @ctx: the user data (XML parser context)
Daniel Veillard06047432000-04-24 11:33:38 +0000882 * @fullname: The element name, including namespace prefix
Daniel Veillard517752b1999-04-05 12:20:10 +0000883 * @atts: An array of name/value attributes pairs, NULL terminated
Daniel Veillard97b58771998-10-20 06:14:16 +0000884 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000885 * called when an opening tag has been processed.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000886 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000887void
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000888startElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
Daniel Veillard97b58771998-10-20 06:14:16 +0000889{
Daniel Veillard27d88741999-05-29 11:51:49 +0000890 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000891 xmlNodePtr ret;
892 xmlNodePtr parent = ctxt->node;
893 xmlNsPtr ns;
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000894 xmlChar *name;
895 xmlChar *prefix;
896 const xmlChar *att;
897 const xmlChar *value;
Daniel Veillard517752b1999-04-05 12:20:10 +0000898 int i;
899
Daniel Veillard260a68f1998-08-13 03:39:55 +0000900#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +0000901 fprintf(stderr, "SAX.startElement(%s)\n", fullname);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000902#endif
Daniel Veillard7f7d1111999-09-22 09:46:25 +0000903
904 /*
905 * First check on validity:
906 */
907 if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
908 ((ctxt->myDoc->intSubset == NULL) ||
909 ((ctxt->myDoc->intSubset->notations == NULL) &&
910 (ctxt->myDoc->intSubset->elements == NULL) &&
911 (ctxt->myDoc->intSubset->attributes == NULL) &&
912 (ctxt->myDoc->intSubset->entities == NULL)))) {
913 if (ctxt->vctxt.error != NULL) {
914 ctxt->vctxt.error(ctxt->vctxt.userData,
915 "Validation failed: no DTD found !\n");
916 }
917 ctxt->validate = 0;
918 }
919
920
Daniel Veillard517752b1999-04-05 12:20:10 +0000921 /*
922 * Split the full name into a namespace prefix and the tag name
923 */
Daniel Veillardcf461992000-03-14 18:30:20 +0000924 name = xmlSplitQName(ctxt, fullname, &prefix);
Daniel Veillard517752b1999-04-05 12:20:10 +0000925
926
927 /*
928 * Note : the namespace resolution is deferred until the end of the
929 * attributes parsing, since local namespace can be defined as
930 * an attribute at this level.
931 */
932 ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
933 if (ret == NULL) return;
Daniel Veillardcf461992000-03-14 18:30:20 +0000934 if (ctxt->myDoc->children == NULL) {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000935#ifdef DEBUG_SAX_TREE
936 fprintf(stderr, "Setting %s as root\n", name);
937#endif
Daniel Veillardcf461992000-03-14 18:30:20 +0000938 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000939 } else if (parent == NULL) {
Daniel Veillardcf461992000-03-14 18:30:20 +0000940 parent = ctxt->myDoc->children;
Daniel Veillardb96e6431999-08-29 21:02:19 +0000941 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000942 ctxt->nodemem = -1;
Daniel Veillard517752b1999-04-05 12:20:10 +0000943
944 /*
945 * We are parsing a new node.
946 */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000947#ifdef DEBUG_SAX_TREE
948 fprintf(stderr, "pushing(%s)\n", name);
949#endif
Daniel Veillard517752b1999-04-05 12:20:10 +0000950 nodePush(ctxt, ret);
951
952 /*
953 * Link the child element
954 */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000955 if (parent != NULL) {
956 if (parent->type == XML_ELEMENT_NODE) {
957#ifdef DEBUG_SAX_TREE
958 fprintf(stderr, "adding child %s to %s\n", name, parent->name);
959#endif
960 xmlAddChild(parent, ret);
961 } else {
962#ifdef DEBUG_SAX_TREE
963 fprintf(stderr, "adding sibling %s to ", name);
964 xmlDebugDumpOneNode(stderr, parent, 0);
965#endif
966 xmlAddSibling(parent, ret);
967 }
968 }
Daniel Veillard517752b1999-04-05 12:20:10 +0000969
970 /*
Daniel Veillardb96e6431999-08-29 21:02:19 +0000971 * process all the attributes whose name start with "xml"
Daniel Veillard517752b1999-04-05 12:20:10 +0000972 */
973 if (atts != NULL) {
974 i = 0;
975 att = atts[i++];
976 value = atts[i++];
Daniel Veillardbe803962000-06-28 23:40:59 +0000977 if (!ctxt->html) {
978 while ((att != NULL) && (value != NULL)) {
979 if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l'))
980 attribute(ctxt, att, value);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000981
Daniel Veillardbe803962000-06-28 23:40:59 +0000982 att = atts[i++];
983 value = atts[i++];
984 }
Daniel Veillard517752b1999-04-05 12:20:10 +0000985 }
986 }
987
988 /*
989 * Search the namespace, note that since the attributes have been
990 * processed, the local namespaces are available.
991 */
992 ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
993 if ((ns == NULL) && (parent != NULL))
994 ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
Daniel Veillarde0854c32000-08-27 21:12:29 +0000995 if ((prefix != NULL) && (ns == NULL)) {
996 ns = xmlNewNs(ret, NULL, prefix);
997 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
998 ctxt->sax->warning(ctxt->userData,
999 "Namespace prefix %s is not defined\n", prefix);
1000 }
Daniel Veillard517752b1999-04-05 12:20:10 +00001001 xmlSetNs(ret, ns);
1002
Daniel Veillardbe803962000-06-28 23:40:59 +00001003 /*
1004 * process all the other attributes
1005 */
1006 if (atts != NULL) {
1007 i = 0;
1008 att = atts[i++];
1009 value = atts[i++];
1010 if (ctxt->html) {
1011 while (att != NULL) {
1012 attribute(ctxt, att, value);
1013 att = atts[i++];
1014 value = atts[i++];
1015 }
1016 } else {
1017 while ((att != NULL) && (value != NULL)) {
1018 if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l'))
1019 attribute(ctxt, att, value);
1020
1021 /*
1022 * Next ones
1023 */
1024 att = atts[i++];
1025 value = atts[i++];
1026 }
1027 }
1028 }
1029
1030 /*
1031 * If it's the Document root, finish the Dtd validation and
1032 * check the document root element for validity
1033 */
1034 if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) {
1035 ctxt->valid &= xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
1036 ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
1037 ctxt->vctxt.finishDtd = 1;
1038 }
1039
Daniel Veillard517752b1999-04-05 12:20:10 +00001040 if (prefix != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +00001041 xmlFree(prefix);
Daniel Veillard517752b1999-04-05 12:20:10 +00001042 if (name != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +00001043 xmlFree(name);
Daniel Veillard517752b1999-04-05 12:20:10 +00001044
Daniel Veillard260a68f1998-08-13 03:39:55 +00001045}
1046
Daniel Veillard97b58771998-10-20 06:14:16 +00001047/**
1048 * endElement:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001049 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +00001050 * @name: The element name
1051 *
Daniel Veillard260a68f1998-08-13 03:39:55 +00001052 * called when the end of an element has been detected.
1053 */
Daniel Veillard97b58771998-10-20 06:14:16 +00001054void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001055endElement(void *ctx, const xmlChar *name)
Daniel Veillard97b58771998-10-20 06:14:16 +00001056{
Daniel Veillard27d88741999-05-29 11:51:49 +00001057 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001058 xmlParserNodeInfo node_info;
1059 xmlNodePtr cur = ctxt->node;
1060
Daniel Veillard260a68f1998-08-13 03:39:55 +00001061#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +00001062 if (name == NULL)
1063 fprintf(stderr, "SAX.endElement(NULL)\n");
1064 else
1065 fprintf(stderr, "SAX.endElement(%s)\n", name);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001066#endif
Daniel Veillard517752b1999-04-05 12:20:10 +00001067
1068 /* Capture end position and add node */
1069 if (cur != NULL && ctxt->record_info) {
1070 node_info.end_pos = ctxt->input->cur - ctxt->input->base;
1071 node_info.end_line = ctxt->input->line;
1072 node_info.node = cur;
1073 xmlParserAddNodeInfo(ctxt, &node_info);
1074 }
Daniel Veillardbe803962000-06-28 23:40:59 +00001075 ctxt->nodemem = -1;
Daniel Veillard517752b1999-04-05 12:20:10 +00001076
Daniel Veillardb05deb71999-08-10 19:04:08 +00001077 if (ctxt->validate && ctxt->wellFormed &&
1078 ctxt->myDoc && ctxt->myDoc->intSubset)
1079 ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
1080 cur);
1081
1082
Daniel Veillard517752b1999-04-05 12:20:10 +00001083 /*
1084 * end of parsing of this node.
1085 */
Daniel Veillardb96e6431999-08-29 21:02:19 +00001086#ifdef DEBUG_SAX_TREE
1087 fprintf(stderr, "popping(%s)\n", cur->name);
1088#endif
Daniel Veillard517752b1999-04-05 12:20:10 +00001089 nodePop(ctxt);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001090}
1091
Daniel Veillard97b58771998-10-20 06:14:16 +00001092/**
Daniel Veillard517752b1999-04-05 12:20:10 +00001093 * reference:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001094 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001095 * @name: The entity name
Daniel Veillard11e00581998-10-24 18:27:49 +00001096 *
Daniel Veillard517752b1999-04-05 12:20:10 +00001097 * called when an entity reference is detected.
Daniel Veillard11e00581998-10-24 18:27:49 +00001098 */
1099void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001100reference(void *ctx, const xmlChar *name)
Daniel Veillard11e00581998-10-24 18:27:49 +00001101{
Daniel Veillard27d88741999-05-29 11:51:49 +00001102 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001103 xmlNodePtr ret;
1104
Daniel Veillard11e00581998-10-24 18:27:49 +00001105#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +00001106 fprintf(stderr, "SAX.reference(%s)\n", name);
Daniel Veillard11e00581998-10-24 18:27:49 +00001107#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001108 if (name[0] == '#')
1109 ret = xmlNewCharRef(ctxt->myDoc, name);
1110 else
1111 ret = xmlNewReference(ctxt->myDoc, name);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001112#ifdef DEBUG_SAX_TREE
1113 fprintf(stderr, "add reference %s to %s \n", name, ctxt->node->name);
1114#endif
Daniel Veillard517752b1999-04-05 12:20:10 +00001115 xmlAddChild(ctxt->node, ret);
Daniel Veillard11e00581998-10-24 18:27:49 +00001116}
1117
1118/**
Daniel Veillard97b58771998-10-20 06:14:16 +00001119 * characters:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001120 * @ctx: the user data (XML parser context)
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001121 * @ch: a xmlChar string
1122 * @len: the number of xmlChar
Daniel Veillard97b58771998-10-20 06:14:16 +00001123 *
Daniel Veillard260a68f1998-08-13 03:39:55 +00001124 * receiving some chars from the parser.
1125 * Question: how much at a time ???
1126 */
Daniel Veillard97b58771998-10-20 06:14:16 +00001127void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001128characters(void *ctx, const xmlChar *ch, int len)
Daniel Veillard97b58771998-10-20 06:14:16 +00001129{
Daniel Veillard27d88741999-05-29 11:51:49 +00001130 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001131 xmlNodePtr lastChild;
1132
1133#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +00001134 fprintf(stderr, "SAX.characters(%.30s, %d)\n", ch, len);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001135#endif
1136 /*
1137 * Handle the data if any. If there is no child
1138 * add it as content, otherwise if the last child is text,
1139 * concatenate it, else create a new node of type text.
1140 */
1141
Daniel Veillard35008381999-10-25 13:15:52 +00001142 if (ctxt->node == NULL) {
1143#ifdef DEBUG_SAX_TREE
1144 fprintf(stderr, "add chars: ctxt->node == NULL !\n");
1145#endif
1146 return;
1147 }
Daniel Veillard260a68f1998-08-13 03:39:55 +00001148 lastChild = xmlGetLastChild(ctxt->node);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001149#ifdef DEBUG_SAX_TREE
1150 fprintf(stderr, "add chars to %s \n", ctxt->node->name);
1151#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00001152
1153 /*
1154 * Here we needed an accelerator mechanism in case of very large
1155 * elements. Use an attribute in the structure !!!
1156 */
1157 if (lastChild == NULL) {
1158 /* first node, first time */
Daniel Veillard517752b1999-04-05 12:20:10 +00001159 xmlNodeAddContentLen(ctxt->node, ch, len);
Daniel Veillardbe803962000-06-28 23:40:59 +00001160#ifndef XML_USE_BUFFER_CONTENT
1161 if (ctxt->node->children != NULL) {
1162 ctxt->nodelen = len;
1163 ctxt->nodemem = len + 1;
1164 }
1165#endif
1166 } else {
Daniel Veillarde0854c32000-08-27 21:12:29 +00001167 if ((xmlNodeIsText(lastChild)) && (ctxt->nodemem != 0)) {
Daniel Veillardbe803962000-06-28 23:40:59 +00001168#ifndef XML_USE_BUFFER_CONTENT
1169 /*
1170 * The whole point of maintaining nodelen and nodemem,
1171 * xmlTextConcat is too costly, i.e. compute lenght,
1172 * reallocate a new buffer, move data, append ch. Here
1173 * We try to minimaze realloc() uses and avoid copying
1174 * and recomputing lenght over and over.
1175 */
1176 if (ctxt->nodelen + len >= ctxt->nodemem) {
1177 xmlChar *newbuf;
1178 int size;
1179
1180 size = ctxt->nodemem + len;
1181 size *= 2;
1182 newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
1183 if (newbuf == NULL) {
1184 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1185 ctxt->sax->error(ctxt->userData,
1186 "SAX.characters(): out of memory\n");
1187 return;
1188 }
1189 ctxt->nodemem = size;
1190 lastChild->content = newbuf;
1191 }
1192 memcpy(&lastChild->content[ctxt->nodelen], ch, len);
1193 ctxt->nodelen += len;
1194 lastChild->content[ctxt->nodelen] = 0;
1195#else
Daniel Veillard517752b1999-04-05 12:20:10 +00001196 xmlTextConcat(lastChild, ch, len);
Daniel Veillardbe803962000-06-28 23:40:59 +00001197#endif
1198 } else {
1199 /* Mixed content, first time */
Daniel Veillard517752b1999-04-05 12:20:10 +00001200 lastChild = xmlNewTextLen(ch, len);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001201 xmlAddChild(ctxt->node, lastChild);
Daniel Veillardbe803962000-06-28 23:40:59 +00001202#ifndef XML_USE_BUFFER_CONTENT
1203 if (ctxt->node->children != NULL) {
1204 ctxt->nodelen = len;
1205 ctxt->nodemem = len + 1;
1206 }
1207#endif
Daniel Veillard260a68f1998-08-13 03:39:55 +00001208 }
1209 }
1210}
1211
Daniel Veillard97b58771998-10-20 06:14:16 +00001212/**
1213 * ignorableWhitespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001214 * @ctx: the user data (XML parser context)
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001215 * @ch: a xmlChar string
1216 * @len: the number of xmlChar
Daniel Veillard97b58771998-10-20 06:14:16 +00001217 *
Daniel Veillard260a68f1998-08-13 03:39:55 +00001218 * receiving some ignorable whitespaces from the parser.
1219 * Question: how much at a time ???
1220 */
Daniel Veillard97b58771998-10-20 06:14:16 +00001221void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001222ignorableWhitespace(void *ctx, const xmlChar *ch, int len)
Daniel Veillard97b58771998-10-20 06:14:16 +00001223{
Daniel Veillard27d88741999-05-29 11:51:49 +00001224 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillard260a68f1998-08-13 03:39:55 +00001225#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +00001226 fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001227#endif
1228}
1229
Daniel Veillard97b58771998-10-20 06:14:16 +00001230/**
1231 * processingInstruction:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001232 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +00001233 * @target: the target name
1234 * @data: the PI data's
Daniel Veillard97b58771998-10-20 06:14:16 +00001235 *
1236 * A processing instruction has been parsed.
Daniel Veillard260a68f1998-08-13 03:39:55 +00001237 */
Daniel Veillard97b58771998-10-20 06:14:16 +00001238void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001239processingInstruction(void *ctx, const xmlChar *target,
1240 const xmlChar *data)
Daniel Veillard97b58771998-10-20 06:14:16 +00001241{
Daniel Veillardb96e6431999-08-29 21:02:19 +00001242 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1243 xmlNodePtr ret;
1244 xmlNodePtr parent = ctxt->node;
1245
Daniel Veillard260a68f1998-08-13 03:39:55 +00001246#ifdef DEBUG_SAX
1247 fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
1248#endif
Daniel Veillardb96e6431999-08-29 21:02:19 +00001249
1250 ret = xmlNewPI(target, data);
1251 if (ret == NULL) return;
Daniel Veillardcf461992000-03-14 18:30:20 +00001252 parent = ctxt->node;
1253
1254 if (ctxt->inSubset == 1) {
1255 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
1256 return;
1257 } else if (ctxt->inSubset == 2) {
1258 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
1259 return;
1260 }
1261 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001262#ifdef DEBUG_SAX_TREE
1263 fprintf(stderr, "Setting PI %s as root\n", target);
1264#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001265 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1266 return;
Daniel Veillardb96e6431999-08-29 21:02:19 +00001267 }
Daniel Veillardcf461992000-03-14 18:30:20 +00001268 if (parent->type == XML_ELEMENT_NODE) {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001269#ifdef DEBUG_SAX_TREE
Daniel Veillardcf461992000-03-14 18:30:20 +00001270 fprintf(stderr, "adding PI %s child to %s\n", target, parent->name);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001271#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001272 xmlAddChild(parent, ret);
1273 } else {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001274#ifdef DEBUG_SAX_TREE
Daniel Veillardcf461992000-03-14 18:30:20 +00001275 fprintf(stderr, "adding PI %s sibling to ", target);
1276 xmlDebugDumpOneNode(stderr, parent, 0);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001277#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001278 xmlAddSibling(parent, ret);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001279 }
Daniel Veillard260a68f1998-08-13 03:39:55 +00001280}
1281
Daniel Veillard517752b1999-04-05 12:20:10 +00001282/**
1283 * globalNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001284 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001285 * @href: the namespace associated URN
1286 * @prefix: the namespace prefix
1287 *
1288 * An old global namespace has been parsed.
1289 */
1290void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001291globalNamespace(void *ctx, const xmlChar *href, const xmlChar *prefix)
Daniel Veillard517752b1999-04-05 12:20:10 +00001292{
Daniel Veillard27d88741999-05-29 11:51:49 +00001293 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001294#ifdef DEBUG_SAX
1295 fprintf(stderr, "SAX.globalNamespace(%s, %s)\n", href, prefix);
1296#endif
1297 xmlNewGlobalNs(ctxt->myDoc, href, prefix);
1298}
1299
1300/**
1301 * setNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001302 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001303 * @name: the namespace prefix
1304 *
1305 * Set the current element namespace.
1306 */
Daniel Veillard06047432000-04-24 11:33:38 +00001307
Daniel Veillard517752b1999-04-05 12:20:10 +00001308void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001309setNamespace(void *ctx, const xmlChar *name)
Daniel Veillard517752b1999-04-05 12:20:10 +00001310{
Daniel Veillard27d88741999-05-29 11:51:49 +00001311 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001312 xmlNsPtr ns;
1313 xmlNodePtr parent;
1314
1315#ifdef DEBUG_SAX
1316 fprintf(stderr, "SAX.setNamespace(%s)\n", name);
1317#endif
1318 ns = xmlSearchNs(ctxt->myDoc, ctxt->node, name);
1319 if (ns == NULL) { /* ctxt->node may not have a parent yet ! */
1320 if (ctxt->nodeNr >= 2) {
1321 parent = ctxt->nodeTab[ctxt->nodeNr - 2];
1322 if (parent != NULL)
1323 ns = xmlSearchNs(ctxt->myDoc, parent, name);
1324 }
1325 }
1326 xmlSetNs(ctxt->node, ns);
1327}
1328
1329/**
1330 * getNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001331 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001332 *
1333 * Get the current element namespace.
Daniel Veillard06047432000-04-24 11:33:38 +00001334 *
1335 * Returns the xmlNsPtr or NULL if none
Daniel Veillard517752b1999-04-05 12:20:10 +00001336 */
Daniel Veillard06047432000-04-24 11:33:38 +00001337
Daniel Veillard517752b1999-04-05 12:20:10 +00001338xmlNsPtr
Daniel Veillard27d88741999-05-29 11:51:49 +00001339getNamespace(void *ctx)
Daniel Veillard517752b1999-04-05 12:20:10 +00001340{
Daniel Veillard27d88741999-05-29 11:51:49 +00001341 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001342 xmlNsPtr ret;
1343
1344#ifdef DEBUG_SAX
1345 fprintf(stderr, "SAX.getNamespace()\n");
1346#endif
1347 ret = ctxt->node->ns;
1348 return(ret);
1349}
1350
1351/**
1352 * checkNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001353 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001354 * @namespace: the namespace to check against
1355 *
1356 * Check that the current element namespace is the same as the
1357 * one read upon parsing.
Daniel Veillard06047432000-04-24 11:33:38 +00001358 *
1359 * Returns 1 if true 0 otherwise
Daniel Veillard517752b1999-04-05 12:20:10 +00001360 */
Daniel Veillard06047432000-04-24 11:33:38 +00001361
Daniel Veillard517752b1999-04-05 12:20:10 +00001362int
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001363checkNamespace(void *ctx, xmlChar *namespace)
Daniel Veillard517752b1999-04-05 12:20:10 +00001364{
Daniel Veillard27d88741999-05-29 11:51:49 +00001365 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001366 xmlNodePtr cur = ctxt->node;
1367
1368#ifdef DEBUG_SAX
1369 fprintf(stderr, "SAX.checkNamespace(%s)\n", namespace);
1370#endif
1371
1372 /*
1373 * Check that the Name in the ETag is the same as in the STag.
1374 */
1375 if (namespace == NULL) {
1376 if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
1377 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1378 ctxt->sax->error(ctxt,
1379 "End tags for %s don't hold the namespace %s\n",
1380 cur->name, cur->ns->prefix);
1381 ctxt->wellFormed = 0;
1382 }
1383 } else {
1384 if ((cur->ns == NULL) || (cur->ns->prefix == NULL)) {
1385 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1386 ctxt->sax->error(ctxt,
1387 "End tags %s holds a prefix %s not used by the open tag\n",
1388 cur->name, namespace);
1389 ctxt->wellFormed = 0;
Daniel Veillard8b5dd832000-10-01 20:28:44 +00001390 } else if (!xmlStrEqual(namespace, cur->ns->prefix)) {
Daniel Veillard517752b1999-04-05 12:20:10 +00001391 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1392 ctxt->sax->error(ctxt,
1393 "Start and End tags for %s don't use the same namespaces: %s and %s\n",
1394 cur->name, cur->ns->prefix, namespace);
1395 ctxt->wellFormed = 0;
1396 } else
1397 return(1);
1398 }
1399 return(0);
1400}
1401
1402/**
1403 * namespaceDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001404 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001405 * @href: the namespace associated URN
1406 * @prefix: the namespace prefix
1407 *
1408 * A namespace has been parsed.
1409 */
1410void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001411namespaceDecl(void *ctx, const xmlChar *href, const xmlChar *prefix)
Daniel Veillard517752b1999-04-05 12:20:10 +00001412{
Daniel Veillard27d88741999-05-29 11:51:49 +00001413 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001414#ifdef DEBUG_SAX
1415 if (prefix == NULL)
1416 fprintf(stderr, "SAX.namespaceDecl(%s, NULL)\n", href);
1417 else
1418 fprintf(stderr, "SAX.namespaceDecl(%s, %s)\n", href, prefix);
1419#endif
1420 xmlNewNs(ctxt->node, href, prefix);
1421}
1422
1423/**
1424 * comment:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001425 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001426 * @value: the comment content
1427 *
1428 * A comment has been parsed.
1429 */
1430void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001431comment(void *ctx, const xmlChar *value)
Daniel Veillard517752b1999-04-05 12:20:10 +00001432{
Daniel Veillard27d88741999-05-29 11:51:49 +00001433 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard14fff061999-06-22 21:49:07 +00001434 xmlNodePtr ret;
Daniel Veillardb96e6431999-08-29 21:02:19 +00001435 xmlNodePtr parent = ctxt->node;
Daniel Veillard14fff061999-06-22 21:49:07 +00001436
Daniel Veillard517752b1999-04-05 12:20:10 +00001437#ifdef DEBUG_SAX
1438 fprintf(stderr, "SAX.comment(%s)\n", value);
1439#endif
Daniel Veillard14fff061999-06-22 21:49:07 +00001440 ret = xmlNewDocComment(ctxt->myDoc, value);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001441 if (ret == NULL) return;
1442
Daniel Veillardcf461992000-03-14 18:30:20 +00001443 if (ctxt->inSubset == 1) {
1444 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
1445 return;
1446 } else if (ctxt->inSubset == 2) {
1447 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
1448 return;
1449 }
1450 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001451#ifdef DEBUG_SAX_TREE
1452 fprintf(stderr, "Setting comment as root\n");
1453#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001454 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1455 return;
Daniel Veillardb96e6431999-08-29 21:02:19 +00001456 }
Daniel Veillardcf461992000-03-14 18:30:20 +00001457 if (parent->type == XML_ELEMENT_NODE) {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001458#ifdef DEBUG_SAX_TREE
Daniel Veillardcf461992000-03-14 18:30:20 +00001459 fprintf(stderr, "adding comment child to %s\n", parent->name);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001460#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001461 xmlAddChild(parent, ret);
1462 } else {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001463#ifdef DEBUG_SAX_TREE
Daniel Veillardcf461992000-03-14 18:30:20 +00001464 fprintf(stderr, "adding comment sibling to ");
1465 xmlDebugDumpOneNode(stderr, parent, 0);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001466#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001467 xmlAddSibling(parent, ret);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001468 }
Daniel Veillardb05deb71999-08-10 19:04:08 +00001469}
1470
1471/**
1472 * cdataBlock:
1473 * @ctx: the user data (XML parser context)
1474 * @value: The pcdata content
1475 * @len: the block length
1476 *
1477 * called when a pcdata block has been parsed
1478 */
1479void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001480cdataBlock(void *ctx, const xmlChar *value, int len)
Daniel Veillardb05deb71999-08-10 19:04:08 +00001481{
1482 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001483 xmlNodePtr ret, lastChild;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001484
1485#ifdef DEBUG_SAX
Daniel Veillardb96e6431999-08-29 21:02:19 +00001486 fprintf(stderr, "SAX.pcdata(%.10s, %d)\n", value, len);
Daniel Veillardb05deb71999-08-10 19:04:08 +00001487#endif
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001488 lastChild = xmlGetLastChild(ctxt->node);
1489#ifdef DEBUG_SAX_TREE
1490 fprintf(stderr, "add chars to %s \n", ctxt->node->name);
1491#endif
1492 if ((lastChild != NULL) &&
1493 (lastChild->type == XML_CDATA_SECTION_NODE)) {
1494 xmlTextConcat(lastChild, value, len);
1495 } else {
1496 ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
1497 xmlAddChild(ctxt->node, ret);
1498 }
Daniel Veillard517752b1999-04-05 12:20:10 +00001499}
1500
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001501/*
1502 * Default handler for XML, builds the DOM tree
1503 */
Daniel Veillard260a68f1998-08-13 03:39:55 +00001504xmlSAXHandler xmlDefaultSAXHandler = {
Daniel Veillard517752b1999-04-05 12:20:10 +00001505 internalSubset,
1506 isStandalone,
1507 hasInternalSubset,
1508 hasExternalSubset,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001509 resolveEntity,
Daniel Veillard517752b1999-04-05 12:20:10 +00001510 getEntity,
1511 entityDecl,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001512 notationDecl,
Daniel Veillard517752b1999-04-05 12:20:10 +00001513 attributeDecl,
1514 elementDecl,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001515 unparsedEntityDecl,
1516 setDocumentLocator,
1517 startDocument,
1518 endDocument,
1519 startElement,
1520 endElement,
Daniel Veillard517752b1999-04-05 12:20:10 +00001521 reference,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001522 characters,
1523 ignorableWhitespace,
1524 processingInstruction,
Daniel Veillard517752b1999-04-05 12:20:10 +00001525 comment,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001526 xmlParserWarning,
1527 xmlParserError,
1528 xmlParserError,
Daniel Veillardb05deb71999-08-10 19:04:08 +00001529 getParameterEntity,
1530 cdataBlock,
Daniel Veillardcf461992000-03-14 18:30:20 +00001531 externalSubset,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001532};
1533
Daniel Veillard97b58771998-10-20 06:14:16 +00001534/**
1535 * xmlDefaultSAXHandlerInit:
1536 *
1537 * Initialize the default SAX handler
Daniel Veillard97b58771998-10-20 06:14:16 +00001538 */
1539void
1540xmlDefaultSAXHandlerInit(void)
1541{
Daniel Veillard517752b1999-04-05 12:20:10 +00001542 xmlDefaultSAXHandler.internalSubset = internalSubset;
Daniel Veillardcf461992000-03-14 18:30:20 +00001543 xmlDefaultSAXHandler.externalSubset = externalSubset;
Daniel Veillard517752b1999-04-05 12:20:10 +00001544 xmlDefaultSAXHandler.isStandalone = isStandalone;
1545 xmlDefaultSAXHandler.hasInternalSubset = hasInternalSubset;
1546 xmlDefaultSAXHandler.hasExternalSubset = hasExternalSubset;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001547 xmlDefaultSAXHandler.resolveEntity = resolveEntity;
Daniel Veillard517752b1999-04-05 12:20:10 +00001548 xmlDefaultSAXHandler.getEntity = getEntity;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001549 xmlDefaultSAXHandler.getParameterEntity = getParameterEntity;
Daniel Veillard517752b1999-04-05 12:20:10 +00001550 xmlDefaultSAXHandler.entityDecl = entityDecl;
1551 xmlDefaultSAXHandler.attributeDecl = attributeDecl;
1552 xmlDefaultSAXHandler.elementDecl = elementDecl;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001553 xmlDefaultSAXHandler.notationDecl = notationDecl;
1554 xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
1555 xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1556 xmlDefaultSAXHandler.startDocument = startDocument;
1557 xmlDefaultSAXHandler.endDocument = endDocument;
1558 xmlDefaultSAXHandler.startElement = startElement;
1559 xmlDefaultSAXHandler.endElement = endElement;
Daniel Veillard517752b1999-04-05 12:20:10 +00001560 xmlDefaultSAXHandler.reference = reference;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001561 xmlDefaultSAXHandler.characters = characters;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001562 xmlDefaultSAXHandler.cdataBlock = cdataBlock;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001563 xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1564 xmlDefaultSAXHandler.processingInstruction = processingInstruction;
Daniel Veillard517752b1999-04-05 12:20:10 +00001565 xmlDefaultSAXHandler.comment = comment;
Daniel Veillardcf461992000-03-14 18:30:20 +00001566 if (xmlGetWarningsDefaultValue == 0)
1567 xmlDefaultSAXHandler.warning = NULL;
1568 else
1569 xmlDefaultSAXHandler.warning = xmlParserWarning;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001570 xmlDefaultSAXHandler.error = xmlParserError;
1571 xmlDefaultSAXHandler.fatalError = xmlParserError;
1572}
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001573
1574/*
1575 * Default handler for HTML, builds the DOM tree
1576 */
1577xmlSAXHandler htmlDefaultSAXHandler = {
Daniel Veillardd83eb822000-06-30 18:39:56 +00001578 internalSubset,
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001579 NULL,
1580 NULL,
1581 NULL,
1582 NULL,
1583 getEntity,
1584 NULL,
1585 NULL,
1586 NULL,
1587 NULL,
1588 NULL,
1589 setDocumentLocator,
1590 startDocument,
1591 endDocument,
1592 startElement,
1593 endElement,
1594 NULL,
1595 characters,
1596 ignorableWhitespace,
1597 NULL,
1598 comment,
1599 xmlParserWarning,
1600 xmlParserError,
1601 xmlParserError,
Daniel Veillardb05deb71999-08-10 19:04:08 +00001602 getParameterEntity,
1603 NULL,
Daniel Veillardcf461992000-03-14 18:30:20 +00001604 NULL,
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001605};
1606
1607/**
1608 * htmlDefaultSAXHandlerInit:
1609 *
1610 * Initialize the default SAX handler
1611 */
1612void
1613htmlDefaultSAXHandlerInit(void)
1614{
Daniel Veillardd83eb822000-06-30 18:39:56 +00001615 htmlDefaultSAXHandler.internalSubset = internalSubset;
Daniel Veillardcf461992000-03-14 18:30:20 +00001616 htmlDefaultSAXHandler.externalSubset = NULL;
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001617 htmlDefaultSAXHandler.isStandalone = NULL;
1618 htmlDefaultSAXHandler.hasInternalSubset = NULL;
1619 htmlDefaultSAXHandler.hasExternalSubset = NULL;
1620 htmlDefaultSAXHandler.resolveEntity = NULL;
1621 htmlDefaultSAXHandler.getEntity = getEntity;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001622 htmlDefaultSAXHandler.getParameterEntity = NULL;
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001623 htmlDefaultSAXHandler.entityDecl = NULL;
1624 htmlDefaultSAXHandler.attributeDecl = NULL;
1625 htmlDefaultSAXHandler.elementDecl = NULL;
1626 htmlDefaultSAXHandler.notationDecl = NULL;
1627 htmlDefaultSAXHandler.unparsedEntityDecl = NULL;
1628 htmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1629 htmlDefaultSAXHandler.startDocument = startDocument;
1630 htmlDefaultSAXHandler.endDocument = endDocument;
1631 htmlDefaultSAXHandler.startElement = startElement;
1632 htmlDefaultSAXHandler.endElement = endElement;
1633 htmlDefaultSAXHandler.reference = NULL;
1634 htmlDefaultSAXHandler.characters = characters;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001635 htmlDefaultSAXHandler.cdataBlock = NULL;
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001636 htmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1637 htmlDefaultSAXHandler.processingInstruction = NULL;
1638 htmlDefaultSAXHandler.comment = comment;
1639 htmlDefaultSAXHandler.warning = xmlParserWarning;
1640 htmlDefaultSAXHandler.error = xmlParserError;
1641 htmlDefaultSAXHandler.fatalError = xmlParserError;
1642}
Daniel Veillard39c7d712000-09-10 16:14:55 +00001643
1644/*
1645 * Default handler for HTML, builds the DOM tree
1646 */
1647xmlSAXHandler sgmlDefaultSAXHandler = {
1648 internalSubset,
1649 NULL,
1650 NULL,
1651 NULL,
1652 NULL,
1653 getEntity,
1654 NULL,
1655 NULL,
1656 NULL,
1657 NULL,
1658 NULL,
1659 setDocumentLocator,
1660 startDocument,
1661 endDocument,
1662 startElement,
1663 endElement,
1664 NULL,
1665 characters,
1666 ignorableWhitespace,
1667 NULL,
1668 comment,
1669 xmlParserWarning,
1670 xmlParserError,
1671 xmlParserError,
1672 getParameterEntity,
1673 NULL,
1674 NULL,
1675};
1676
1677/**
1678 * sgmlDefaultSAXHandlerInit:
1679 *
1680 * Initialize the default SAX handler
1681 */
1682void
1683sgmlDefaultSAXHandlerInit(void)
1684{
1685 sgmlDefaultSAXHandler.internalSubset = internalSubset;
1686 sgmlDefaultSAXHandler.externalSubset = NULL;
1687 sgmlDefaultSAXHandler.isStandalone = NULL;
1688 sgmlDefaultSAXHandler.hasInternalSubset = NULL;
1689 sgmlDefaultSAXHandler.hasExternalSubset = NULL;
1690 sgmlDefaultSAXHandler.resolveEntity = NULL;
1691 sgmlDefaultSAXHandler.getEntity = getEntity;
1692 sgmlDefaultSAXHandler.getParameterEntity = NULL;
1693 sgmlDefaultSAXHandler.entityDecl = NULL;
1694 sgmlDefaultSAXHandler.attributeDecl = NULL;
1695 sgmlDefaultSAXHandler.elementDecl = NULL;
1696 sgmlDefaultSAXHandler.notationDecl = NULL;
1697 sgmlDefaultSAXHandler.unparsedEntityDecl = NULL;
1698 sgmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1699 sgmlDefaultSAXHandler.startDocument = startDocument;
1700 sgmlDefaultSAXHandler.endDocument = endDocument;
1701 sgmlDefaultSAXHandler.startElement = startElement;
1702 sgmlDefaultSAXHandler.endElement = endElement;
1703 sgmlDefaultSAXHandler.reference = NULL;
1704 sgmlDefaultSAXHandler.characters = characters;
1705 sgmlDefaultSAXHandler.cdataBlock = NULL;
1706 sgmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1707 sgmlDefaultSAXHandler.processingInstruction = NULL;
1708 sgmlDefaultSAXHandler.comment = comment;
1709 sgmlDefaultSAXHandler.warning = xmlParserWarning;
1710 sgmlDefaultSAXHandler.error = xmlParserError;
1711 sgmlDefaultSAXHandler.fatalError = xmlParserError;
1712}