blob: 7406105fb554042937ca4b957899cbc4d22647c9 [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 Veillardb71379b2000-10-09 12:30:39 +000024#include <libxml/xmlerror.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 /*
Daniel Veillard47e12f22000-10-15 14:24:25 +0000743 * Do the last stage of the attribute normalization
744 * Needed for HTML too:
745 * http://www.w3.org/TR/html4/types.html#h-6.2
Daniel Veillardcf461992000-03-14 18:30:20 +0000746 */
Daniel Veillard47e12f22000-10-15 14:24:25 +0000747 nval = xmlValidNormalizeAttributeValue(ctxt->myDoc, ctxt->node,
748 fullname, value);
Daniel Veillardcf461992000-03-14 18:30:20 +0000749 if (nval != NULL)
750 value = nval;
Daniel Veillard517752b1999-04-05 12:20:10 +0000751
752 /*
753 * Check whether it's a namespace definition
754 */
Daniel Veillardbe803962000-06-28 23:40:59 +0000755 if ((!ctxt->html) && (ns == NULL) &&
Daniel Veillard517752b1999-04-05 12:20:10 +0000756 (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
757 (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
Daniel Veillardbe803962000-06-28 23:40:59 +0000758 xmlURIPtr uri;
759
760 uri = xmlParseURI((const char *)value);
761 if (uri == NULL) {
762 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
763 ctxt->sax->warning(ctxt->userData,
764 "nmlns: %s not a valid URI\n", value);
765 } else {
766 if (uri->scheme == NULL) {
767 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
768 ctxt->sax->warning(ctxt->userData,
769 "nmlns: URI %s is not absolute\n", value);
770 }
771 xmlFreeURI(uri);
772 }
773
Daniel Veillard517752b1999-04-05 12:20:10 +0000774 /* a default namespace definition */
775 xmlNewNs(ctxt->node, value, NULL);
776 if (name != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +0000777 xmlFree(name);
Daniel Veillardcf461992000-03-14 18:30:20 +0000778 if (nval != NULL)
779 xmlFree(nval);
Daniel Veillard517752b1999-04-05 12:20:10 +0000780 return;
781 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000782 if ((!ctxt->html) &&
783 (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
Daniel Veillard517752b1999-04-05 12:20:10 +0000784 (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
Daniel Veillardcf461992000-03-14 18:30:20 +0000785 /*
786 * Validate also for namespace decls, they are attributes from
787 * an XML-1.0 perspective
788 TODO ... doesn't map well with current API
789 if (ctxt->validate && ctxt->wellFormed &&
790 ctxt->myDoc && ctxt->myDoc->intSubset)
791 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
792 ctxt->node, ret, value);
793 */
Daniel Veillard517752b1999-04-05 12:20:10 +0000794 /* a standard namespace definition */
795 xmlNewNs(ctxt->node, value, name);
Daniel Veillard6454aec1999-09-02 22:04:43 +0000796 xmlFree(ns);
Daniel Veillard517752b1999-04-05 12:20:10 +0000797 if (name != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +0000798 xmlFree(name);
Daniel Veillardcf461992000-03-14 18:30:20 +0000799 if (nval != NULL)
800 xmlFree(nval);
Daniel Veillard517752b1999-04-05 12:20:10 +0000801 return;
802 }
803
Daniel Veillard5cb5ab81999-12-21 15:35:29 +0000804 if (ns != NULL)
805 namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
806 else {
807 namespace = NULL;
808 }
809
Daniel Veillardb96e6431999-08-29 21:02:19 +0000810 /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
811 ret = xmlNewNsProp(ctxt->node, namespace, name, NULL);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000812
Daniel Veillardb96e6431999-08-29 21:02:19 +0000813 if (ret != NULL) {
Daniel Veillardcf461992000-03-14 18:30:20 +0000814 if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
815 xmlNodePtr tmp;
816
817 ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
818 tmp = ret->children;
819 while (tmp != NULL) {
820 tmp->parent = (xmlNodePtr) ret;
821 if (tmp->next == NULL)
822 ret->last = tmp;
823 tmp = tmp->next;
824 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000825 } else if (value != NULL) {
Daniel Veillardcf461992000-03-14 18:30:20 +0000826 ret->children = xmlNewDocText(ctxt->myDoc, value);
827 ret->last = ret->children;
828 if (ret->children != NULL)
829 ret->children->parent = (xmlNodePtr) ret;
830 }
Daniel Veillardb96e6431999-08-29 21:02:19 +0000831 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000832
Daniel Veillardbe803962000-06-28 23:40:59 +0000833 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
Daniel Veillardcf461992000-03-14 18:30:20 +0000834 ctxt->myDoc && ctxt->myDoc->intSubset) {
835
836 /*
837 * If we don't substitute entities, the validation should be
838 * done on a value with replaced entities anyway.
839 */
840 if (!ctxt->replaceEntities) {
841 xmlChar *val;
842
843 ctxt->depth++;
844 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
845 0,0,0);
846 ctxt->depth--;
847 if (val == NULL)
848 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
849 ctxt->myDoc, ctxt->node, ret, value);
850 else {
851 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
852 ctxt->myDoc, ctxt->node, ret, val);
853 xmlFree(val);
854 }
855 } else {
856 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000857 ctxt->node, ret, value);
Daniel Veillardcf461992000-03-14 18:30:20 +0000858 }
859 } else {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000860 /*
861 * when validating, the ID registration is done at the attribute
862 * validation level. Otherwise we have to do specific handling here.
863 */
864 if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
865 xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
Daniel Veillardc08a2c61999-09-08 21:35:25 +0000866 else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
867 xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000868 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000869
Daniel Veillardcf461992000-03-14 18:30:20 +0000870 if (nval != NULL)
871 xmlFree(nval);
Daniel Veillard517752b1999-04-05 12:20:10 +0000872 if (name != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +0000873 xmlFree(name);
Daniel Veillard517752b1999-04-05 12:20:10 +0000874 if (ns != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +0000875 xmlFree(ns);
Daniel Veillard517752b1999-04-05 12:20:10 +0000876}
877
878/**
Daniel Veillard97b58771998-10-20 06:14:16 +0000879 * startElement:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000880 * @ctx: the user data (XML parser context)
Daniel Veillard06047432000-04-24 11:33:38 +0000881 * @fullname: The element name, including namespace prefix
Daniel Veillard517752b1999-04-05 12:20:10 +0000882 * @atts: An array of name/value attributes pairs, NULL terminated
Daniel Veillard97b58771998-10-20 06:14:16 +0000883 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000884 * called when an opening tag has been processed.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000885 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000886void
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000887startElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
Daniel Veillard97b58771998-10-20 06:14:16 +0000888{
Daniel Veillard27d88741999-05-29 11:51:49 +0000889 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000890 xmlNodePtr ret;
891 xmlNodePtr parent = ctxt->node;
892 xmlNsPtr ns;
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000893 xmlChar *name;
894 xmlChar *prefix;
895 const xmlChar *att;
896 const xmlChar *value;
Daniel Veillard517752b1999-04-05 12:20:10 +0000897 int i;
898
Daniel Veillard260a68f1998-08-13 03:39:55 +0000899#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +0000900 fprintf(stderr, "SAX.startElement(%s)\n", fullname);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000901#endif
Daniel Veillard7f7d1111999-09-22 09:46:25 +0000902
903 /*
904 * First check on validity:
905 */
906 if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
907 ((ctxt->myDoc->intSubset == NULL) ||
908 ((ctxt->myDoc->intSubset->notations == NULL) &&
909 (ctxt->myDoc->intSubset->elements == NULL) &&
910 (ctxt->myDoc->intSubset->attributes == NULL) &&
911 (ctxt->myDoc->intSubset->entities == NULL)))) {
912 if (ctxt->vctxt.error != NULL) {
913 ctxt->vctxt.error(ctxt->vctxt.userData,
914 "Validation failed: no DTD found !\n");
915 }
916 ctxt->validate = 0;
917 }
918
919
Daniel Veillard517752b1999-04-05 12:20:10 +0000920 /*
921 * Split the full name into a namespace prefix and the tag name
922 */
Daniel Veillardcf461992000-03-14 18:30:20 +0000923 name = xmlSplitQName(ctxt, fullname, &prefix);
Daniel Veillard517752b1999-04-05 12:20:10 +0000924
925
926 /*
927 * Note : the namespace resolution is deferred until the end of the
928 * attributes parsing, since local namespace can be defined as
929 * an attribute at this level.
930 */
931 ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
932 if (ret == NULL) return;
Daniel Veillardcf461992000-03-14 18:30:20 +0000933 if (ctxt->myDoc->children == NULL) {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000934#ifdef DEBUG_SAX_TREE
935 fprintf(stderr, "Setting %s as root\n", name);
936#endif
Daniel Veillardcf461992000-03-14 18:30:20 +0000937 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000938 } else if (parent == NULL) {
Daniel Veillardcf461992000-03-14 18:30:20 +0000939 parent = ctxt->myDoc->children;
Daniel Veillardb96e6431999-08-29 21:02:19 +0000940 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000941 ctxt->nodemem = -1;
Daniel Veillard517752b1999-04-05 12:20:10 +0000942
943 /*
944 * We are parsing a new node.
945 */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000946#ifdef DEBUG_SAX_TREE
947 fprintf(stderr, "pushing(%s)\n", name);
948#endif
Daniel Veillard517752b1999-04-05 12:20:10 +0000949 nodePush(ctxt, ret);
950
951 /*
952 * Link the child element
953 */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000954 if (parent != NULL) {
955 if (parent->type == XML_ELEMENT_NODE) {
956#ifdef DEBUG_SAX_TREE
957 fprintf(stderr, "adding child %s to %s\n", name, parent->name);
958#endif
959 xmlAddChild(parent, ret);
960 } else {
961#ifdef DEBUG_SAX_TREE
962 fprintf(stderr, "adding sibling %s to ", name);
963 xmlDebugDumpOneNode(stderr, parent, 0);
964#endif
965 xmlAddSibling(parent, ret);
966 }
967 }
Daniel Veillard517752b1999-04-05 12:20:10 +0000968
969 /*
Daniel Veillardb96e6431999-08-29 21:02:19 +0000970 * process all the attributes whose name start with "xml"
Daniel Veillard517752b1999-04-05 12:20:10 +0000971 */
972 if (atts != NULL) {
973 i = 0;
974 att = atts[i++];
975 value = atts[i++];
Daniel Veillardbe803962000-06-28 23:40:59 +0000976 if (!ctxt->html) {
977 while ((att != NULL) && (value != NULL)) {
978 if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l'))
979 attribute(ctxt, att, value);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000980
Daniel Veillardbe803962000-06-28 23:40:59 +0000981 att = atts[i++];
982 value = atts[i++];
983 }
Daniel Veillard517752b1999-04-05 12:20:10 +0000984 }
985 }
986
987 /*
988 * Search the namespace, note that since the attributes have been
989 * processed, the local namespaces are available.
990 */
991 ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
992 if ((ns == NULL) && (parent != NULL))
993 ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
Daniel Veillarde0854c32000-08-27 21:12:29 +0000994 if ((prefix != NULL) && (ns == NULL)) {
995 ns = xmlNewNs(ret, NULL, prefix);
996 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
997 ctxt->sax->warning(ctxt->userData,
998 "Namespace prefix %s is not defined\n", prefix);
999 }
Daniel Veillard517752b1999-04-05 12:20:10 +00001000 xmlSetNs(ret, ns);
1001
Daniel Veillardbe803962000-06-28 23:40:59 +00001002 /*
1003 * process all the other attributes
1004 */
1005 if (atts != NULL) {
1006 i = 0;
1007 att = atts[i++];
1008 value = atts[i++];
1009 if (ctxt->html) {
1010 while (att != NULL) {
1011 attribute(ctxt, att, value);
1012 att = atts[i++];
1013 value = atts[i++];
1014 }
1015 } else {
1016 while ((att != NULL) && (value != NULL)) {
1017 if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l'))
1018 attribute(ctxt, att, value);
1019
1020 /*
1021 * Next ones
1022 */
1023 att = atts[i++];
1024 value = atts[i++];
1025 }
1026 }
1027 }
1028
1029 /*
1030 * If it's the Document root, finish the Dtd validation and
1031 * check the document root element for validity
1032 */
1033 if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) {
1034 ctxt->valid &= xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
1035 ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
1036 ctxt->vctxt.finishDtd = 1;
1037 }
1038
Daniel Veillard517752b1999-04-05 12:20:10 +00001039 if (prefix != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +00001040 xmlFree(prefix);
Daniel Veillard517752b1999-04-05 12:20:10 +00001041 if (name != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +00001042 xmlFree(name);
Daniel Veillard517752b1999-04-05 12:20:10 +00001043
Daniel Veillard260a68f1998-08-13 03:39:55 +00001044}
1045
Daniel Veillard97b58771998-10-20 06:14:16 +00001046/**
1047 * endElement:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001048 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +00001049 * @name: The element name
1050 *
Daniel Veillard260a68f1998-08-13 03:39:55 +00001051 * called when the end of an element has been detected.
1052 */
Daniel Veillard97b58771998-10-20 06:14:16 +00001053void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001054endElement(void *ctx, const xmlChar *name)
Daniel Veillard97b58771998-10-20 06:14:16 +00001055{
Daniel Veillard27d88741999-05-29 11:51:49 +00001056 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001057 xmlParserNodeInfo node_info;
1058 xmlNodePtr cur = ctxt->node;
1059
Daniel Veillard260a68f1998-08-13 03:39:55 +00001060#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +00001061 if (name == NULL)
1062 fprintf(stderr, "SAX.endElement(NULL)\n");
1063 else
1064 fprintf(stderr, "SAX.endElement(%s)\n", name);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001065#endif
Daniel Veillard517752b1999-04-05 12:20:10 +00001066
1067 /* Capture end position and add node */
1068 if (cur != NULL && ctxt->record_info) {
1069 node_info.end_pos = ctxt->input->cur - ctxt->input->base;
1070 node_info.end_line = ctxt->input->line;
1071 node_info.node = cur;
1072 xmlParserAddNodeInfo(ctxt, &node_info);
1073 }
Daniel Veillardbe803962000-06-28 23:40:59 +00001074 ctxt->nodemem = -1;
Daniel Veillard517752b1999-04-05 12:20:10 +00001075
Daniel Veillardb05deb71999-08-10 19:04:08 +00001076 if (ctxt->validate && ctxt->wellFormed &&
1077 ctxt->myDoc && ctxt->myDoc->intSubset)
1078 ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
1079 cur);
1080
1081
Daniel Veillard517752b1999-04-05 12:20:10 +00001082 /*
1083 * end of parsing of this node.
1084 */
Daniel Veillardb96e6431999-08-29 21:02:19 +00001085#ifdef DEBUG_SAX_TREE
1086 fprintf(stderr, "popping(%s)\n", cur->name);
1087#endif
Daniel Veillard517752b1999-04-05 12:20:10 +00001088 nodePop(ctxt);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001089}
1090
Daniel Veillard97b58771998-10-20 06:14:16 +00001091/**
Daniel Veillard517752b1999-04-05 12:20:10 +00001092 * reference:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001093 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001094 * @name: The entity name
Daniel Veillard11e00581998-10-24 18:27:49 +00001095 *
Daniel Veillard517752b1999-04-05 12:20:10 +00001096 * called when an entity reference is detected.
Daniel Veillard11e00581998-10-24 18:27:49 +00001097 */
1098void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001099reference(void *ctx, const xmlChar *name)
Daniel Veillard11e00581998-10-24 18:27:49 +00001100{
Daniel Veillard27d88741999-05-29 11:51:49 +00001101 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001102 xmlNodePtr ret;
1103
Daniel Veillard11e00581998-10-24 18:27:49 +00001104#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +00001105 fprintf(stderr, "SAX.reference(%s)\n", name);
Daniel Veillard11e00581998-10-24 18:27:49 +00001106#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001107 if (name[0] == '#')
1108 ret = xmlNewCharRef(ctxt->myDoc, name);
1109 else
1110 ret = xmlNewReference(ctxt->myDoc, name);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001111#ifdef DEBUG_SAX_TREE
1112 fprintf(stderr, "add reference %s to %s \n", name, ctxt->node->name);
1113#endif
Daniel Veillard517752b1999-04-05 12:20:10 +00001114 xmlAddChild(ctxt->node, ret);
Daniel Veillard11e00581998-10-24 18:27:49 +00001115}
1116
1117/**
Daniel Veillard97b58771998-10-20 06:14:16 +00001118 * characters:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001119 * @ctx: the user data (XML parser context)
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001120 * @ch: a xmlChar string
1121 * @len: the number of xmlChar
Daniel Veillard97b58771998-10-20 06:14:16 +00001122 *
Daniel Veillard260a68f1998-08-13 03:39:55 +00001123 * receiving some chars from the parser.
1124 * Question: how much at a time ???
1125 */
Daniel Veillard97b58771998-10-20 06:14:16 +00001126void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001127characters(void *ctx, const xmlChar *ch, int len)
Daniel Veillard97b58771998-10-20 06:14:16 +00001128{
Daniel Veillard27d88741999-05-29 11:51:49 +00001129 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001130 xmlNodePtr lastChild;
1131
1132#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +00001133 fprintf(stderr, "SAX.characters(%.30s, %d)\n", ch, len);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001134#endif
1135 /*
1136 * Handle the data if any. If there is no child
1137 * add it as content, otherwise if the last child is text,
1138 * concatenate it, else create a new node of type text.
1139 */
1140
Daniel Veillard35008381999-10-25 13:15:52 +00001141 if (ctxt->node == NULL) {
1142#ifdef DEBUG_SAX_TREE
1143 fprintf(stderr, "add chars: ctxt->node == NULL !\n");
1144#endif
1145 return;
1146 }
Daniel Veillard260a68f1998-08-13 03:39:55 +00001147 lastChild = xmlGetLastChild(ctxt->node);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001148#ifdef DEBUG_SAX_TREE
1149 fprintf(stderr, "add chars to %s \n", ctxt->node->name);
1150#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00001151
1152 /*
1153 * Here we needed an accelerator mechanism in case of very large
1154 * elements. Use an attribute in the structure !!!
1155 */
1156 if (lastChild == NULL) {
1157 /* first node, first time */
Daniel Veillard517752b1999-04-05 12:20:10 +00001158 xmlNodeAddContentLen(ctxt->node, ch, len);
Daniel Veillardbe803962000-06-28 23:40:59 +00001159#ifndef XML_USE_BUFFER_CONTENT
1160 if (ctxt->node->children != NULL) {
1161 ctxt->nodelen = len;
1162 ctxt->nodemem = len + 1;
1163 }
1164#endif
1165 } else {
Daniel Veillarde0854c32000-08-27 21:12:29 +00001166 if ((xmlNodeIsText(lastChild)) && (ctxt->nodemem != 0)) {
Daniel Veillardbe803962000-06-28 23:40:59 +00001167#ifndef XML_USE_BUFFER_CONTENT
1168 /*
1169 * The whole point of maintaining nodelen and nodemem,
1170 * xmlTextConcat is too costly, i.e. compute lenght,
1171 * reallocate a new buffer, move data, append ch. Here
1172 * We try to minimaze realloc() uses and avoid copying
1173 * and recomputing lenght over and over.
1174 */
1175 if (ctxt->nodelen + len >= ctxt->nodemem) {
1176 xmlChar *newbuf;
1177 int size;
1178
1179 size = ctxt->nodemem + len;
1180 size *= 2;
1181 newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
1182 if (newbuf == NULL) {
1183 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1184 ctxt->sax->error(ctxt->userData,
1185 "SAX.characters(): out of memory\n");
1186 return;
1187 }
1188 ctxt->nodemem = size;
1189 lastChild->content = newbuf;
1190 }
1191 memcpy(&lastChild->content[ctxt->nodelen], ch, len);
1192 ctxt->nodelen += len;
1193 lastChild->content[ctxt->nodelen] = 0;
1194#else
Daniel Veillard517752b1999-04-05 12:20:10 +00001195 xmlTextConcat(lastChild, ch, len);
Daniel Veillardbe803962000-06-28 23:40:59 +00001196#endif
1197 } else {
1198 /* Mixed content, first time */
Daniel Veillard517752b1999-04-05 12:20:10 +00001199 lastChild = xmlNewTextLen(ch, len);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001200 xmlAddChild(ctxt->node, lastChild);
Daniel Veillardbe803962000-06-28 23:40:59 +00001201#ifndef XML_USE_BUFFER_CONTENT
1202 if (ctxt->node->children != NULL) {
1203 ctxt->nodelen = len;
1204 ctxt->nodemem = len + 1;
1205 }
1206#endif
Daniel Veillard260a68f1998-08-13 03:39:55 +00001207 }
1208 }
1209}
1210
Daniel Veillard97b58771998-10-20 06:14:16 +00001211/**
1212 * ignorableWhitespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001213 * @ctx: the user data (XML parser context)
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001214 * @ch: a xmlChar string
1215 * @len: the number of xmlChar
Daniel Veillard97b58771998-10-20 06:14:16 +00001216 *
Daniel Veillard260a68f1998-08-13 03:39:55 +00001217 * receiving some ignorable whitespaces from the parser.
1218 * Question: how much at a time ???
1219 */
Daniel Veillard97b58771998-10-20 06:14:16 +00001220void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001221ignorableWhitespace(void *ctx, const xmlChar *ch, int len)
Daniel Veillard97b58771998-10-20 06:14:16 +00001222{
Daniel Veillard27d88741999-05-29 11:51:49 +00001223 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillard260a68f1998-08-13 03:39:55 +00001224#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +00001225 fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001226#endif
1227}
1228
Daniel Veillard97b58771998-10-20 06:14:16 +00001229/**
1230 * processingInstruction:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001231 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +00001232 * @target: the target name
1233 * @data: the PI data's
Daniel Veillard97b58771998-10-20 06:14:16 +00001234 *
1235 * A processing instruction has been parsed.
Daniel Veillard260a68f1998-08-13 03:39:55 +00001236 */
Daniel Veillard97b58771998-10-20 06:14:16 +00001237void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001238processingInstruction(void *ctx, const xmlChar *target,
1239 const xmlChar *data)
Daniel Veillard97b58771998-10-20 06:14:16 +00001240{
Daniel Veillardb96e6431999-08-29 21:02:19 +00001241 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1242 xmlNodePtr ret;
1243 xmlNodePtr parent = ctxt->node;
1244
Daniel Veillard260a68f1998-08-13 03:39:55 +00001245#ifdef DEBUG_SAX
1246 fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
1247#endif
Daniel Veillardb96e6431999-08-29 21:02:19 +00001248
1249 ret = xmlNewPI(target, data);
1250 if (ret == NULL) return;
Daniel Veillardcf461992000-03-14 18:30:20 +00001251 parent = ctxt->node;
1252
1253 if (ctxt->inSubset == 1) {
1254 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
1255 return;
1256 } else if (ctxt->inSubset == 2) {
1257 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
1258 return;
1259 }
1260 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001261#ifdef DEBUG_SAX_TREE
1262 fprintf(stderr, "Setting PI %s as root\n", target);
1263#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001264 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1265 return;
Daniel Veillardb96e6431999-08-29 21:02:19 +00001266 }
Daniel Veillardcf461992000-03-14 18:30:20 +00001267 if (parent->type == XML_ELEMENT_NODE) {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001268#ifdef DEBUG_SAX_TREE
Daniel Veillardcf461992000-03-14 18:30:20 +00001269 fprintf(stderr, "adding PI %s child to %s\n", target, parent->name);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001270#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001271 xmlAddChild(parent, ret);
1272 } else {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001273#ifdef DEBUG_SAX_TREE
Daniel Veillardcf461992000-03-14 18:30:20 +00001274 fprintf(stderr, "adding PI %s sibling to ", target);
1275 xmlDebugDumpOneNode(stderr, parent, 0);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001276#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001277 xmlAddSibling(parent, ret);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001278 }
Daniel Veillard260a68f1998-08-13 03:39:55 +00001279}
1280
Daniel Veillard517752b1999-04-05 12:20:10 +00001281/**
1282 * globalNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001283 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001284 * @href: the namespace associated URN
1285 * @prefix: the namespace prefix
1286 *
1287 * An old global namespace has been parsed.
1288 */
1289void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001290globalNamespace(void *ctx, const xmlChar *href, const xmlChar *prefix)
Daniel Veillard517752b1999-04-05 12:20:10 +00001291{
Daniel Veillard27d88741999-05-29 11:51:49 +00001292 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001293#ifdef DEBUG_SAX
1294 fprintf(stderr, "SAX.globalNamespace(%s, %s)\n", href, prefix);
1295#endif
1296 xmlNewGlobalNs(ctxt->myDoc, href, prefix);
1297}
1298
1299/**
1300 * setNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001301 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001302 * @name: the namespace prefix
1303 *
1304 * Set the current element namespace.
1305 */
Daniel Veillard06047432000-04-24 11:33:38 +00001306
Daniel Veillard517752b1999-04-05 12:20:10 +00001307void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001308setNamespace(void *ctx, const xmlChar *name)
Daniel Veillard517752b1999-04-05 12:20:10 +00001309{
Daniel Veillard27d88741999-05-29 11:51:49 +00001310 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001311 xmlNsPtr ns;
1312 xmlNodePtr parent;
1313
1314#ifdef DEBUG_SAX
1315 fprintf(stderr, "SAX.setNamespace(%s)\n", name);
1316#endif
1317 ns = xmlSearchNs(ctxt->myDoc, ctxt->node, name);
1318 if (ns == NULL) { /* ctxt->node may not have a parent yet ! */
1319 if (ctxt->nodeNr >= 2) {
1320 parent = ctxt->nodeTab[ctxt->nodeNr - 2];
1321 if (parent != NULL)
1322 ns = xmlSearchNs(ctxt->myDoc, parent, name);
1323 }
1324 }
1325 xmlSetNs(ctxt->node, ns);
1326}
1327
1328/**
1329 * getNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001330 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001331 *
1332 * Get the current element namespace.
Daniel Veillard06047432000-04-24 11:33:38 +00001333 *
1334 * Returns the xmlNsPtr or NULL if none
Daniel Veillard517752b1999-04-05 12:20:10 +00001335 */
Daniel Veillard06047432000-04-24 11:33:38 +00001336
Daniel Veillard517752b1999-04-05 12:20:10 +00001337xmlNsPtr
Daniel Veillard27d88741999-05-29 11:51:49 +00001338getNamespace(void *ctx)
Daniel Veillard517752b1999-04-05 12:20:10 +00001339{
Daniel Veillard27d88741999-05-29 11:51:49 +00001340 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001341 xmlNsPtr ret;
1342
1343#ifdef DEBUG_SAX
1344 fprintf(stderr, "SAX.getNamespace()\n");
1345#endif
1346 ret = ctxt->node->ns;
1347 return(ret);
1348}
1349
1350/**
1351 * checkNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001352 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001353 * @namespace: the namespace to check against
1354 *
1355 * Check that the current element namespace is the same as the
1356 * one read upon parsing.
Daniel Veillard06047432000-04-24 11:33:38 +00001357 *
1358 * Returns 1 if true 0 otherwise
Daniel Veillard517752b1999-04-05 12:20:10 +00001359 */
Daniel Veillard06047432000-04-24 11:33:38 +00001360
Daniel Veillard517752b1999-04-05 12:20:10 +00001361int
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001362checkNamespace(void *ctx, xmlChar *namespace)
Daniel Veillard517752b1999-04-05 12:20:10 +00001363{
Daniel Veillard27d88741999-05-29 11:51:49 +00001364 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001365 xmlNodePtr cur = ctxt->node;
1366
1367#ifdef DEBUG_SAX
1368 fprintf(stderr, "SAX.checkNamespace(%s)\n", namespace);
1369#endif
1370
1371 /*
1372 * Check that the Name in the ETag is the same as in the STag.
1373 */
1374 if (namespace == NULL) {
1375 if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
1376 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1377 ctxt->sax->error(ctxt,
1378 "End tags for %s don't hold the namespace %s\n",
1379 cur->name, cur->ns->prefix);
1380 ctxt->wellFormed = 0;
1381 }
1382 } else {
1383 if ((cur->ns == NULL) || (cur->ns->prefix == NULL)) {
1384 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1385 ctxt->sax->error(ctxt,
1386 "End tags %s holds a prefix %s not used by the open tag\n",
1387 cur->name, namespace);
1388 ctxt->wellFormed = 0;
Daniel Veillard8b5dd832000-10-01 20:28:44 +00001389 } else if (!xmlStrEqual(namespace, cur->ns->prefix)) {
Daniel Veillard517752b1999-04-05 12:20:10 +00001390 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1391 ctxt->sax->error(ctxt,
1392 "Start and End tags for %s don't use the same namespaces: %s and %s\n",
1393 cur->name, cur->ns->prefix, namespace);
1394 ctxt->wellFormed = 0;
1395 } else
1396 return(1);
1397 }
1398 return(0);
1399}
1400
1401/**
1402 * namespaceDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001403 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001404 * @href: the namespace associated URN
1405 * @prefix: the namespace prefix
1406 *
1407 * A namespace has been parsed.
1408 */
1409void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001410namespaceDecl(void *ctx, const xmlChar *href, const xmlChar *prefix)
Daniel Veillard517752b1999-04-05 12:20:10 +00001411{
Daniel Veillard27d88741999-05-29 11:51:49 +00001412 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001413#ifdef DEBUG_SAX
1414 if (prefix == NULL)
1415 fprintf(stderr, "SAX.namespaceDecl(%s, NULL)\n", href);
1416 else
1417 fprintf(stderr, "SAX.namespaceDecl(%s, %s)\n", href, prefix);
1418#endif
1419 xmlNewNs(ctxt->node, href, prefix);
1420}
1421
1422/**
1423 * comment:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001424 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001425 * @value: the comment content
1426 *
1427 * A comment has been parsed.
1428 */
1429void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001430comment(void *ctx, const xmlChar *value)
Daniel Veillard517752b1999-04-05 12:20:10 +00001431{
Daniel Veillard27d88741999-05-29 11:51:49 +00001432 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard14fff061999-06-22 21:49:07 +00001433 xmlNodePtr ret;
Daniel Veillardb96e6431999-08-29 21:02:19 +00001434 xmlNodePtr parent = ctxt->node;
Daniel Veillard14fff061999-06-22 21:49:07 +00001435
Daniel Veillard517752b1999-04-05 12:20:10 +00001436#ifdef DEBUG_SAX
1437 fprintf(stderr, "SAX.comment(%s)\n", value);
1438#endif
Daniel Veillard14fff061999-06-22 21:49:07 +00001439 ret = xmlNewDocComment(ctxt->myDoc, value);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001440 if (ret == NULL) return;
1441
Daniel Veillardcf461992000-03-14 18:30:20 +00001442 if (ctxt->inSubset == 1) {
1443 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
1444 return;
1445 } else if (ctxt->inSubset == 2) {
1446 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
1447 return;
1448 }
1449 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001450#ifdef DEBUG_SAX_TREE
1451 fprintf(stderr, "Setting comment as root\n");
1452#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001453 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1454 return;
Daniel Veillardb96e6431999-08-29 21:02:19 +00001455 }
Daniel Veillardcf461992000-03-14 18:30:20 +00001456 if (parent->type == XML_ELEMENT_NODE) {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001457#ifdef DEBUG_SAX_TREE
Daniel Veillardcf461992000-03-14 18:30:20 +00001458 fprintf(stderr, "adding comment child to %s\n", parent->name);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001459#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001460 xmlAddChild(parent, ret);
1461 } else {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001462#ifdef DEBUG_SAX_TREE
Daniel Veillardcf461992000-03-14 18:30:20 +00001463 fprintf(stderr, "adding comment sibling to ");
1464 xmlDebugDumpOneNode(stderr, parent, 0);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001465#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001466 xmlAddSibling(parent, ret);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001467 }
Daniel Veillardb05deb71999-08-10 19:04:08 +00001468}
1469
1470/**
1471 * cdataBlock:
1472 * @ctx: the user data (XML parser context)
1473 * @value: The pcdata content
1474 * @len: the block length
1475 *
1476 * called when a pcdata block has been parsed
1477 */
1478void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001479cdataBlock(void *ctx, const xmlChar *value, int len)
Daniel Veillardb05deb71999-08-10 19:04:08 +00001480{
1481 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001482 xmlNodePtr ret, lastChild;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001483
1484#ifdef DEBUG_SAX
Daniel Veillardb96e6431999-08-29 21:02:19 +00001485 fprintf(stderr, "SAX.pcdata(%.10s, %d)\n", value, len);
Daniel Veillardb05deb71999-08-10 19:04:08 +00001486#endif
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001487 lastChild = xmlGetLastChild(ctxt->node);
1488#ifdef DEBUG_SAX_TREE
1489 fprintf(stderr, "add chars to %s \n", ctxt->node->name);
1490#endif
1491 if ((lastChild != NULL) &&
1492 (lastChild->type == XML_CDATA_SECTION_NODE)) {
1493 xmlTextConcat(lastChild, value, len);
1494 } else {
1495 ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
1496 xmlAddChild(ctxt->node, ret);
1497 }
Daniel Veillard517752b1999-04-05 12:20:10 +00001498}
1499
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001500/*
1501 * Default handler for XML, builds the DOM tree
1502 */
Daniel Veillard260a68f1998-08-13 03:39:55 +00001503xmlSAXHandler xmlDefaultSAXHandler = {
Daniel Veillard517752b1999-04-05 12:20:10 +00001504 internalSubset,
1505 isStandalone,
1506 hasInternalSubset,
1507 hasExternalSubset,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001508 resolveEntity,
Daniel Veillard517752b1999-04-05 12:20:10 +00001509 getEntity,
1510 entityDecl,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001511 notationDecl,
Daniel Veillard517752b1999-04-05 12:20:10 +00001512 attributeDecl,
1513 elementDecl,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001514 unparsedEntityDecl,
1515 setDocumentLocator,
1516 startDocument,
1517 endDocument,
1518 startElement,
1519 endElement,
Daniel Veillard517752b1999-04-05 12:20:10 +00001520 reference,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001521 characters,
1522 ignorableWhitespace,
1523 processingInstruction,
Daniel Veillard517752b1999-04-05 12:20:10 +00001524 comment,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001525 xmlParserWarning,
1526 xmlParserError,
1527 xmlParserError,
Daniel Veillardb05deb71999-08-10 19:04:08 +00001528 getParameterEntity,
1529 cdataBlock,
Daniel Veillardcf461992000-03-14 18:30:20 +00001530 externalSubset,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001531};
1532
Daniel Veillard97b58771998-10-20 06:14:16 +00001533/**
1534 * xmlDefaultSAXHandlerInit:
1535 *
1536 * Initialize the default SAX handler
Daniel Veillard97b58771998-10-20 06:14:16 +00001537 */
1538void
1539xmlDefaultSAXHandlerInit(void)
1540{
Daniel Veillard517752b1999-04-05 12:20:10 +00001541 xmlDefaultSAXHandler.internalSubset = internalSubset;
Daniel Veillardcf461992000-03-14 18:30:20 +00001542 xmlDefaultSAXHandler.externalSubset = externalSubset;
Daniel Veillard517752b1999-04-05 12:20:10 +00001543 xmlDefaultSAXHandler.isStandalone = isStandalone;
1544 xmlDefaultSAXHandler.hasInternalSubset = hasInternalSubset;
1545 xmlDefaultSAXHandler.hasExternalSubset = hasExternalSubset;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001546 xmlDefaultSAXHandler.resolveEntity = resolveEntity;
Daniel Veillard517752b1999-04-05 12:20:10 +00001547 xmlDefaultSAXHandler.getEntity = getEntity;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001548 xmlDefaultSAXHandler.getParameterEntity = getParameterEntity;
Daniel Veillard517752b1999-04-05 12:20:10 +00001549 xmlDefaultSAXHandler.entityDecl = entityDecl;
1550 xmlDefaultSAXHandler.attributeDecl = attributeDecl;
1551 xmlDefaultSAXHandler.elementDecl = elementDecl;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001552 xmlDefaultSAXHandler.notationDecl = notationDecl;
1553 xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
1554 xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1555 xmlDefaultSAXHandler.startDocument = startDocument;
1556 xmlDefaultSAXHandler.endDocument = endDocument;
1557 xmlDefaultSAXHandler.startElement = startElement;
1558 xmlDefaultSAXHandler.endElement = endElement;
Daniel Veillard517752b1999-04-05 12:20:10 +00001559 xmlDefaultSAXHandler.reference = reference;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001560 xmlDefaultSAXHandler.characters = characters;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001561 xmlDefaultSAXHandler.cdataBlock = cdataBlock;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001562 xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1563 xmlDefaultSAXHandler.processingInstruction = processingInstruction;
Daniel Veillard517752b1999-04-05 12:20:10 +00001564 xmlDefaultSAXHandler.comment = comment;
Daniel Veillardcf461992000-03-14 18:30:20 +00001565 if (xmlGetWarningsDefaultValue == 0)
1566 xmlDefaultSAXHandler.warning = NULL;
1567 else
1568 xmlDefaultSAXHandler.warning = xmlParserWarning;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001569 xmlDefaultSAXHandler.error = xmlParserError;
1570 xmlDefaultSAXHandler.fatalError = xmlParserError;
1571}
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001572
1573/*
1574 * Default handler for HTML, builds the DOM tree
1575 */
1576xmlSAXHandler htmlDefaultSAXHandler = {
Daniel Veillardd83eb822000-06-30 18:39:56 +00001577 internalSubset,
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001578 NULL,
1579 NULL,
1580 NULL,
1581 NULL,
1582 getEntity,
1583 NULL,
1584 NULL,
1585 NULL,
1586 NULL,
1587 NULL,
1588 setDocumentLocator,
1589 startDocument,
1590 endDocument,
1591 startElement,
1592 endElement,
1593 NULL,
1594 characters,
1595 ignorableWhitespace,
1596 NULL,
1597 comment,
1598 xmlParserWarning,
1599 xmlParserError,
1600 xmlParserError,
Daniel Veillardb05deb71999-08-10 19:04:08 +00001601 getParameterEntity,
Daniel Veillard7eda8452000-10-14 23:38:43 +00001602 cdataBlock,
Daniel Veillardcf461992000-03-14 18:30:20 +00001603 NULL,
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001604};
1605
1606/**
1607 * htmlDefaultSAXHandlerInit:
1608 *
1609 * Initialize the default SAX handler
1610 */
1611void
1612htmlDefaultSAXHandlerInit(void)
1613{
Daniel Veillardd83eb822000-06-30 18:39:56 +00001614 htmlDefaultSAXHandler.internalSubset = internalSubset;
Daniel Veillardcf461992000-03-14 18:30:20 +00001615 htmlDefaultSAXHandler.externalSubset = NULL;
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001616 htmlDefaultSAXHandler.isStandalone = NULL;
1617 htmlDefaultSAXHandler.hasInternalSubset = NULL;
1618 htmlDefaultSAXHandler.hasExternalSubset = NULL;
1619 htmlDefaultSAXHandler.resolveEntity = NULL;
1620 htmlDefaultSAXHandler.getEntity = getEntity;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001621 htmlDefaultSAXHandler.getParameterEntity = NULL;
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001622 htmlDefaultSAXHandler.entityDecl = NULL;
1623 htmlDefaultSAXHandler.attributeDecl = NULL;
1624 htmlDefaultSAXHandler.elementDecl = NULL;
1625 htmlDefaultSAXHandler.notationDecl = NULL;
1626 htmlDefaultSAXHandler.unparsedEntityDecl = NULL;
1627 htmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1628 htmlDefaultSAXHandler.startDocument = startDocument;
1629 htmlDefaultSAXHandler.endDocument = endDocument;
1630 htmlDefaultSAXHandler.startElement = startElement;
1631 htmlDefaultSAXHandler.endElement = endElement;
1632 htmlDefaultSAXHandler.reference = NULL;
1633 htmlDefaultSAXHandler.characters = characters;
Daniel Veillard7eda8452000-10-14 23:38:43 +00001634 xmlDefaultSAXHandler.cdataBlock = cdataBlock;
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001635 htmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1636 htmlDefaultSAXHandler.processingInstruction = NULL;
1637 htmlDefaultSAXHandler.comment = comment;
1638 htmlDefaultSAXHandler.warning = xmlParserWarning;
1639 htmlDefaultSAXHandler.error = xmlParserError;
1640 htmlDefaultSAXHandler.fatalError = xmlParserError;
1641}
Daniel Veillard39c7d712000-09-10 16:14:55 +00001642
1643/*
1644 * Default handler for HTML, builds the DOM tree
1645 */
1646xmlSAXHandler sgmlDefaultSAXHandler = {
1647 internalSubset,
1648 NULL,
1649 NULL,
1650 NULL,
1651 NULL,
1652 getEntity,
1653 NULL,
1654 NULL,
1655 NULL,
1656 NULL,
1657 NULL,
1658 setDocumentLocator,
1659 startDocument,
1660 endDocument,
1661 startElement,
1662 endElement,
1663 NULL,
1664 characters,
1665 ignorableWhitespace,
1666 NULL,
1667 comment,
1668 xmlParserWarning,
1669 xmlParserError,
1670 xmlParserError,
1671 getParameterEntity,
1672 NULL,
1673 NULL,
1674};
1675
1676/**
1677 * sgmlDefaultSAXHandlerInit:
1678 *
1679 * Initialize the default SAX handler
1680 */
1681void
1682sgmlDefaultSAXHandlerInit(void)
1683{
1684 sgmlDefaultSAXHandler.internalSubset = internalSubset;
1685 sgmlDefaultSAXHandler.externalSubset = NULL;
1686 sgmlDefaultSAXHandler.isStandalone = NULL;
1687 sgmlDefaultSAXHandler.hasInternalSubset = NULL;
1688 sgmlDefaultSAXHandler.hasExternalSubset = NULL;
1689 sgmlDefaultSAXHandler.resolveEntity = NULL;
1690 sgmlDefaultSAXHandler.getEntity = getEntity;
1691 sgmlDefaultSAXHandler.getParameterEntity = NULL;
1692 sgmlDefaultSAXHandler.entityDecl = NULL;
1693 sgmlDefaultSAXHandler.attributeDecl = NULL;
1694 sgmlDefaultSAXHandler.elementDecl = NULL;
1695 sgmlDefaultSAXHandler.notationDecl = NULL;
1696 sgmlDefaultSAXHandler.unparsedEntityDecl = NULL;
1697 sgmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1698 sgmlDefaultSAXHandler.startDocument = startDocument;
1699 sgmlDefaultSAXHandler.endDocument = endDocument;
1700 sgmlDefaultSAXHandler.startElement = startElement;
1701 sgmlDefaultSAXHandler.endElement = endElement;
1702 sgmlDefaultSAXHandler.reference = NULL;
1703 sgmlDefaultSAXHandler.characters = characters;
1704 sgmlDefaultSAXHandler.cdataBlock = NULL;
1705 sgmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1706 sgmlDefaultSAXHandler.processingInstruction = NULL;
1707 sgmlDefaultSAXHandler.comment = comment;
1708 sgmlDefaultSAXHandler.warning = xmlParserWarning;
1709 sgmlDefaultSAXHandler.error = xmlParserError;
1710 sgmlDefaultSAXHandler.fatalError = xmlParserError;
1711}