blob: 8483c2fd2fb99892cc89cf4a37b7c1b645d4d777 [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
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000164 xmlGenericError(xmlGenericErrorContext,
165 "SAX.internalSubset(%s, %s, %s)\n",
Daniel Veillard517752b1999-04-05 12:20:10 +0000166 name, ExternalID, SystemID);
167#endif
Daniel Veillardd83eb822000-06-30 18:39:56 +0000168
169 if (ctxt->myDoc == NULL)
170 return;
171 dtd = xmlGetIntSubset(ctxt->myDoc);
172 if (dtd != NULL) {
Daniel Veillardb8f25c92000-08-19 19:52:36 +0000173 if (ctxt->html)
174 return;
Daniel Veillardd83eb822000-06-30 18:39:56 +0000175 xmlUnlinkNode((xmlNodePtr) dtd);
176 xmlFreeDtd(dtd);
177 ctxt->myDoc->intSubset = NULL;
178 }
179 ctxt->myDoc->intSubset =
180 xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
Daniel Veillardcf461992000-03-14 18:30:20 +0000181}
182
183/**
184 * externalSubset:
185 * @ctx: the user data (XML parser context)
Daniel Veillard06047432000-04-24 11:33:38 +0000186 * @name: the root element name
187 * @ExternalID: the external ID
188 * @SystemID: the SYSTEM ID (e.g. filename or URL)
Daniel Veillardcf461992000-03-14 18:30:20 +0000189 *
190 * Callback on external subset declaration.
191 */
192void
193externalSubset(void *ctx, const xmlChar *name,
194 const xmlChar *ExternalID, const xmlChar *SystemID)
195{
196 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
197#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000198 xmlGenericError(xmlGenericErrorContext,
199 "SAX.externalSubset(%s, %s, %s)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000200 name, ExternalID, SystemID);
201#endif
Daniel Veillardb05deb71999-08-10 19:04:08 +0000202 if (((ExternalID != NULL) || (SystemID != NULL)) &&
203 (ctxt->validate && ctxt->wellFormed && ctxt->myDoc)) {
204 /*
205 * Try to fetch and parse the external subset.
206 */
Daniel Veillardcf461992000-03-14 18:30:20 +0000207 xmlParserInputPtr oldinput;
208 int oldinputNr;
209 int oldinputMax;
210 xmlParserInputPtr *oldinputTab;
211 int oldwellFormed;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000212 xmlParserInputPtr input = NULL;
213 xmlCharEncoding enc;
Daniel Veillard32bc74e2000-07-14 14:49:25 +0000214 int oldcharset;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000215
Daniel Veillardb05deb71999-08-10 19:04:08 +0000216 /*
217 * Ask the Entity resolver to load the damn thing
218 */
Daniel Veillardcf461992000-03-14 18:30:20 +0000219 if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
220 input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000221 SystemID);
222 if (input == NULL) {
Daniel Veillardb05deb71999-08-10 19:04:08 +0000223 return;
224 }
225
Daniel Veillardcf461992000-03-14 18:30:20 +0000226 xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
227
Daniel Veillardb05deb71999-08-10 19:04:08 +0000228 /*
Daniel Veillardcf461992000-03-14 18:30:20 +0000229 * make sure we won't destroy the main document context
Daniel Veillardb05deb71999-08-10 19:04:08 +0000230 */
Daniel Veillardcf461992000-03-14 18:30:20 +0000231 oldinput = ctxt->input;
232 oldinputNr = ctxt->inputNr;
233 oldinputMax = ctxt->inputMax;
234 oldinputTab = ctxt->inputTab;
235 oldwellFormed = ctxt->wellFormed;
Daniel Veillardbe803962000-06-28 23:40:59 +0000236 oldcharset = ctxt->charset;
Daniel Veillardcf461992000-03-14 18:30:20 +0000237
238 ctxt->inputTab = (xmlParserInputPtr *)
239 xmlMalloc(5 * sizeof(xmlParserInputPtr));
240 if (ctxt->inputTab == NULL) {
241 ctxt->errNo = XML_ERR_NO_MEMORY;
242 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
243 ctxt->sax->error(ctxt->userData,
244 "externalSubset: out of memory\n");
245 ctxt->errNo = XML_ERR_NO_MEMORY;
246 ctxt->input = oldinput;
247 ctxt->inputNr = oldinputNr;
248 ctxt->inputMax = oldinputMax;
249 ctxt->inputTab = oldinputTab;
Daniel Veillardbe803962000-06-28 23:40:59 +0000250 ctxt->charset = oldcharset;
Daniel Veillardcf461992000-03-14 18:30:20 +0000251 return;
252 }
253 ctxt->inputNr = 0;
254 ctxt->inputMax = 5;
255 ctxt->input = NULL;
256 xmlPushInput(ctxt, input);
257
258 /*
259 * On the fly encoding conversion if needed
260 */
261 enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
262 xmlSwitchEncoding(ctxt, enc);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000263
264 if (input->filename == NULL)
Daniel Veillardb96e6431999-08-29 21:02:19 +0000265 input->filename = (char *) xmlStrdup(SystemID);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000266 input->line = 1;
267 input->col = 1;
Daniel Veillardcf461992000-03-14 18:30:20 +0000268 input->base = ctxt->input->cur;
269 input->cur = ctxt->input->cur;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000270 input->free = NULL;
271
272 /*
273 * let's parse that entity knowing it's an external subset.
274 */
Daniel Veillardcf461992000-03-14 18:30:20 +0000275 xmlParseExternalSubset(ctxt, ExternalID, SystemID);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000276
Daniel Veillardcf461992000-03-14 18:30:20 +0000277 /*
278 * Free up the external entities
279 */
280
281 while (ctxt->inputNr > 1)
282 xmlPopInput(ctxt);
283 xmlFreeInputStream(ctxt->input);
284 xmlFree(ctxt->inputTab);
285
286 /*
287 * Restore the parsing context of the main entity
288 */
289 ctxt->input = oldinput;
290 ctxt->inputNr = oldinputNr;
291 ctxt->inputMax = oldinputMax;
292 ctxt->inputTab = oldinputTab;
Daniel Veillardbe803962000-06-28 23:40:59 +0000293 ctxt->charset = oldcharset;
Daniel Veillardcf461992000-03-14 18:30:20 +0000294 /* ctxt->wellFormed = oldwellFormed; */
Daniel Veillard011b63c1999-06-02 17:44:04 +0000295 }
Daniel Veillard517752b1999-04-05 12:20:10 +0000296}
297
298/**
Daniel Veillard97b58771998-10-20 06:14:16 +0000299 * resolveEntity:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000300 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000301 * @publicId: The public ID of the entity
302 * @systemId: The system ID of the entity
303 *
Daniel Veillard686d6b62000-01-03 11:08:02 +0000304 * The entity loader, to control the loading of external entities,
305 * the application can either:
306 * - override this resolveEntity() callback in the SAX block
307 * - or better use the xmlSetExternalEntityLoader() function to
308 * set up it's own entity resolution routine
Daniel Veillard97b58771998-10-20 06:14:16 +0000309 *
Daniel Veillard1e346af1999-02-22 10:33:01 +0000310 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000311 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000312xmlParserInputPtr
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000313resolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard97b58771998-10-20 06:14:16 +0000314{
Daniel Veillard011b63c1999-06-02 17:44:04 +0000315 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000316 xmlParserInputPtr ret;
Daniel Veillard04698d92000-09-17 16:00:22 +0000317 xmlChar *URI;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000318 const char *base = NULL;
319
320 if (ctxt->input != NULL)
321 base = ctxt->input->filename;
322 if (base == NULL)
323 base = ctxt->directory;
324
Daniel Veillard04698d92000-09-17 16:00:22 +0000325 URI = xmlBuildURI(systemId, (const xmlChar *) base);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000326
327#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000328 xmlGenericError(xmlGenericErrorContext,
329 "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000330#endif
Daniel Veillardccb09631998-10-27 06:21:04 +0000331
Daniel Veillard39c7d712000-09-10 16:14:55 +0000332 ret = xmlLoadExternalEntity((const char *) URI,
333 (const char *) publicId, ctxt);
334 if (URI != NULL)
335 xmlFree(URI);
336 return(ret);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000337}
338
Daniel Veillard97b58771998-10-20 06:14:16 +0000339/**
Daniel Veillard517752b1999-04-05 12:20:10 +0000340 * getEntity:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000341 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000342 * @name: The entity name
343 *
344 * Get an entity by name
345 *
Daniel Veillard011b63c1999-06-02 17:44:04 +0000346 * Returns the xmlEntityPtr if found.
Daniel Veillard517752b1999-04-05 12:20:10 +0000347 */
348xmlEntityPtr
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000349getEntity(void *ctx, const xmlChar *name)
Daniel Veillard517752b1999-04-05 12:20:10 +0000350{
Daniel Veillard27d88741999-05-29 11:51:49 +0000351 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000352 xmlEntityPtr ret;
353
354#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000355 xmlGenericError(xmlGenericErrorContext,
356 "SAX.getEntity(%s)\n", name);
Daniel Veillard517752b1999-04-05 12:20:10 +0000357#endif
358
359 ret = xmlGetDocEntity(ctxt->myDoc, name);
Daniel Veillard87b95392000-08-12 21:12:04 +0000360 if ((ret != NULL) && (ctxt->validate) && (ret->children == NULL) &&
361 (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
362 /*
363 * for validation purposes we really need to fetch and
364 * parse the external entity
365 */
366 int parse;
367 xmlNodePtr children;
368
369 parse = xmlParseCtxtExternalEntity(ctxt,
370 ret->SystemID, ret->ExternalID, &children);
371 xmlAddChildList((xmlNodePtr) ret, children);
372 }
Daniel Veillard517752b1999-04-05 12:20:10 +0000373 return(ret);
374}
375
Daniel Veillardb05deb71999-08-10 19:04:08 +0000376/**
377 * getParameterEntity:
378 * @ctx: the user data (XML parser context)
379 * @name: The entity name
380 *
381 * Get a parameter entity by name
382 *
383 * Returns the xmlEntityPtr if found.
384 */
385xmlEntityPtr
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000386getParameterEntity(void *ctx, const xmlChar *name)
Daniel Veillardb05deb71999-08-10 19:04:08 +0000387{
388 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
389 xmlEntityPtr ret;
390
391#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000392 xmlGenericError(xmlGenericErrorContext,
393 "SAX.getParameterEntity(%s)\n", name);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000394#endif
395
396 ret = xmlGetParameterEntity(ctxt->myDoc, name);
397 return(ret);
398}
399
Daniel Veillard517752b1999-04-05 12:20:10 +0000400
401/**
402 * entityDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000403 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000404 * @name: the entity name
405 * @type: the entity type
406 * @publicId: The public ID of the entity
407 * @systemId: The system ID of the entity
408 * @content: the entity value (without processing).
409 *
410 * An entity definition has been parsed
411 */
412void
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000413entityDecl(void *ctx, const xmlChar *name, int type,
414 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
Daniel Veillard517752b1999-04-05 12:20:10 +0000415{
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000416 xmlEntityPtr ent;
Daniel Veillard27d88741999-05-29 11:51:49 +0000417 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000418
419#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000420 xmlGenericError(xmlGenericErrorContext,
421 "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
Daniel Veillard517752b1999-04-05 12:20:10 +0000422 name, type, publicId, systemId, content);
423#endif
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000424 if (ctxt->inSubset == 1) {
425 ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
Daniel Veillardcf461992000-03-14 18:30:20 +0000426 systemId, content);
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000427 if ((ent == NULL) && (ctxt->pedantic) &&
428 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
429 ctxt->sax->warning(ctxt,
430 "Entity(%s) already defined in the internal subset\n", name);
Daniel Veillard39c7d712000-09-10 16:14:55 +0000431 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
Daniel Veillard04698d92000-09-17 16:00:22 +0000432 xmlChar *URI;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000433 const char *base = NULL;
434
435 if (ctxt->input != NULL)
436 base = ctxt->input->filename;
437 if (base == NULL)
438 base = ctxt->directory;
439
Daniel Veillard04698d92000-09-17 16:00:22 +0000440 URI = xmlBuildURI(systemId, (const xmlChar *) base);
Daniel Veillard39c7d712000-09-10 16:14:55 +0000441 ent->URI = URI;
442 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000443 } else if (ctxt->inSubset == 2) {
444 ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
Daniel Veillardcf461992000-03-14 18:30:20 +0000445 systemId, content);
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000446 if ((ent == NULL) && (ctxt->pedantic) &&
447 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
448 ctxt->sax->warning(ctxt,
449 "Entity(%s) already defined in the external subset\n", name);
Daniel Veillard39c7d712000-09-10 16:14:55 +0000450 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
Daniel Veillard04698d92000-09-17 16:00:22 +0000451 xmlChar *URI;
Daniel Veillard39c7d712000-09-10 16:14:55 +0000452 const char *base = NULL;
453
454 if (ctxt->input != NULL)
455 base = ctxt->input->filename;
456 if (base == NULL)
457 base = ctxt->directory;
458
Daniel Veillard04698d92000-09-17 16:00:22 +0000459 URI = xmlBuildURI(systemId, (const xmlChar *) base);
Daniel Veillard39c7d712000-09-10 16:14:55 +0000460 ent->URI = URI;
461 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +0000462 } else {
Daniel Veillardcf461992000-03-14 18:30:20 +0000463 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
464 ctxt->sax->error(ctxt,
465 "SAX.entityDecl(%s) called while not in subset\n", name);
466 }
Daniel Veillard517752b1999-04-05 12:20:10 +0000467}
468
469/**
470 * attributeDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000471 * @ctx: the user data (XML parser context)
Daniel Veillard06047432000-04-24 11:33:38 +0000472 * @elem: the name of the element
Daniel Veillardcf461992000-03-14 18:30:20 +0000473 * @fullname: the attribute name
Daniel Veillard517752b1999-04-05 12:20:10 +0000474 * @type: the attribute type
Daniel Veillard06047432000-04-24 11:33:38 +0000475 * @def: the type of default value
476 * @defaultValue: the attribute default value
477 * @tree: the tree of enumerated value set
Daniel Veillard517752b1999-04-05 12:20:10 +0000478 *
479 * An attribute definition has been parsed
480 */
481void
Daniel Veillardcf461992000-03-14 18:30:20 +0000482attributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000483 int type, int def, const xmlChar *defaultValue,
Daniel Veillard517752b1999-04-05 12:20:10 +0000484 xmlEnumerationPtr tree)
485{
Daniel Veillard27d88741999-05-29 11:51:49 +0000486 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000487 xmlAttributePtr attr;
Daniel Veillardcf461992000-03-14 18:30:20 +0000488 xmlChar *name = NULL, *prefix = NULL;
Daniel Veillard517752b1999-04-05 12:20:10 +0000489
490#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000491 xmlGenericError(xmlGenericErrorContext,
492 "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000493 elem, fullname, type, def, defaultValue);
Daniel Veillard517752b1999-04-05 12:20:10 +0000494#endif
Daniel Veillardcf461992000-03-14 18:30:20 +0000495 name = xmlSplitQName(ctxt, fullname, &prefix);
496 if (ctxt->inSubset == 1)
497 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
Daniel Veillard32bc74e2000-07-14 14:49:25 +0000498 name, prefix, (xmlAttributeType) type,
499 (xmlAttributeDefault) def, defaultValue, tree);
Daniel Veillardcf461992000-03-14 18:30:20 +0000500 else if (ctxt->inSubset == 2)
501 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
Daniel Veillard32bc74e2000-07-14 14:49:25 +0000502 name, prefix, (xmlAttributeType) type,
503 (xmlAttributeDefault) def, defaultValue, tree);
Daniel Veillardcf461992000-03-14 18:30:20 +0000504 else {
505 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
506 ctxt->sax->error(ctxt,
507 "SAX.attributeDecl(%s) called while not in subset\n", name);
508 return;
509 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000510 if (attr == 0) ctxt->valid = 0;
511 if (ctxt->validate && ctxt->wellFormed &&
512 ctxt->myDoc && ctxt->myDoc->intSubset)
513 ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
514 attr);
Daniel Veillardcf461992000-03-14 18:30:20 +0000515 if (prefix != NULL)
516 xmlFree(prefix);
517 if (name != NULL)
518 xmlFree(name);
Daniel Veillard517752b1999-04-05 12:20:10 +0000519}
520
521/**
522 * elementDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000523 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +0000524 * @name: the element name
525 * @type: the element type
Daniel Veillard06047432000-04-24 11:33:38 +0000526 * @content: the element value tree
Daniel Veillard517752b1999-04-05 12:20:10 +0000527 *
528 * An element definition has been parsed
529 */
530void
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000531elementDecl(void *ctx, const xmlChar *name, int type,
Daniel Veillard517752b1999-04-05 12:20:10 +0000532 xmlElementContentPtr content)
533{
Daniel Veillard27d88741999-05-29 11:51:49 +0000534 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillardcf461992000-03-14 18:30:20 +0000535 xmlElementPtr elem = NULL;
Daniel Veillard517752b1999-04-05 12:20:10 +0000536
537#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000538 xmlGenericError(xmlGenericErrorContext,
539 "SAX.elementDecl(%s, %d, ...)\n",
Daniel Veillardcf461992000-03-14 18:30:20 +0000540 fullname, type);
Daniel Veillard517752b1999-04-05 12:20:10 +0000541#endif
Daniel Veillardb05deb71999-08-10 19:04:08 +0000542
Daniel Veillardcf461992000-03-14 18:30:20 +0000543 if (ctxt->inSubset == 1)
544 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
Daniel Veillard32bc74e2000-07-14 14:49:25 +0000545 name, (xmlElementTypeVal) type, content);
Daniel Veillardcf461992000-03-14 18:30:20 +0000546 else if (ctxt->inSubset == 2)
547 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
Daniel Veillard32bc74e2000-07-14 14:49:25 +0000548 name, (xmlElementTypeVal) type, content);
Daniel Veillardcf461992000-03-14 18:30:20 +0000549 else {
550 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
551 ctxt->sax->error(ctxt,
552 "SAX.elementDecl(%s) called while not in subset\n", name);
553 return;
554 }
555 if (elem == NULL) ctxt->valid = 0;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000556 if (ctxt->validate && ctxt->wellFormed &&
557 ctxt->myDoc && ctxt->myDoc->intSubset)
558 ctxt->valid &= xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
Daniel Veillard517752b1999-04-05 12:20:10 +0000559}
560
561/**
Daniel Veillard97b58771998-10-20 06:14:16 +0000562 * notationDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000563 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000564 * @name: The name of the notation
565 * @publicId: The public ID of the entity
566 * @systemId: The system ID of the entity
567 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000568 * What to do when a notation declaration has been parsed.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000569 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000570void
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000571notationDecl(void *ctx, const xmlChar *name,
572 const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillard97b58771998-10-20 06:14:16 +0000573{
Daniel Veillard27d88741999-05-29 11:51:49 +0000574 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillardcf461992000-03-14 18:30:20 +0000575 xmlNotationPtr nota = NULL;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000576
Daniel Veillard260a68f1998-08-13 03:39:55 +0000577#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000578 xmlGenericError(xmlGenericErrorContext,
579 "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000580#endif
Daniel Veillardb05deb71999-08-10 19:04:08 +0000581
Daniel Veillardcf461992000-03-14 18:30:20 +0000582 if (ctxt->inSubset == 1)
583 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000584 publicId, systemId);
Daniel Veillardcf461992000-03-14 18:30:20 +0000585 else if (ctxt->inSubset == 2)
586 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
587 publicId, systemId);
588 else {
589 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
590 ctxt->sax->error(ctxt,
591 "SAX.notationDecl(%s) called while not in subset\n", name);
592 return;
593 }
594 if (nota == NULL) ctxt->valid = 0;
Daniel Veillardb05deb71999-08-10 19:04:08 +0000595 if (ctxt->validate && ctxt->wellFormed &&
596 ctxt->myDoc && ctxt->myDoc->intSubset)
597 ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
598 nota);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000599}
600
Daniel Veillard97b58771998-10-20 06:14:16 +0000601/**
602 * unparsedEntityDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000603 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000604 * @name: The name of the entity
605 * @publicId: The public ID of the entity
606 * @systemId: The system ID of the entity
607 * @notationName: the name of the notation
608 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000609 * What to do when an unparsed entity declaration is parsed
Daniel Veillard260a68f1998-08-13 03:39:55 +0000610 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000611void
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000612unparsedEntityDecl(void *ctx, const xmlChar *name,
613 const xmlChar *publicId, const xmlChar *systemId,
614 const xmlChar *notationName)
Daniel Veillard97b58771998-10-20 06:14:16 +0000615{
Daniel Veillardb96e6431999-08-29 21:02:19 +0000616 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000617#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000618 xmlGenericError(xmlGenericErrorContext,
619 "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
Daniel Veillard260a68f1998-08-13 03:39:55 +0000620 name, publicId, systemId, notationName);
621#endif
Daniel Veillardb96e6431999-08-29 21:02:19 +0000622 if (ctxt->validate && ctxt->wellFormed &&
623 ctxt->myDoc && ctxt->myDoc->intSubset)
624 ctxt->valid &= xmlValidateNotationUse(&ctxt->vctxt, ctxt->myDoc,
625 notationName);
626 xmlAddDocEntity(ctxt->myDoc, name,
627 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
628 publicId, systemId, notationName);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000629}
630
Daniel Veillard97b58771998-10-20 06:14:16 +0000631/**
632 * setDocumentLocator:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000633 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000634 * @loc: A SAX Locator
635 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000636 * Receive the document locator at startup, actually xmlDefaultSAXLocator
637 * Everything is available on the context, so this is useless in our case.
638 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000639void
Daniel Veillard27d88741999-05-29 11:51:49 +0000640setDocumentLocator(void *ctx, xmlSAXLocatorPtr loc)
Daniel Veillard97b58771998-10-20 06:14:16 +0000641{
Daniel Veillard27d88741999-05-29 11:51:49 +0000642 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillard260a68f1998-08-13 03:39:55 +0000643#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000644 xmlGenericError(xmlGenericErrorContext,
645 "SAX.setDocumentLocator()\n");
Daniel Veillard260a68f1998-08-13 03:39:55 +0000646#endif
647}
648
Daniel Veillard97b58771998-10-20 06:14:16 +0000649/**
650 * startDocument:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000651 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000652 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000653 * called when the document start being processed.
654 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000655void
Daniel Veillard27d88741999-05-29 11:51:49 +0000656startDocument(void *ctx)
Daniel Veillard97b58771998-10-20 06:14:16 +0000657{
Daniel Veillard27d88741999-05-29 11:51:49 +0000658 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000659 xmlDocPtr doc;
660
Daniel Veillard260a68f1998-08-13 03:39:55 +0000661#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000662 xmlGenericError(xmlGenericErrorContext,
663 "SAX.startDocument()\n");
Daniel Veillard260a68f1998-08-13 03:39:55 +0000664#endif
Daniel Veillard3f6f7f62000-06-30 17:58:25 +0000665 if (ctxt->html) {
666 if (ctxt->myDoc == NULL)
Daniel Veillard87b95392000-08-12 21:12:04 +0000667#ifdef LIBXML_HTML_ENABLED
Daniel Veillardb8f25c92000-08-19 19:52:36 +0000668 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
Daniel Veillard87b95392000-08-12 21:12:04 +0000669#else
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000670 xmlGenericError(xmlGenericErrorContext,
671 "libxml2 built without HTML support\n");
Daniel Veillard87b95392000-08-12 21:12:04 +0000672#endif
Daniel Veillard3f6f7f62000-06-30 17:58:25 +0000673 } else {
674 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
675 if (doc != NULL) {
676 if (ctxt->encoding != NULL)
677 doc->encoding = xmlStrdup(ctxt->encoding);
678 else
679 doc->encoding = NULL;
680 doc->standalone = ctxt->standalone;
681 }
Daniel Veillard517752b1999-04-05 12:20:10 +0000682 }
Daniel Veillard87b95392000-08-12 21:12:04 +0000683 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
684 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
685 ctxt->myDoc->URL = xmlStrdup((xmlChar *) ctxt->input->filename);
686 }
Daniel Veillard260a68f1998-08-13 03:39:55 +0000687}
688
Daniel Veillard97b58771998-10-20 06:14:16 +0000689/**
690 * endDocument:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000691 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +0000692 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000693 * called when the document end has been detected.
694 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000695void
Daniel Veillard27d88741999-05-29 11:51:49 +0000696endDocument(void *ctx)
Daniel Veillard97b58771998-10-20 06:14:16 +0000697{
Daniel Veillardc08a2c61999-09-08 21:35:25 +0000698 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000699#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000700 xmlGenericError(xmlGenericErrorContext,
701 "SAX.endDocument()\n");
Daniel Veillard260a68f1998-08-13 03:39:55 +0000702#endif
Daniel Veillardc08a2c61999-09-08 21:35:25 +0000703 if (ctxt->validate && ctxt->wellFormed &&
704 ctxt->myDoc && ctxt->myDoc->intSubset)
705 ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
Daniel Veillard496a1cf2000-05-03 14:20:55 +0000706
707 /*
708 * Grab the encoding if it was added on-the-fly
709 */
710 if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
711 (ctxt->myDoc->encoding == NULL)) {
712 ctxt->myDoc->encoding = ctxt->encoding;
713 ctxt->encoding = NULL;
714 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000715 if ((ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
716 (ctxt->myDoc->encoding == NULL)) {
717 ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
718 }
719 if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
720 (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
721 ctxt->myDoc->charset = ctxt->charset;
722 }
Daniel Veillard260a68f1998-08-13 03:39:55 +0000723}
724
Daniel Veillard97b58771998-10-20 06:14:16 +0000725/**
Daniel Veillard517752b1999-04-05 12:20:10 +0000726 * attribute:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000727 * @ctx: the user data (XML parser context)
Daniel Veillard06047432000-04-24 11:33:38 +0000728 * @fullname: The attribute name, including namespace prefix
Daniel Veillard517752b1999-04-05 12:20:10 +0000729 * @value: The attribute value
730 *
731 * Handle an attribute that has been read by the parser.
732 * The default handling is to convert the attribute into an
733 * DOM subtree and past it in a new xmlAttr element added to
734 * the element.
735 */
736void
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000737attribute(void *ctx, const xmlChar *fullname, const xmlChar *value)
Daniel Veillard517752b1999-04-05 12:20:10 +0000738{
Daniel Veillard27d88741999-05-29 11:51:49 +0000739 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000740 xmlAttrPtr ret;
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000741 xmlChar *name;
742 xmlChar *ns;
Daniel Veillardcf461992000-03-14 18:30:20 +0000743 xmlChar *nval;
Daniel Veillardb96e6431999-08-29 21:02:19 +0000744 xmlNsPtr namespace;
Daniel Veillard517752b1999-04-05 12:20:10 +0000745
746/****************
747#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000748 xmlGenericError(xmlGenericErrorContext,
749 "SAX.attribute(%s, %s)\n", fullname, value);
Daniel Veillard517752b1999-04-05 12:20:10 +0000750#endif
751 ****************/
752 /*
753 * Split the full name into a namespace prefix and the tag name
754 */
Daniel Veillardcf461992000-03-14 18:30:20 +0000755 name = xmlSplitQName(ctxt, fullname, &ns);
756
757 /*
Daniel Veillard47e12f22000-10-15 14:24:25 +0000758 * Do the last stage of the attribute normalization
759 * Needed for HTML too:
760 * http://www.w3.org/TR/html4/types.html#h-6.2
Daniel Veillardcf461992000-03-14 18:30:20 +0000761 */
Daniel Veillard47e12f22000-10-15 14:24:25 +0000762 nval = xmlValidNormalizeAttributeValue(ctxt->myDoc, ctxt->node,
763 fullname, value);
Daniel Veillardcf461992000-03-14 18:30:20 +0000764 if (nval != NULL)
765 value = nval;
Daniel Veillard517752b1999-04-05 12:20:10 +0000766
767 /*
768 * Check whether it's a namespace definition
769 */
Daniel Veillardbe803962000-06-28 23:40:59 +0000770 if ((!ctxt->html) && (ns == NULL) &&
Daniel Veillard517752b1999-04-05 12:20:10 +0000771 (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
772 (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
Daniel Veillardbe803962000-06-28 23:40:59 +0000773 xmlURIPtr uri;
774
775 uri = xmlParseURI((const char *)value);
776 if (uri == NULL) {
777 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
778 ctxt->sax->warning(ctxt->userData,
779 "nmlns: %s not a valid URI\n", value);
780 } else {
781 if (uri->scheme == NULL) {
782 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
783 ctxt->sax->warning(ctxt->userData,
784 "nmlns: URI %s is not absolute\n", value);
785 }
786 xmlFreeURI(uri);
787 }
788
Daniel Veillard517752b1999-04-05 12:20:10 +0000789 /* a default namespace definition */
790 xmlNewNs(ctxt->node, value, NULL);
791 if (name != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +0000792 xmlFree(name);
Daniel Veillardcf461992000-03-14 18:30:20 +0000793 if (nval != NULL)
794 xmlFree(nval);
Daniel Veillard517752b1999-04-05 12:20:10 +0000795 return;
796 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000797 if ((!ctxt->html) &&
798 (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
Daniel Veillard517752b1999-04-05 12:20:10 +0000799 (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
Daniel Veillardcf461992000-03-14 18:30:20 +0000800 /*
801 * Validate also for namespace decls, they are attributes from
802 * an XML-1.0 perspective
803 TODO ... doesn't map well with current API
804 if (ctxt->validate && ctxt->wellFormed &&
805 ctxt->myDoc && ctxt->myDoc->intSubset)
806 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
807 ctxt->node, ret, value);
808 */
Daniel Veillard517752b1999-04-05 12:20:10 +0000809 /* a standard namespace definition */
810 xmlNewNs(ctxt->node, value, name);
Daniel Veillard6454aec1999-09-02 22:04:43 +0000811 xmlFree(ns);
Daniel Veillard517752b1999-04-05 12:20:10 +0000812 if (name != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +0000813 xmlFree(name);
Daniel Veillardcf461992000-03-14 18:30:20 +0000814 if (nval != NULL)
815 xmlFree(nval);
Daniel Veillard517752b1999-04-05 12:20:10 +0000816 return;
817 }
818
Daniel Veillard5cb5ab81999-12-21 15:35:29 +0000819 if (ns != NULL)
820 namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
821 else {
822 namespace = NULL;
823 }
824
Daniel Veillardb96e6431999-08-29 21:02:19 +0000825 /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
826 ret = xmlNewNsProp(ctxt->node, namespace, name, NULL);
Daniel Veillardb05deb71999-08-10 19:04:08 +0000827
Daniel Veillardb96e6431999-08-29 21:02:19 +0000828 if (ret != NULL) {
Daniel Veillardcf461992000-03-14 18:30:20 +0000829 if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
830 xmlNodePtr tmp;
831
832 ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
833 tmp = ret->children;
834 while (tmp != NULL) {
835 tmp->parent = (xmlNodePtr) ret;
836 if (tmp->next == NULL)
837 ret->last = tmp;
838 tmp = tmp->next;
839 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000840 } else if (value != NULL) {
Daniel Veillardcf461992000-03-14 18:30:20 +0000841 ret->children = xmlNewDocText(ctxt->myDoc, value);
842 ret->last = ret->children;
843 if (ret->children != NULL)
844 ret->children->parent = (xmlNodePtr) ret;
845 }
Daniel Veillardb96e6431999-08-29 21:02:19 +0000846 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000847
Daniel Veillardbe803962000-06-28 23:40:59 +0000848 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
Daniel Veillardcf461992000-03-14 18:30:20 +0000849 ctxt->myDoc && ctxt->myDoc->intSubset) {
850
851 /*
852 * If we don't substitute entities, the validation should be
853 * done on a value with replaced entities anyway.
854 */
855 if (!ctxt->replaceEntities) {
856 xmlChar *val;
857
858 ctxt->depth++;
859 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
860 0,0,0);
861 ctxt->depth--;
862 if (val == NULL)
863 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
864 ctxt->myDoc, ctxt->node, ret, value);
865 else {
866 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
867 ctxt->myDoc, ctxt->node, ret, val);
868 xmlFree(val);
869 }
870 } else {
871 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
Daniel Veillardb05deb71999-08-10 19:04:08 +0000872 ctxt->node, ret, value);
Daniel Veillardcf461992000-03-14 18:30:20 +0000873 }
874 } else {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000875 /*
876 * when validating, the ID registration is done at the attribute
877 * validation level. Otherwise we have to do specific handling here.
878 */
879 if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
880 xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
Daniel Veillardc08a2c61999-09-08 21:35:25 +0000881 else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
882 xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000883 }
Daniel Veillardb05deb71999-08-10 19:04:08 +0000884
Daniel Veillardcf461992000-03-14 18:30:20 +0000885 if (nval != NULL)
886 xmlFree(nval);
Daniel Veillard517752b1999-04-05 12:20:10 +0000887 if (name != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +0000888 xmlFree(name);
Daniel Veillard517752b1999-04-05 12:20:10 +0000889 if (ns != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +0000890 xmlFree(ns);
Daniel Veillard517752b1999-04-05 12:20:10 +0000891}
892
893/**
Daniel Veillard97b58771998-10-20 06:14:16 +0000894 * startElement:
Daniel Veillard011b63c1999-06-02 17:44:04 +0000895 * @ctx: the user data (XML parser context)
Daniel Veillard06047432000-04-24 11:33:38 +0000896 * @fullname: The element name, including namespace prefix
Daniel Veillard517752b1999-04-05 12:20:10 +0000897 * @atts: An array of name/value attributes pairs, NULL terminated
Daniel Veillard97b58771998-10-20 06:14:16 +0000898 *
Daniel Veillard260a68f1998-08-13 03:39:55 +0000899 * called when an opening tag has been processed.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000900 */
Daniel Veillard97b58771998-10-20 06:14:16 +0000901void
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000902startElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
Daniel Veillard97b58771998-10-20 06:14:16 +0000903{
Daniel Veillard27d88741999-05-29 11:51:49 +0000904 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +0000905 xmlNodePtr ret;
906 xmlNodePtr parent = ctxt->node;
907 xmlNsPtr ns;
Daniel Veillarddd6b3671999-09-23 22:19:22 +0000908 xmlChar *name;
909 xmlChar *prefix;
910 const xmlChar *att;
911 const xmlChar *value;
Daniel Veillard517752b1999-04-05 12:20:10 +0000912 int i;
913
Daniel Veillard260a68f1998-08-13 03:39:55 +0000914#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000915 xmlGenericError(xmlGenericErrorContext,
916 "SAX.startElement(%s)\n", fullname);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000917#endif
Daniel Veillard7f7d1111999-09-22 09:46:25 +0000918
919 /*
920 * First check on validity:
921 */
922 if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
923 ((ctxt->myDoc->intSubset == NULL) ||
924 ((ctxt->myDoc->intSubset->notations == NULL) &&
925 (ctxt->myDoc->intSubset->elements == NULL) &&
926 (ctxt->myDoc->intSubset->attributes == NULL) &&
927 (ctxt->myDoc->intSubset->entities == NULL)))) {
928 if (ctxt->vctxt.error != NULL) {
929 ctxt->vctxt.error(ctxt->vctxt.userData,
930 "Validation failed: no DTD found !\n");
931 }
932 ctxt->validate = 0;
933 }
934
935
Daniel Veillard517752b1999-04-05 12:20:10 +0000936 /*
937 * Split the full name into a namespace prefix and the tag name
938 */
Daniel Veillardcf461992000-03-14 18:30:20 +0000939 name = xmlSplitQName(ctxt, fullname, &prefix);
Daniel Veillard517752b1999-04-05 12:20:10 +0000940
941
942 /*
943 * Note : the namespace resolution is deferred until the end of the
944 * attributes parsing, since local namespace can be defined as
945 * an attribute at this level.
946 */
947 ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
948 if (ret == NULL) return;
Daniel Veillardcf461992000-03-14 18:30:20 +0000949 if (ctxt->myDoc->children == NULL) {
Daniel Veillardb96e6431999-08-29 21:02:19 +0000950#ifdef DEBUG_SAX_TREE
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000951 xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000952#endif
Daniel Veillardcf461992000-03-14 18:30:20 +0000953 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000954 } else if (parent == NULL) {
Daniel Veillardcf461992000-03-14 18:30:20 +0000955 parent = ctxt->myDoc->children;
Daniel Veillardb96e6431999-08-29 21:02:19 +0000956 }
Daniel Veillardbe803962000-06-28 23:40:59 +0000957 ctxt->nodemem = -1;
Daniel Veillard517752b1999-04-05 12:20:10 +0000958
959 /*
960 * We are parsing a new node.
961 */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000962#ifdef DEBUG_SAX_TREE
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000963 xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000964#endif
Daniel Veillard517752b1999-04-05 12:20:10 +0000965 nodePush(ctxt, ret);
966
967 /*
968 * Link the child element
969 */
Daniel Veillardb96e6431999-08-29 21:02:19 +0000970 if (parent != NULL) {
971 if (parent->type == XML_ELEMENT_NODE) {
972#ifdef DEBUG_SAX_TREE
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000973 xmlGenericError(xmlGenericErrorContext,
974 "adding child %s to %s\n", name, parent->name);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000975#endif
976 xmlAddChild(parent, ret);
977 } else {
978#ifdef DEBUG_SAX_TREE
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000979 xmlGenericError(xmlGenericErrorContext,
980 "adding sibling %s to ", name);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000981 xmlDebugDumpOneNode(stderr, parent, 0);
982#endif
983 xmlAddSibling(parent, ret);
984 }
985 }
Daniel Veillard517752b1999-04-05 12:20:10 +0000986
987 /*
Daniel Veillardb96e6431999-08-29 21:02:19 +0000988 * process all the attributes whose name start with "xml"
Daniel Veillard517752b1999-04-05 12:20:10 +0000989 */
990 if (atts != NULL) {
991 i = 0;
992 att = atts[i++];
993 value = atts[i++];
Daniel Veillardbe803962000-06-28 23:40:59 +0000994 if (!ctxt->html) {
995 while ((att != NULL) && (value != NULL)) {
996 if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l'))
997 attribute(ctxt, att, value);
Daniel Veillardb96e6431999-08-29 21:02:19 +0000998
Daniel Veillardbe803962000-06-28 23:40:59 +0000999 att = atts[i++];
1000 value = atts[i++];
1001 }
Daniel Veillard517752b1999-04-05 12:20:10 +00001002 }
1003 }
1004
1005 /*
1006 * Search the namespace, note that since the attributes have been
1007 * processed, the local namespaces are available.
1008 */
1009 ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
1010 if ((ns == NULL) && (parent != NULL))
1011 ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
Daniel Veillarde0854c32000-08-27 21:12:29 +00001012 if ((prefix != NULL) && (ns == NULL)) {
1013 ns = xmlNewNs(ret, NULL, prefix);
1014 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
1015 ctxt->sax->warning(ctxt->userData,
1016 "Namespace prefix %s is not defined\n", prefix);
1017 }
Daniel Veillard517752b1999-04-05 12:20:10 +00001018 xmlSetNs(ret, ns);
1019
Daniel Veillardbe803962000-06-28 23:40:59 +00001020 /*
1021 * process all the other attributes
1022 */
1023 if (atts != NULL) {
1024 i = 0;
1025 att = atts[i++];
1026 value = atts[i++];
1027 if (ctxt->html) {
1028 while (att != NULL) {
1029 attribute(ctxt, att, value);
1030 att = atts[i++];
1031 value = atts[i++];
1032 }
1033 } else {
1034 while ((att != NULL) && (value != NULL)) {
1035 if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l'))
1036 attribute(ctxt, att, value);
1037
1038 /*
1039 * Next ones
1040 */
1041 att = atts[i++];
1042 value = atts[i++];
1043 }
1044 }
1045 }
1046
1047 /*
1048 * If it's the Document root, finish the Dtd validation and
1049 * check the document root element for validity
1050 */
1051 if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) {
1052 ctxt->valid &= xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
1053 ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
1054 ctxt->vctxt.finishDtd = 1;
1055 }
1056
Daniel Veillard517752b1999-04-05 12:20:10 +00001057 if (prefix != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +00001058 xmlFree(prefix);
Daniel Veillard517752b1999-04-05 12:20:10 +00001059 if (name != NULL)
Daniel Veillard6454aec1999-09-02 22:04:43 +00001060 xmlFree(name);
Daniel Veillard517752b1999-04-05 12:20:10 +00001061
Daniel Veillard260a68f1998-08-13 03:39:55 +00001062}
1063
Daniel Veillard97b58771998-10-20 06:14:16 +00001064/**
1065 * endElement:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001066 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +00001067 * @name: The element name
1068 *
Daniel Veillard260a68f1998-08-13 03:39:55 +00001069 * called when the end of an element has been detected.
1070 */
Daniel Veillard97b58771998-10-20 06:14:16 +00001071void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001072endElement(void *ctx, const xmlChar *name)
Daniel Veillard97b58771998-10-20 06:14:16 +00001073{
Daniel Veillard27d88741999-05-29 11:51:49 +00001074 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001075 xmlParserNodeInfo node_info;
1076 xmlNodePtr cur = ctxt->node;
1077
Daniel Veillard260a68f1998-08-13 03:39:55 +00001078#ifdef DEBUG_SAX
Daniel Veillard517752b1999-04-05 12:20:10 +00001079 if (name == NULL)
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001080 xmlGenericError(xmlGenericErrorContext, "SAX.endElement(NULL)\n");
Daniel Veillard517752b1999-04-05 12:20:10 +00001081 else
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001082 xmlGenericError(xmlGenericErrorContext, "SAX.endElement(%s)\n", name);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001083#endif
Daniel Veillard517752b1999-04-05 12:20:10 +00001084
1085 /* Capture end position and add node */
1086 if (cur != NULL && ctxt->record_info) {
1087 node_info.end_pos = ctxt->input->cur - ctxt->input->base;
1088 node_info.end_line = ctxt->input->line;
1089 node_info.node = cur;
1090 xmlParserAddNodeInfo(ctxt, &node_info);
1091 }
Daniel Veillardbe803962000-06-28 23:40:59 +00001092 ctxt->nodemem = -1;
Daniel Veillard517752b1999-04-05 12:20:10 +00001093
Daniel Veillardb05deb71999-08-10 19:04:08 +00001094 if (ctxt->validate && ctxt->wellFormed &&
1095 ctxt->myDoc && ctxt->myDoc->intSubset)
1096 ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
1097 cur);
1098
1099
Daniel Veillard517752b1999-04-05 12:20:10 +00001100 /*
1101 * end of parsing of this node.
1102 */
Daniel Veillardb96e6431999-08-29 21:02:19 +00001103#ifdef DEBUG_SAX_TREE
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001104 xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001105#endif
Daniel Veillard517752b1999-04-05 12:20:10 +00001106 nodePop(ctxt);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001107}
1108
Daniel Veillard97b58771998-10-20 06:14:16 +00001109/**
Daniel Veillard517752b1999-04-05 12:20:10 +00001110 * reference:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001111 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001112 * @name: The entity name
Daniel Veillard11e00581998-10-24 18:27:49 +00001113 *
Daniel Veillard517752b1999-04-05 12:20:10 +00001114 * called when an entity reference is detected.
Daniel Veillard11e00581998-10-24 18:27:49 +00001115 */
1116void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001117reference(void *ctx, const xmlChar *name)
Daniel Veillard11e00581998-10-24 18:27:49 +00001118{
Daniel Veillard27d88741999-05-29 11:51:49 +00001119 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001120 xmlNodePtr ret;
1121
Daniel Veillard11e00581998-10-24 18:27:49 +00001122#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001123 xmlGenericError(xmlGenericErrorContext,
1124 "SAX.reference(%s)\n", name);
Daniel Veillard11e00581998-10-24 18:27:49 +00001125#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001126 if (name[0] == '#')
1127 ret = xmlNewCharRef(ctxt->myDoc, name);
1128 else
1129 ret = xmlNewReference(ctxt->myDoc, name);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001130#ifdef DEBUG_SAX_TREE
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001131 xmlGenericError(xmlGenericErrorContext,
1132 "add reference %s to %s \n", name, ctxt->node->name);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001133#endif
Daniel Veillard517752b1999-04-05 12:20:10 +00001134 xmlAddChild(ctxt->node, ret);
Daniel Veillard11e00581998-10-24 18:27:49 +00001135}
1136
1137/**
Daniel Veillard97b58771998-10-20 06:14:16 +00001138 * characters:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001139 * @ctx: the user data (XML parser context)
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001140 * @ch: a xmlChar string
1141 * @len: the number of xmlChar
Daniel Veillard97b58771998-10-20 06:14:16 +00001142 *
Daniel Veillard260a68f1998-08-13 03:39:55 +00001143 * receiving some chars from the parser.
1144 * Question: how much at a time ???
1145 */
Daniel Veillard97b58771998-10-20 06:14:16 +00001146void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001147characters(void *ctx, const xmlChar *ch, int len)
Daniel Veillard97b58771998-10-20 06:14:16 +00001148{
Daniel Veillard27d88741999-05-29 11:51:49 +00001149 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001150 xmlNodePtr lastChild;
1151
1152#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001153 xmlGenericError(xmlGenericErrorContext,
1154 "SAX.characters(%.30s, %d)\n", ch, len);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001155#endif
1156 /*
1157 * Handle the data if any. If there is no child
1158 * add it as content, otherwise if the last child is text,
1159 * concatenate it, else create a new node of type text.
1160 */
1161
Daniel Veillard35008381999-10-25 13:15:52 +00001162 if (ctxt->node == NULL) {
1163#ifdef DEBUG_SAX_TREE
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001164 xmlGenericError(xmlGenericErrorContext,
1165 "add chars: ctxt->node == NULL !\n");
Daniel Veillard35008381999-10-25 13:15:52 +00001166#endif
1167 return;
1168 }
Daniel Veillard260a68f1998-08-13 03:39:55 +00001169 lastChild = xmlGetLastChild(ctxt->node);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001170#ifdef DEBUG_SAX_TREE
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001171 xmlGenericError(xmlGenericErrorContext,
1172 "add chars to %s \n", ctxt->node->name);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001173#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00001174
1175 /*
1176 * Here we needed an accelerator mechanism in case of very large
1177 * elements. Use an attribute in the structure !!!
1178 */
1179 if (lastChild == NULL) {
1180 /* first node, first time */
Daniel Veillard517752b1999-04-05 12:20:10 +00001181 xmlNodeAddContentLen(ctxt->node, ch, len);
Daniel Veillardbe803962000-06-28 23:40:59 +00001182#ifndef XML_USE_BUFFER_CONTENT
1183 if (ctxt->node->children != NULL) {
1184 ctxt->nodelen = len;
1185 ctxt->nodemem = len + 1;
1186 }
1187#endif
1188 } else {
Daniel Veillarde0854c32000-08-27 21:12:29 +00001189 if ((xmlNodeIsText(lastChild)) && (ctxt->nodemem != 0)) {
Daniel Veillardbe803962000-06-28 23:40:59 +00001190#ifndef XML_USE_BUFFER_CONTENT
1191 /*
1192 * The whole point of maintaining nodelen and nodemem,
1193 * xmlTextConcat is too costly, i.e. compute lenght,
1194 * reallocate a new buffer, move data, append ch. Here
1195 * We try to minimaze realloc() uses and avoid copying
1196 * and recomputing lenght over and over.
1197 */
1198 if (ctxt->nodelen + len >= ctxt->nodemem) {
1199 xmlChar *newbuf;
1200 int size;
1201
1202 size = ctxt->nodemem + len;
1203 size *= 2;
1204 newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
1205 if (newbuf == NULL) {
1206 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1207 ctxt->sax->error(ctxt->userData,
1208 "SAX.characters(): out of memory\n");
1209 return;
1210 }
1211 ctxt->nodemem = size;
1212 lastChild->content = newbuf;
1213 }
1214 memcpy(&lastChild->content[ctxt->nodelen], ch, len);
1215 ctxt->nodelen += len;
1216 lastChild->content[ctxt->nodelen] = 0;
1217#else
Daniel Veillard517752b1999-04-05 12:20:10 +00001218 xmlTextConcat(lastChild, ch, len);
Daniel Veillardbe803962000-06-28 23:40:59 +00001219#endif
1220 } else {
1221 /* Mixed content, first time */
Daniel Veillard517752b1999-04-05 12:20:10 +00001222 lastChild = xmlNewTextLen(ch, len);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001223 xmlAddChild(ctxt->node, lastChild);
Daniel Veillardbe803962000-06-28 23:40:59 +00001224#ifndef XML_USE_BUFFER_CONTENT
1225 if (ctxt->node->children != NULL) {
1226 ctxt->nodelen = len;
1227 ctxt->nodemem = len + 1;
1228 }
1229#endif
Daniel Veillard260a68f1998-08-13 03:39:55 +00001230 }
1231 }
1232}
1233
Daniel Veillard97b58771998-10-20 06:14:16 +00001234/**
1235 * ignorableWhitespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001236 * @ctx: the user data (XML parser context)
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001237 * @ch: a xmlChar string
1238 * @len: the number of xmlChar
Daniel Veillard97b58771998-10-20 06:14:16 +00001239 *
Daniel Veillard260a68f1998-08-13 03:39:55 +00001240 * receiving some ignorable whitespaces from the parser.
1241 * Question: how much at a time ???
1242 */
Daniel Veillard97b58771998-10-20 06:14:16 +00001243void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001244ignorableWhitespace(void *ctx, const xmlChar *ch, int len)
Daniel Veillard97b58771998-10-20 06:14:16 +00001245{
Daniel Veillard27d88741999-05-29 11:51:49 +00001246 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
Daniel Veillard260a68f1998-08-13 03:39:55 +00001247#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001248 xmlGenericError(xmlGenericErrorContext,
1249 "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001250#endif
1251}
1252
Daniel Veillard97b58771998-10-20 06:14:16 +00001253/**
1254 * processingInstruction:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001255 * @ctx: the user data (XML parser context)
Daniel Veillard97b58771998-10-20 06:14:16 +00001256 * @target: the target name
1257 * @data: the PI data's
Daniel Veillard97b58771998-10-20 06:14:16 +00001258 *
1259 * A processing instruction has been parsed.
Daniel Veillard260a68f1998-08-13 03:39:55 +00001260 */
Daniel Veillard97b58771998-10-20 06:14:16 +00001261void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001262processingInstruction(void *ctx, const xmlChar *target,
1263 const xmlChar *data)
Daniel Veillard97b58771998-10-20 06:14:16 +00001264{
Daniel Veillardb96e6431999-08-29 21:02:19 +00001265 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1266 xmlNodePtr ret;
1267 xmlNodePtr parent = ctxt->node;
1268
Daniel Veillard260a68f1998-08-13 03:39:55 +00001269#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001270 xmlGenericError(xmlGenericErrorContext,
1271 "SAX.processingInstruction(%s, %s)\n", target, data);
Daniel Veillard260a68f1998-08-13 03:39:55 +00001272#endif
Daniel Veillardb96e6431999-08-29 21:02:19 +00001273
1274 ret = xmlNewPI(target, data);
1275 if (ret == NULL) return;
Daniel Veillardcf461992000-03-14 18:30:20 +00001276 parent = ctxt->node;
1277
1278 if (ctxt->inSubset == 1) {
1279 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
1280 return;
1281 } else if (ctxt->inSubset == 2) {
1282 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
1283 return;
1284 }
1285 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001286#ifdef DEBUG_SAX_TREE
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001287 xmlGenericError(xmlGenericErrorContext,
1288 "Setting PI %s as root\n", target);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001289#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001290 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1291 return;
Daniel Veillardb96e6431999-08-29 21:02:19 +00001292 }
Daniel Veillardcf461992000-03-14 18:30:20 +00001293 if (parent->type == XML_ELEMENT_NODE) {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001294#ifdef DEBUG_SAX_TREE
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001295 xmlGenericError(xmlGenericErrorContext,
1296 "adding PI %s child to %s\n", target, parent->name);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001297#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001298 xmlAddChild(parent, ret);
1299 } else {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001300#ifdef DEBUG_SAX_TREE
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001301 xmlGenericError(xmlGenericErrorContext,
1302 "adding PI %s sibling to ", target);
Daniel Veillardcf461992000-03-14 18:30:20 +00001303 xmlDebugDumpOneNode(stderr, parent, 0);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001304#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001305 xmlAddSibling(parent, ret);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001306 }
Daniel Veillard260a68f1998-08-13 03:39:55 +00001307}
1308
Daniel Veillard517752b1999-04-05 12:20:10 +00001309/**
1310 * globalNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001311 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001312 * @href: the namespace associated URN
1313 * @prefix: the namespace prefix
1314 *
1315 * An old global namespace has been parsed.
1316 */
1317void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001318globalNamespace(void *ctx, const xmlChar *href, const xmlChar *prefix)
Daniel Veillard517752b1999-04-05 12:20:10 +00001319{
Daniel Veillard27d88741999-05-29 11:51:49 +00001320 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001321#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001322 xmlGenericError(xmlGenericErrorContext,
1323 "SAX.globalNamespace(%s, %s)\n", href, prefix);
Daniel Veillard517752b1999-04-05 12:20:10 +00001324#endif
1325 xmlNewGlobalNs(ctxt->myDoc, href, prefix);
1326}
1327
1328/**
1329 * setNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001330 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001331 * @name: the namespace prefix
1332 *
1333 * Set the current element namespace.
1334 */
Daniel Veillard06047432000-04-24 11:33:38 +00001335
Daniel Veillard517752b1999-04-05 12:20:10 +00001336void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001337setNamespace(void *ctx, const xmlChar *name)
Daniel Veillard517752b1999-04-05 12:20:10 +00001338{
Daniel Veillard27d88741999-05-29 11:51:49 +00001339 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001340 xmlNsPtr ns;
1341 xmlNodePtr parent;
1342
1343#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001344 xmlGenericError(xmlGenericErrorContext, "SAX.setNamespace(%s)\n", name);
Daniel Veillard517752b1999-04-05 12:20:10 +00001345#endif
1346 ns = xmlSearchNs(ctxt->myDoc, ctxt->node, name);
1347 if (ns == NULL) { /* ctxt->node may not have a parent yet ! */
1348 if (ctxt->nodeNr >= 2) {
1349 parent = ctxt->nodeTab[ctxt->nodeNr - 2];
1350 if (parent != NULL)
1351 ns = xmlSearchNs(ctxt->myDoc, parent, name);
1352 }
1353 }
1354 xmlSetNs(ctxt->node, ns);
1355}
1356
1357/**
1358 * getNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001359 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001360 *
1361 * Get the current element namespace.
Daniel Veillard06047432000-04-24 11:33:38 +00001362 *
1363 * Returns the xmlNsPtr or NULL if none
Daniel Veillard517752b1999-04-05 12:20:10 +00001364 */
Daniel Veillard06047432000-04-24 11:33:38 +00001365
Daniel Veillard517752b1999-04-05 12:20:10 +00001366xmlNsPtr
Daniel Veillard27d88741999-05-29 11:51:49 +00001367getNamespace(void *ctx)
Daniel Veillard517752b1999-04-05 12:20:10 +00001368{
Daniel Veillard27d88741999-05-29 11:51:49 +00001369 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001370 xmlNsPtr ret;
1371
1372#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001373 xmlGenericError(xmlGenericErrorContext, "SAX.getNamespace()\n");
Daniel Veillard517752b1999-04-05 12:20:10 +00001374#endif
1375 ret = ctxt->node->ns;
1376 return(ret);
1377}
1378
1379/**
1380 * checkNamespace:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001381 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001382 * @namespace: the namespace to check against
1383 *
1384 * Check that the current element namespace is the same as the
1385 * one read upon parsing.
Daniel Veillard06047432000-04-24 11:33:38 +00001386 *
1387 * Returns 1 if true 0 otherwise
Daniel Veillard517752b1999-04-05 12:20:10 +00001388 */
Daniel Veillard06047432000-04-24 11:33:38 +00001389
Daniel Veillard517752b1999-04-05 12:20:10 +00001390int
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001391checkNamespace(void *ctx, xmlChar *namespace)
Daniel Veillard517752b1999-04-05 12:20:10 +00001392{
Daniel Veillard27d88741999-05-29 11:51:49 +00001393 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001394 xmlNodePtr cur = ctxt->node;
1395
1396#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001397 xmlGenericError(xmlGenericErrorContext,
1398 "SAX.checkNamespace(%s)\n", namespace);
Daniel Veillard517752b1999-04-05 12:20:10 +00001399#endif
1400
1401 /*
1402 * Check that the Name in the ETag is the same as in the STag.
1403 */
1404 if (namespace == NULL) {
1405 if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
1406 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1407 ctxt->sax->error(ctxt,
1408 "End tags for %s don't hold the namespace %s\n",
1409 cur->name, cur->ns->prefix);
1410 ctxt->wellFormed = 0;
1411 }
1412 } else {
1413 if ((cur->ns == NULL) || (cur->ns->prefix == NULL)) {
1414 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1415 ctxt->sax->error(ctxt,
1416 "End tags %s holds a prefix %s not used by the open tag\n",
1417 cur->name, namespace);
1418 ctxt->wellFormed = 0;
Daniel Veillard8b5dd832000-10-01 20:28:44 +00001419 } else if (!xmlStrEqual(namespace, cur->ns->prefix)) {
Daniel Veillard517752b1999-04-05 12:20:10 +00001420 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1421 ctxt->sax->error(ctxt,
1422 "Start and End tags for %s don't use the same namespaces: %s and %s\n",
1423 cur->name, cur->ns->prefix, namespace);
1424 ctxt->wellFormed = 0;
1425 } else
1426 return(1);
1427 }
1428 return(0);
1429}
1430
1431/**
1432 * namespaceDecl:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001433 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001434 * @href: the namespace associated URN
1435 * @prefix: the namespace prefix
1436 *
1437 * A namespace has been parsed.
1438 */
1439void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001440namespaceDecl(void *ctx, const xmlChar *href, const xmlChar *prefix)
Daniel Veillard517752b1999-04-05 12:20:10 +00001441{
Daniel Veillard27d88741999-05-29 11:51:49 +00001442 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard517752b1999-04-05 12:20:10 +00001443#ifdef DEBUG_SAX
1444 if (prefix == NULL)
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001445 xmlGenericError(xmlGenericErrorContext,
1446 "SAX.namespaceDecl(%s, NULL)\n", href);
Daniel Veillard517752b1999-04-05 12:20:10 +00001447 else
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001448 xmlGenericError(xmlGenericErrorContext,
1449 "SAX.namespaceDecl(%s, %s)\n", href, prefix);
Daniel Veillard517752b1999-04-05 12:20:10 +00001450#endif
1451 xmlNewNs(ctxt->node, href, prefix);
1452}
1453
1454/**
1455 * comment:
Daniel Veillard011b63c1999-06-02 17:44:04 +00001456 * @ctx: the user data (XML parser context)
Daniel Veillard517752b1999-04-05 12:20:10 +00001457 * @value: the comment content
1458 *
1459 * A comment has been parsed.
1460 */
1461void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001462comment(void *ctx, const xmlChar *value)
Daniel Veillard517752b1999-04-05 12:20:10 +00001463{
Daniel Veillard27d88741999-05-29 11:51:49 +00001464 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillard14fff061999-06-22 21:49:07 +00001465 xmlNodePtr ret;
Daniel Veillardb96e6431999-08-29 21:02:19 +00001466 xmlNodePtr parent = ctxt->node;
Daniel Veillard14fff061999-06-22 21:49:07 +00001467
Daniel Veillard517752b1999-04-05 12:20:10 +00001468#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001469 xmlGenericError(xmlGenericErrorContext, "SAX.comment(%s)\n", value);
Daniel Veillard517752b1999-04-05 12:20:10 +00001470#endif
Daniel Veillard14fff061999-06-22 21:49:07 +00001471 ret = xmlNewDocComment(ctxt->myDoc, value);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001472 if (ret == NULL) return;
1473
Daniel Veillardcf461992000-03-14 18:30:20 +00001474 if (ctxt->inSubset == 1) {
1475 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
1476 return;
1477 } else if (ctxt->inSubset == 2) {
1478 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
1479 return;
1480 }
1481 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001482#ifdef DEBUG_SAX_TREE
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001483 xmlGenericError(xmlGenericErrorContext,
1484 "Setting comment as root\n");
Daniel Veillardb96e6431999-08-29 21:02:19 +00001485#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001486 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1487 return;
Daniel Veillardb96e6431999-08-29 21:02:19 +00001488 }
Daniel Veillardcf461992000-03-14 18:30:20 +00001489 if (parent->type == XML_ELEMENT_NODE) {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001490#ifdef DEBUG_SAX_TREE
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001491 xmlGenericError(xmlGenericErrorContext,
1492 "adding comment child to %s\n", parent->name);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001493#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001494 xmlAddChild(parent, ret);
1495 } else {
Daniel Veillardb96e6431999-08-29 21:02:19 +00001496#ifdef DEBUG_SAX_TREE
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001497 xmlGenericError(xmlGenericErrorContext,
1498 "adding comment sibling to ");
Daniel Veillardcf461992000-03-14 18:30:20 +00001499 xmlDebugDumpOneNode(stderr, parent, 0);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001500#endif
Daniel Veillardcf461992000-03-14 18:30:20 +00001501 xmlAddSibling(parent, ret);
Daniel Veillardb96e6431999-08-29 21:02:19 +00001502 }
Daniel Veillardb05deb71999-08-10 19:04:08 +00001503}
1504
1505/**
1506 * cdataBlock:
1507 * @ctx: the user data (XML parser context)
1508 * @value: The pcdata content
1509 * @len: the block length
1510 *
1511 * called when a pcdata block has been parsed
1512 */
1513void
Daniel Veillarddd6b3671999-09-23 22:19:22 +00001514cdataBlock(void *ctx, const xmlChar *value, int len)
Daniel Veillardb05deb71999-08-10 19:04:08 +00001515{
1516 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001517 xmlNodePtr ret, lastChild;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001518
1519#ifdef DEBUG_SAX
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001520 xmlGenericError(xmlGenericErrorContext,
1521 "SAX.pcdata(%.10s, %d)\n", value, len);
Daniel Veillardb05deb71999-08-10 19:04:08 +00001522#endif
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001523 lastChild = xmlGetLastChild(ctxt->node);
1524#ifdef DEBUG_SAX_TREE
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001525 xmlGenericError(xmlGenericErrorContext,
1526 "add chars to %s \n", ctxt->node->name);
Daniel Veillarddbfd6411999-12-28 16:35:14 +00001527#endif
1528 if ((lastChild != NULL) &&
1529 (lastChild->type == XML_CDATA_SECTION_NODE)) {
1530 xmlTextConcat(lastChild, value, len);
1531 } else {
1532 ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
1533 xmlAddChild(ctxt->node, ret);
1534 }
Daniel Veillard517752b1999-04-05 12:20:10 +00001535}
1536
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001537/*
1538 * Default handler for XML, builds the DOM tree
1539 */
Daniel Veillard260a68f1998-08-13 03:39:55 +00001540xmlSAXHandler xmlDefaultSAXHandler = {
Daniel Veillard517752b1999-04-05 12:20:10 +00001541 internalSubset,
1542 isStandalone,
1543 hasInternalSubset,
1544 hasExternalSubset,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001545 resolveEntity,
Daniel Veillard517752b1999-04-05 12:20:10 +00001546 getEntity,
1547 entityDecl,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001548 notationDecl,
Daniel Veillard517752b1999-04-05 12:20:10 +00001549 attributeDecl,
1550 elementDecl,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001551 unparsedEntityDecl,
1552 setDocumentLocator,
1553 startDocument,
1554 endDocument,
1555 startElement,
1556 endElement,
Daniel Veillard517752b1999-04-05 12:20:10 +00001557 reference,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001558 characters,
1559 ignorableWhitespace,
1560 processingInstruction,
Daniel Veillard517752b1999-04-05 12:20:10 +00001561 comment,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001562 xmlParserWarning,
1563 xmlParserError,
1564 xmlParserError,
Daniel Veillardb05deb71999-08-10 19:04:08 +00001565 getParameterEntity,
1566 cdataBlock,
Daniel Veillardcf461992000-03-14 18:30:20 +00001567 externalSubset,
Daniel Veillard260a68f1998-08-13 03:39:55 +00001568};
1569
Daniel Veillard97b58771998-10-20 06:14:16 +00001570/**
1571 * xmlDefaultSAXHandlerInit:
1572 *
1573 * Initialize the default SAX handler
Daniel Veillard97b58771998-10-20 06:14:16 +00001574 */
1575void
1576xmlDefaultSAXHandlerInit(void)
1577{
Daniel Veillard517752b1999-04-05 12:20:10 +00001578 xmlDefaultSAXHandler.internalSubset = internalSubset;
Daniel Veillardcf461992000-03-14 18:30:20 +00001579 xmlDefaultSAXHandler.externalSubset = externalSubset;
Daniel Veillard517752b1999-04-05 12:20:10 +00001580 xmlDefaultSAXHandler.isStandalone = isStandalone;
1581 xmlDefaultSAXHandler.hasInternalSubset = hasInternalSubset;
1582 xmlDefaultSAXHandler.hasExternalSubset = hasExternalSubset;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001583 xmlDefaultSAXHandler.resolveEntity = resolveEntity;
Daniel Veillard517752b1999-04-05 12:20:10 +00001584 xmlDefaultSAXHandler.getEntity = getEntity;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001585 xmlDefaultSAXHandler.getParameterEntity = getParameterEntity;
Daniel Veillard517752b1999-04-05 12:20:10 +00001586 xmlDefaultSAXHandler.entityDecl = entityDecl;
1587 xmlDefaultSAXHandler.attributeDecl = attributeDecl;
1588 xmlDefaultSAXHandler.elementDecl = elementDecl;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001589 xmlDefaultSAXHandler.notationDecl = notationDecl;
1590 xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
1591 xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1592 xmlDefaultSAXHandler.startDocument = startDocument;
1593 xmlDefaultSAXHandler.endDocument = endDocument;
1594 xmlDefaultSAXHandler.startElement = startElement;
1595 xmlDefaultSAXHandler.endElement = endElement;
Daniel Veillard517752b1999-04-05 12:20:10 +00001596 xmlDefaultSAXHandler.reference = reference;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001597 xmlDefaultSAXHandler.characters = characters;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001598 xmlDefaultSAXHandler.cdataBlock = cdataBlock;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001599 xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1600 xmlDefaultSAXHandler.processingInstruction = processingInstruction;
Daniel Veillard517752b1999-04-05 12:20:10 +00001601 xmlDefaultSAXHandler.comment = comment;
Daniel Veillardcf461992000-03-14 18:30:20 +00001602 if (xmlGetWarningsDefaultValue == 0)
1603 xmlDefaultSAXHandler.warning = NULL;
1604 else
1605 xmlDefaultSAXHandler.warning = xmlParserWarning;
Daniel Veillard260a68f1998-08-13 03:39:55 +00001606 xmlDefaultSAXHandler.error = xmlParserError;
1607 xmlDefaultSAXHandler.fatalError = xmlParserError;
1608}
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001609
1610/*
1611 * Default handler for HTML, builds the DOM tree
1612 */
1613xmlSAXHandler htmlDefaultSAXHandler = {
Daniel Veillardd83eb822000-06-30 18:39:56 +00001614 internalSubset,
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001615 NULL,
1616 NULL,
1617 NULL,
1618 NULL,
1619 getEntity,
1620 NULL,
1621 NULL,
1622 NULL,
1623 NULL,
1624 NULL,
1625 setDocumentLocator,
1626 startDocument,
1627 endDocument,
1628 startElement,
1629 endElement,
1630 NULL,
1631 characters,
1632 ignorableWhitespace,
1633 NULL,
1634 comment,
1635 xmlParserWarning,
1636 xmlParserError,
1637 xmlParserError,
Daniel Veillardb05deb71999-08-10 19:04:08 +00001638 getParameterEntity,
Daniel Veillard7eda8452000-10-14 23:38:43 +00001639 cdataBlock,
Daniel Veillardcf461992000-03-14 18:30:20 +00001640 NULL,
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001641};
1642
1643/**
1644 * htmlDefaultSAXHandlerInit:
1645 *
1646 * Initialize the default SAX handler
1647 */
1648void
1649htmlDefaultSAXHandlerInit(void)
1650{
Daniel Veillardd83eb822000-06-30 18:39:56 +00001651 htmlDefaultSAXHandler.internalSubset = internalSubset;
Daniel Veillardcf461992000-03-14 18:30:20 +00001652 htmlDefaultSAXHandler.externalSubset = NULL;
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001653 htmlDefaultSAXHandler.isStandalone = NULL;
1654 htmlDefaultSAXHandler.hasInternalSubset = NULL;
1655 htmlDefaultSAXHandler.hasExternalSubset = NULL;
1656 htmlDefaultSAXHandler.resolveEntity = NULL;
1657 htmlDefaultSAXHandler.getEntity = getEntity;
Daniel Veillardb05deb71999-08-10 19:04:08 +00001658 htmlDefaultSAXHandler.getParameterEntity = NULL;
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001659 htmlDefaultSAXHandler.entityDecl = NULL;
1660 htmlDefaultSAXHandler.attributeDecl = NULL;
1661 htmlDefaultSAXHandler.elementDecl = NULL;
1662 htmlDefaultSAXHandler.notationDecl = NULL;
1663 htmlDefaultSAXHandler.unparsedEntityDecl = NULL;
1664 htmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1665 htmlDefaultSAXHandler.startDocument = startDocument;
1666 htmlDefaultSAXHandler.endDocument = endDocument;
1667 htmlDefaultSAXHandler.startElement = startElement;
1668 htmlDefaultSAXHandler.endElement = endElement;
1669 htmlDefaultSAXHandler.reference = NULL;
1670 htmlDefaultSAXHandler.characters = characters;
Daniel Veillardbf432752000-11-12 15:56:56 +00001671 htmlDefaultSAXHandler.cdataBlock = cdataBlock;
Daniel Veillardbe70ff71999-07-05 16:50:46 +00001672 htmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1673 htmlDefaultSAXHandler.processingInstruction = NULL;
1674 htmlDefaultSAXHandler.comment = comment;
1675 htmlDefaultSAXHandler.warning = xmlParserWarning;
1676 htmlDefaultSAXHandler.error = xmlParserError;
1677 htmlDefaultSAXHandler.fatalError = xmlParserError;
1678}
Daniel Veillard39c7d712000-09-10 16:14:55 +00001679
1680/*
1681 * Default handler for HTML, builds the DOM tree
1682 */
1683xmlSAXHandler sgmlDefaultSAXHandler = {
1684 internalSubset,
1685 NULL,
1686 NULL,
1687 NULL,
1688 NULL,
1689 getEntity,
1690 NULL,
1691 NULL,
1692 NULL,
1693 NULL,
1694 NULL,
1695 setDocumentLocator,
1696 startDocument,
1697 endDocument,
1698 startElement,
1699 endElement,
1700 NULL,
1701 characters,
1702 ignorableWhitespace,
1703 NULL,
1704 comment,
1705 xmlParserWarning,
1706 xmlParserError,
1707 xmlParserError,
1708 getParameterEntity,
1709 NULL,
1710 NULL,
1711};
1712
1713/**
1714 * sgmlDefaultSAXHandlerInit:
1715 *
1716 * Initialize the default SAX handler
1717 */
1718void
1719sgmlDefaultSAXHandlerInit(void)
1720{
1721 sgmlDefaultSAXHandler.internalSubset = internalSubset;
1722 sgmlDefaultSAXHandler.externalSubset = NULL;
1723 sgmlDefaultSAXHandler.isStandalone = NULL;
1724 sgmlDefaultSAXHandler.hasInternalSubset = NULL;
1725 sgmlDefaultSAXHandler.hasExternalSubset = NULL;
1726 sgmlDefaultSAXHandler.resolveEntity = NULL;
1727 sgmlDefaultSAXHandler.getEntity = getEntity;
1728 sgmlDefaultSAXHandler.getParameterEntity = NULL;
1729 sgmlDefaultSAXHandler.entityDecl = NULL;
1730 sgmlDefaultSAXHandler.attributeDecl = NULL;
1731 sgmlDefaultSAXHandler.elementDecl = NULL;
1732 sgmlDefaultSAXHandler.notationDecl = NULL;
1733 sgmlDefaultSAXHandler.unparsedEntityDecl = NULL;
1734 sgmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1735 sgmlDefaultSAXHandler.startDocument = startDocument;
1736 sgmlDefaultSAXHandler.endDocument = endDocument;
1737 sgmlDefaultSAXHandler.startElement = startElement;
1738 sgmlDefaultSAXHandler.endElement = endElement;
1739 sgmlDefaultSAXHandler.reference = NULL;
1740 sgmlDefaultSAXHandler.characters = characters;
1741 sgmlDefaultSAXHandler.cdataBlock = NULL;
1742 sgmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1743 sgmlDefaultSAXHandler.processingInstruction = NULL;
1744 sgmlDefaultSAXHandler.comment = comment;
1745 sgmlDefaultSAXHandler.warning = xmlParserWarning;
1746 sgmlDefaultSAXHandler.error = xmlParserError;
1747 sgmlDefaultSAXHandler.fatalError = xmlParserError;
1748}