Annotation of XML/SAX.c, revision 1.84
1.1 daniel 1: /*
2: * SAX.c : Default SAX handler to build a tree.
1.5 daniel 3: *
1.7 daniel 4: * See Copyright for the status of this software.
5: *
1.5 daniel 6: * Daniel Veillard <Daniel.Veillard@w3.org>
1.1 daniel 7: */
8:
1.32 daniel 9:
1.39 daniel 10: #ifdef WIN32
11: #include "win32config.h"
12: #else
13: #include "config.h"
14: #endif
1.1 daniel 15: #include <stdio.h>
1.5 daniel 16: #include <stdlib.h>
1.68 veillard 17: #include <string.h>
1.57 daniel 18: #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>
1.80 veillard 24: #include <libxml/xmlerror.h>
1.57 daniel 25: #include <libxml/debugXML.h>
26: #include <libxml/xmlIO.h>
27: #include <libxml/SAX.h>
1.60 daniel 28: #include <libxml/uri.h>
1.66 daniel 29: #include <libxml/HTMLtree.h>
1.1 daniel 30:
1.15 daniel 31: /* #define DEBUG_SAX */
1.26 daniel 32: /* #define DEBUG_SAX_TREE */
1.2 daniel 33:
1.5 daniel 34: /**
35: * getPublicId:
1.16 daniel 36: * @ctx: the user data (XML parser context)
1.5 daniel 37: *
1.1 daniel 38: * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
1.5 daniel 39: *
1.34 daniel 40: * Returns a xmlChar *
1.1 daniel 41: */
1.34 daniel 42: const xmlChar *
1.11 daniel 43: getPublicId(void *ctx)
1.5 daniel 44: {
1.11 daniel 45: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.1 daniel 46: return(NULL);
47: }
48:
1.5 daniel 49: /**
50: * getSystemId:
1.16 daniel 51: * @ctx: the user data (XML parser context)
1.5 daniel 52: *
1.12 daniel 53: * Return the system ID, basically URL or filename e.g.
1.5 daniel 54: * http://www.sgmlsource.com/dtds/memo.dtd
55: *
1.34 daniel 56: * Returns a xmlChar *
1.5 daniel 57: */
1.34 daniel 58: const xmlChar *
1.11 daniel 59: getSystemId(void *ctx)
1.5 daniel 60: {
1.11 daniel 61: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.28 daniel 62: return(BAD_CAST ctxt->input->filename);
1.1 daniel 63: }
64:
1.5 daniel 65: /**
66: * getLineNumber:
1.16 daniel 67: * @ctx: the user data (XML parser context)
1.5 daniel 68: *
1.1 daniel 69: * Return the line number of the current parsing point.
1.5 daniel 70: *
1.8 daniel 71: * Returns an int
1.1 daniel 72: */
1.5 daniel 73: int
1.11 daniel 74: getLineNumber(void *ctx)
1.5 daniel 75: {
1.11 daniel 76: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.1 daniel 77: return(ctxt->input->line);
78: }
1.5 daniel 79:
80: /**
81: * getColumnNumber:
1.16 daniel 82: * @ctx: the user data (XML parser context)
1.5 daniel 83: *
1.1 daniel 84: * Return the column number of the current parsing point.
1.5 daniel 85: *
1.8 daniel 86: * Returns an int
1.1 daniel 87: */
1.5 daniel 88: int
1.11 daniel 89: getColumnNumber(void *ctx)
1.5 daniel 90: {
1.11 daniel 91: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.1 daniel 92: return(ctxt->input->col);
93: }
94:
95: /*
96: * The default SAX Locator.
97: */
98:
99: xmlSAXLocator xmlDefaultSAXLocator = {
100: getPublicId, getSystemId, getLineNumber, getColumnNumber
101: };
102:
1.5 daniel 103: /**
1.10 daniel 104: * isStandalone:
1.16 daniel 105: * @ctx: the user data (XML parser context)
1.10 daniel 106: *
107: * Is this document tagged standalone ?
108: *
109: * Returns 1 if true
110: */
111: int
1.11 daniel 112: isStandalone(void *ctx)
1.10 daniel 113: {
1.11 daniel 114: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 115: return(ctxt->myDoc->standalone == 1);
116: }
117:
118: /**
119: * hasInternalSubset:
1.16 daniel 120: * @ctx: the user data (XML parser context)
1.10 daniel 121: *
122: * Does this document has an internal subset
123: *
124: * Returns 1 if true
125: */
126: int
1.11 daniel 127: hasInternalSubset(void *ctx)
1.10 daniel 128: {
1.11 daniel 129: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 130: return(ctxt->myDoc->intSubset != NULL);
131: }
132:
133: /**
134: * hasExternalSubset:
1.16 daniel 135: * @ctx: the user data (XML parser context)
1.10 daniel 136: *
137: * Does this document has an external subset
138: *
139: * Returns 1 if true
140: */
141: int
1.11 daniel 142: hasExternalSubset(void *ctx)
1.10 daniel 143: {
1.11 daniel 144: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 145: return(ctxt->myDoc->extSubset != NULL);
146: }
147:
148: /**
1.19 veillard 149: * internalSubset:
1.58 daniel 150: * @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)
1.10 daniel 154: *
1.41 daniel 155: * Callback on internal subset declaration.
1.10 daniel 156: */
157: void
1.34 daniel 158: internalSubset(void *ctx, const xmlChar *name,
159: const xmlChar *ExternalID, const xmlChar *SystemID)
1.10 daniel 160: {
1.11 daniel 161: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.66 daniel 162: xmlDtdPtr dtd;
1.10 daniel 163: #ifdef DEBUG_SAX
1.83 veillard 164: xmlGenericError(xmlGenericErrorContext,
165: "SAX.internalSubset(%s, %s, %s)\n",
1.10 daniel 166: name, ExternalID, SystemID);
167: #endif
1.66 daniel 168:
1.67 daniel 169: if (ctxt->myDoc == NULL)
170: return;
1.66 daniel 171: dtd = xmlGetIntSubset(ctxt->myDoc);
172: if (dtd != NULL) {
1.72 veillard 173: if (ctxt->html)
174: return;
1.66 daniel 175: xmlUnlinkNode((xmlNodePtr) dtd);
176: xmlFreeDtd(dtd);
1.67 daniel 177: ctxt->myDoc->intSubset = NULL;
1.66 daniel 178: }
1.67 daniel 179: ctxt->myDoc->intSubset =
180: xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
1.49 daniel 181: }
182:
183: /**
184: * externalSubset:
185: * @ctx: the user data (XML parser context)
1.58 daniel 186: * @name: the root element name
187: * @ExternalID: the external ID
188: * @SystemID: the SYSTEM ID (e.g. filename or URL)
1.49 daniel 189: *
190: * Callback on external subset declaration.
191: */
192: void
193: externalSubset(void *ctx, const xmlChar *name,
194: const xmlChar *ExternalID, const xmlChar *SystemID)
195: {
196: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
197: #ifdef DEBUG_SAX
1.83 veillard 198: xmlGenericError(xmlGenericErrorContext,
199: "SAX.externalSubset(%s, %s, %s)\n",
1.49 daniel 200: name, ExternalID, SystemID);
201: #endif
1.24 daniel 202: if (((ExternalID != NULL) || (SystemID != NULL)) &&
203: (ctxt->validate && ctxt->wellFormed && ctxt->myDoc)) {
204: /*
205: * Try to fetch and parse the external subset.
206: */
1.49 daniel 207: xmlParserInputPtr oldinput;
208: int oldinputNr;
209: int oldinputMax;
210: xmlParserInputPtr *oldinputTab;
1.50 daniel 211: int oldwellFormed;
1.24 daniel 212: xmlParserInputPtr input = NULL;
213: xmlCharEncoding enc;
1.68 veillard 214: int oldcharset;
1.24 daniel 215:
216: /*
217: * Ask the Entity resolver to load the damn thing
218: */
1.49 daniel 219: if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
220: input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
1.24 daniel 221: SystemID);
222: if (input == NULL) {
223: return;
224: }
225:
1.50 daniel 226: xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
227:
1.49 daniel 228: /*
229: * make sure we won't destroy the main document context
230: */
231: oldinput = ctxt->input;
232: oldinputNr = ctxt->inputNr;
233: oldinputMax = ctxt->inputMax;
234: oldinputTab = ctxt->inputTab;
1.50 daniel 235: oldwellFormed = ctxt->wellFormed;
1.62 daniel 236: oldcharset = ctxt->charset;
1.49 daniel 237:
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;
1.62 daniel 250: ctxt->charset = oldcharset;
1.49 daniel 251: return;
252: }
253: ctxt->inputNr = 0;
254: ctxt->inputMax = 5;
255: ctxt->input = NULL;
256: xmlPushInput(ctxt, input);
1.43 daniel 257:
1.24 daniel 258: /*
1.43 daniel 259: * On the fly encoding conversion if needed
1.24 daniel 260: */
1.49 daniel 261: enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
262: xmlSwitchEncoding(ctxt, enc);
1.24 daniel 263:
264: if (input->filename == NULL)
1.28 daniel 265: input->filename = (char *) xmlStrdup(SystemID);
1.24 daniel 266: input->line = 1;
267: input->col = 1;
1.49 daniel 268: input->base = ctxt->input->cur;
269: input->cur = ctxt->input->cur;
1.24 daniel 270: input->free = NULL;
271:
272: /*
273: * let's parse that entity knowing it's an external subset.
274: */
1.49 daniel 275: xmlParseExternalSubset(ctxt, ExternalID, SystemID);
276:
277: /*
278: * Free up the external entities
279: */
1.24 daniel 280:
1.49 daniel 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;
1.62 daniel 293: ctxt->charset = oldcharset;
1.52 daniel 294: /* ctxt->wellFormed = oldwellFormed; */
1.12 daniel 295: }
1.10 daniel 296: }
297:
298: /**
1.5 daniel 299: * resolveEntity:
1.16 daniel 300: * @ctx: the user data (XML parser context)
1.5 daniel 301: * @publicId: The public ID of the entity
302: * @systemId: The system ID of the entity
303: *
1.41 daniel 304: * 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
1.5 daniel 309: *
1.8 daniel 310: * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1.5 daniel 311: */
312: xmlParserInputPtr
1.34 daniel 313: resolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
1.5 daniel 314: {
1.12 daniel 315: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.77 veillard 316: xmlParserInputPtr ret;
1.78 veillard 317: xmlChar *URI;
1.77 veillard 318: const char *base = NULL;
319:
320: if (ctxt->input != NULL)
321: base = ctxt->input->filename;
322: if (base == NULL)
323: base = ctxt->directory;
324:
1.78 veillard 325: URI = xmlBuildURI(systemId, (const xmlChar *) base);
1.2 daniel 326:
327: #ifdef DEBUG_SAX
1.83 veillard 328: xmlGenericError(xmlGenericErrorContext,
329: "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
1.2 daniel 330: #endif
1.5 daniel 331:
1.77 veillard 332: ret = xmlLoadExternalEntity((const char *) URI,
333: (const char *) publicId, ctxt);
334: if (URI != NULL)
335: xmlFree(URI);
336: return(ret);
1.1 daniel 337: }
338:
1.5 daniel 339: /**
1.10 daniel 340: * getEntity:
1.16 daniel 341: * @ctx: the user data (XML parser context)
1.10 daniel 342: * @name: The entity name
343: *
344: * Get an entity by name
345: *
1.13 daniel 346: * Returns the xmlEntityPtr if found.
1.10 daniel 347: */
348: xmlEntityPtr
1.34 daniel 349: getEntity(void *ctx, const xmlChar *name)
1.10 daniel 350: {
1.11 daniel 351: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 352: xmlEntityPtr ret;
353:
354: #ifdef DEBUG_SAX
1.83 veillard 355: xmlGenericError(xmlGenericErrorContext,
356: "SAX.getEntity(%s)\n", name);
1.10 daniel 357: #endif
358:
359: ret = xmlGetDocEntity(ctxt->myDoc, name);
1.71 veillard 360: 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: }
1.10 daniel 373: return(ret);
374: }
375:
1.20 daniel 376: /**
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: */
385: xmlEntityPtr
1.34 daniel 386: getParameterEntity(void *ctx, const xmlChar *name)
1.20 daniel 387: {
388: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
389: xmlEntityPtr ret;
390:
391: #ifdef DEBUG_SAX
1.83 veillard 392: xmlGenericError(xmlGenericErrorContext,
393: "SAX.getParameterEntity(%s)\n", name);
1.20 daniel 394: #endif
395:
396: ret = xmlGetParameterEntity(ctxt->myDoc, name);
397: return(ret);
398: }
399:
1.10 daniel 400:
401: /**
402: * entityDecl:
1.16 daniel 403: * @ctx: the user data (XML parser context)
1.10 daniel 404: * @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: */
412: void
1.34 daniel 413: entityDecl(void *ctx, const xmlChar *name, int type,
414: const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1.10 daniel 415: {
1.73 veillard 416: xmlEntityPtr ent;
1.11 daniel 417: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 418:
419: #ifdef DEBUG_SAX
1.83 veillard 420: xmlGenericError(xmlGenericErrorContext,
421: "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
1.10 daniel 422: name, type, publicId, systemId, content);
423: #endif
1.73 veillard 424: if (ctxt->inSubset == 1) {
425: ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
1.51 daniel 426: systemId, content);
1.73 veillard 427: 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);
1.77 veillard 431: if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
1.78 veillard 432: xmlChar *URI;
1.77 veillard 433: const char *base = NULL;
434:
435: if (ctxt->input != NULL)
436: base = ctxt->input->filename;
437: if (base == NULL)
438: base = ctxt->directory;
439:
1.78 veillard 440: URI = xmlBuildURI(systemId, (const xmlChar *) base);
1.77 veillard 441: ent->URI = URI;
442: }
1.73 veillard 443: } else if (ctxt->inSubset == 2) {
444: ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
1.51 daniel 445: systemId, content);
1.73 veillard 446: 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);
1.77 veillard 450: if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
1.78 veillard 451: xmlChar *URI;
1.77 veillard 452: const char *base = NULL;
453:
454: if (ctxt->input != NULL)
455: base = ctxt->input->filename;
456: if (base == NULL)
457: base = ctxt->directory;
458:
1.78 veillard 459: URI = xmlBuildURI(systemId, (const xmlChar *) base);
1.77 veillard 460: ent->URI = URI;
461: }
1.73 veillard 462: } else {
1.50 daniel 463: 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: }
1.10 daniel 467: }
468:
469: /**
470: * attributeDecl:
1.16 daniel 471: * @ctx: the user data (XML parser context)
1.58 daniel 472: * @elem: the name of the element
1.48 daniel 473: * @fullname: the attribute name
1.10 daniel 474: * @type: the attribute type
1.58 daniel 475: * @def: the type of default value
476: * @defaultValue: the attribute default value
477: * @tree: the tree of enumerated value set
1.10 daniel 478: *
479: * An attribute definition has been parsed
480: */
481: void
1.48 daniel 482: attributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
1.34 daniel 483: int type, int def, const xmlChar *defaultValue,
1.10 daniel 484: xmlEnumerationPtr tree)
485: {
1.11 daniel 486: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.21 daniel 487: xmlAttributePtr attr;
1.48 daniel 488: xmlChar *name = NULL, *prefix = NULL;
1.10 daniel 489:
490: #ifdef DEBUG_SAX
1.83 veillard 491: xmlGenericError(xmlGenericErrorContext,
492: "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1.48 daniel 493: elem, fullname, type, def, defaultValue);
1.10 daniel 494: #endif
1.48 daniel 495: name = xmlSplitQName(ctxt, fullname, &prefix);
1.50 daniel 496: if (ctxt->inSubset == 1)
497: attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
1.68 veillard 498: name, prefix, (xmlAttributeType) type,
499: (xmlAttributeDefault) def, defaultValue, tree);
1.50 daniel 500: else if (ctxt->inSubset == 2)
501: attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
1.68 veillard 502: name, prefix, (xmlAttributeType) type,
503: (xmlAttributeDefault) def, defaultValue, tree);
1.50 daniel 504: 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: }
1.21 daniel 510: if (attr == 0) ctxt->valid = 0;
1.23 daniel 511: if (ctxt->validate && ctxt->wellFormed &&
512: ctxt->myDoc && ctxt->myDoc->intSubset)
1.21 daniel 513: ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
514: attr);
1.48 daniel 515: if (prefix != NULL)
516: xmlFree(prefix);
517: if (name != NULL)
518: xmlFree(name);
1.10 daniel 519: }
520:
521: /**
522: * elementDecl:
1.16 daniel 523: * @ctx: the user data (XML parser context)
1.10 daniel 524: * @name: the element name
525: * @type: the element type
1.58 daniel 526: * @content: the element value tree
1.10 daniel 527: *
528: * An element definition has been parsed
529: */
530: void
1.34 daniel 531: elementDecl(void *ctx, const xmlChar *name, int type,
1.10 daniel 532: xmlElementContentPtr content)
533: {
1.11 daniel 534: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.50 daniel 535: xmlElementPtr elem = NULL;
1.10 daniel 536:
537: #ifdef DEBUG_SAX
1.83 veillard 538: xmlGenericError(xmlGenericErrorContext,
539: "SAX.elementDecl(%s, %d, ...)\n",
1.48 daniel 540: fullname, type);
1.10 daniel 541: #endif
1.21 daniel 542:
1.50 daniel 543: if (ctxt->inSubset == 1)
544: elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
1.68 veillard 545: name, (xmlElementTypeVal) type, content);
1.50 daniel 546: else if (ctxt->inSubset == 2)
547: elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
1.68 veillard 548: name, (xmlElementTypeVal) type, content);
1.50 daniel 549: 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;
1.23 daniel 556: if (ctxt->validate && ctxt->wellFormed &&
557: ctxt->myDoc && ctxt->myDoc->intSubset)
1.21 daniel 558: ctxt->valid &= xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
1.10 daniel 559: }
560:
561: /**
1.5 daniel 562: * notationDecl:
1.16 daniel 563: * @ctx: the user data (XML parser context)
1.5 daniel 564: * @name: The name of the notation
565: * @publicId: The public ID of the entity
566: * @systemId: The system ID of the entity
567: *
1.1 daniel 568: * What to do when a notation declaration has been parsed.
569: */
1.5 daniel 570: void
1.34 daniel 571: notationDecl(void *ctx, const xmlChar *name,
572: const xmlChar *publicId, const xmlChar *systemId)
1.5 daniel 573: {
1.11 daniel 574: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.50 daniel 575: xmlNotationPtr nota = NULL;
1.21 daniel 576:
1.2 daniel 577: #ifdef DEBUG_SAX
1.83 veillard 578: xmlGenericError(xmlGenericErrorContext,
579: "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
1.2 daniel 580: #endif
1.21 daniel 581:
1.50 daniel 582: if (ctxt->inSubset == 1)
583: nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
584: publicId, systemId);
585: else if (ctxt->inSubset == 2)
586: nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
1.21 daniel 587: publicId, systemId);
1.50 daniel 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;
1.23 daniel 595: if (ctxt->validate && ctxt->wellFormed &&
596: ctxt->myDoc && ctxt->myDoc->intSubset)
1.21 daniel 597: ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
598: nota);
1.1 daniel 599: }
600:
1.5 daniel 601: /**
602: * unparsedEntityDecl:
1.16 daniel 603: * @ctx: the user data (XML parser context)
1.5 daniel 604: * @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: *
1.1 daniel 609: * What to do when an unparsed entity declaration is parsed
610: */
1.5 daniel 611: void
1.34 daniel 612: unparsedEntityDecl(void *ctx, const xmlChar *name,
613: const xmlChar *publicId, const xmlChar *systemId,
614: const xmlChar *notationName)
1.5 daniel 615: {
1.28 daniel 616: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2 daniel 617: #ifdef DEBUG_SAX
1.83 veillard 618: xmlGenericError(xmlGenericErrorContext,
619: "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
1.2 daniel 620: name, publicId, systemId, notationName);
621: #endif
1.28 daniel 622: 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);
1.1 daniel 629: }
630:
1.5 daniel 631: /**
632: * setDocumentLocator:
1.16 daniel 633: * @ctx: the user data (XML parser context)
1.5 daniel 634: * @loc: A SAX Locator
635: *
1.1 daniel 636: * Receive the document locator at startup, actually xmlDefaultSAXLocator
637: * Everything is available on the context, so this is useless in our case.
638: */
1.5 daniel 639: void
1.11 daniel 640: setDocumentLocator(void *ctx, xmlSAXLocatorPtr loc)
1.5 daniel 641: {
1.11 daniel 642: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2 daniel 643: #ifdef DEBUG_SAX
1.83 veillard 644: xmlGenericError(xmlGenericErrorContext,
645: "SAX.setDocumentLocator()\n");
1.2 daniel 646: #endif
1.1 daniel 647: }
648:
1.5 daniel 649: /**
650: * startDocument:
1.16 daniel 651: * @ctx: the user data (XML parser context)
1.5 daniel 652: *
1.1 daniel 653: * called when the document start being processed.
654: */
1.5 daniel 655: void
1.11 daniel 656: startDocument(void *ctx)
1.5 daniel 657: {
1.11 daniel 658: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 659: xmlDocPtr doc;
660:
1.2 daniel 661: #ifdef DEBUG_SAX
1.83 veillard 662: xmlGenericError(xmlGenericErrorContext,
663: "SAX.startDocument()\n");
1.2 daniel 664: #endif
1.66 daniel 665: if (ctxt->html) {
666: if (ctxt->myDoc == NULL)
1.69 veillard 667: #ifdef LIBXML_HTML_ENABLED
1.72 veillard 668: ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
1.69 veillard 669: #else
1.83 veillard 670: xmlGenericError(xmlGenericErrorContext,
671: "libxml2 built without HTML support\n");
1.69 veillard 672: #endif
1.66 daniel 673: } 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: }
1.10 daniel 682: }
1.70 veillard 683: 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: }
1.1 daniel 687: }
688:
1.5 daniel 689: /**
690: * endDocument:
1.16 daniel 691: * @ctx: the user data (XML parser context)
1.5 daniel 692: *
1.1 daniel 693: * called when the document end has been detected.
694: */
1.5 daniel 695: void
1.11 daniel 696: endDocument(void *ctx)
1.5 daniel 697: {
1.31 daniel 698: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2 daniel 699: #ifdef DEBUG_SAX
1.83 veillard 700: xmlGenericError(xmlGenericErrorContext,
701: "SAX.endDocument()\n");
1.2 daniel 702: #endif
1.31 daniel 703: if (ctxt->validate && ctxt->wellFormed &&
704: ctxt->myDoc && ctxt->myDoc->intSubset)
705: ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
1.59 daniel 706:
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: }
1.62 daniel 715: 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: }
1.1 daniel 723: }
724:
1.5 daniel 725: /**
1.10 daniel 726: * attribute:
1.16 daniel 727: * @ctx: the user data (XML parser context)
1.58 daniel 728: * @fullname: The attribute name, including namespace prefix
1.10 daniel 729: * @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: */
736: void
1.34 daniel 737: attribute(void *ctx, const xmlChar *fullname, const xmlChar *value)
1.10 daniel 738: {
1.11 daniel 739: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 740: xmlAttrPtr ret;
1.34 daniel 741: xmlChar *name;
742: xmlChar *ns;
1.56 daniel 743: xmlChar *nval;
1.29 daniel 744: xmlNsPtr namespace;
1.10 daniel 745:
746: /****************
747: #ifdef DEBUG_SAX
1.83 veillard 748: xmlGenericError(xmlGenericErrorContext,
749: "SAX.attribute(%s, %s)\n", fullname, value);
1.10 daniel 750: #endif
751: ****************/
752: /*
753: * Split the full name into a namespace prefix and the tag name
754: */
1.48 daniel 755: name = xmlSplitQName(ctxt, fullname, &ns);
1.10 daniel 756:
757: /*
1.82 veillard 758: * 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
1.55 daniel 761: */
1.82 veillard 762: nval = xmlValidNormalizeAttributeValue(ctxt->myDoc, ctxt->node,
763: fullname, value);
1.56 daniel 764: if (nval != NULL)
765: value = nval;
1.55 daniel 766:
767: /*
1.10 daniel 768: * Check whether it's a namespace definition
769: */
1.65 daniel 770: if ((!ctxt->html) && (ns == NULL) &&
1.10 daniel 771: (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
772: (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
1.60 daniel 773: 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 {
1.61 daniel 781: if (uri->scheme == NULL) {
1.60 daniel 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:
1.10 daniel 789: /* a default namespace definition */
790: xmlNewNs(ctxt->node, value, NULL);
791: if (name != NULL)
1.30 daniel 792: xmlFree(name);
1.55 daniel 793: if (nval != NULL)
794: xmlFree(nval);
1.10 daniel 795: return;
796: }
1.65 daniel 797: if ((!ctxt->html) &&
798: (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
1.10 daniel 799: (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
1.54 daniel 800: /*
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: */
1.10 daniel 809: /* a standard namespace definition */
810: xmlNewNs(ctxt->node, value, name);
1.30 daniel 811: xmlFree(ns);
1.10 daniel 812: if (name != NULL)
1.30 daniel 813: xmlFree(name);
1.55 daniel 814: if (nval != NULL)
815: xmlFree(nval);
1.10 daniel 816: return;
817: }
818:
1.38 daniel 819: if (ns != NULL)
820: namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
821: else {
822: namespace = NULL;
823: }
824:
1.29 daniel 825: /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
826: ret = xmlNewNsProp(ctxt->node, namespace, name, NULL);
1.22 daniel 827:
1.26 daniel 828: if (ret != NULL) {
1.46 daniel 829: if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
830: xmlNodePtr tmp;
831:
1.44 daniel 832: ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
1.46 daniel 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: }
1.65 daniel 840: } else if (value != NULL) {
1.44 daniel 841: ret->children = xmlNewDocText(ctxt->myDoc, value);
1.46 daniel 842: ret->last = ret->children;
843: if (ret->children != NULL)
844: ret->children->parent = (xmlNodePtr) ret;
845: }
1.26 daniel 846: }
1.22 daniel 847:
1.65 daniel 848: if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
1.56 daniel 849: 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,
1.22 daniel 872: ctxt->node, ret, value);
1.56 daniel 873: }
874: } else {
1.26 daniel 875: /*
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);
1.31 daniel 881: else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
882: xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
1.26 daniel 883: }
1.22 daniel 884:
1.55 daniel 885: if (nval != NULL)
886: xmlFree(nval);
1.10 daniel 887: if (name != NULL)
1.30 daniel 888: xmlFree(name);
1.10 daniel 889: if (ns != NULL)
1.30 daniel 890: xmlFree(ns);
1.10 daniel 891: }
892:
893: /**
1.5 daniel 894: * startElement:
1.16 daniel 895: * @ctx: the user data (XML parser context)
1.58 daniel 896: * @fullname: The element name, including namespace prefix
1.10 daniel 897: * @atts: An array of name/value attributes pairs, NULL terminated
1.5 daniel 898: *
1.1 daniel 899: * called when an opening tag has been processed.
900: */
1.5 daniel 901: void
1.34 daniel 902: startElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
1.5 daniel 903: {
1.11 daniel 904: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 905: xmlNodePtr ret;
906: xmlNodePtr parent = ctxt->node;
907: xmlNsPtr ns;
1.34 daniel 908: xmlChar *name;
909: xmlChar *prefix;
910: const xmlChar *att;
911: const xmlChar *value;
1.10 daniel 912: int i;
913:
1.2 daniel 914: #ifdef DEBUG_SAX
1.83 veillard 915: xmlGenericError(xmlGenericErrorContext,
916: "SAX.startElement(%s)\n", fullname);
1.2 daniel 917: #endif
1.33 daniel 918:
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:
1.10 daniel 936: /*
937: * Split the full name into a namespace prefix and the tag name
938: */
1.48 daniel 939: name = xmlSplitQName(ctxt, fullname, &prefix);
1.10 daniel 940:
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;
1.44 daniel 949: if (ctxt->myDoc->children == NULL) {
1.26 daniel 950: #ifdef DEBUG_SAX_TREE
1.83 veillard 951: xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name);
1.26 daniel 952: #endif
1.45 daniel 953: xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1.26 daniel 954: } else if (parent == NULL) {
1.44 daniel 955: parent = ctxt->myDoc->children;
1.26 daniel 956: }
1.63 daniel 957: ctxt->nodemem = -1;
1.10 daniel 958:
959: /*
960: * We are parsing a new node.
961: */
1.26 daniel 962: #ifdef DEBUG_SAX_TREE
1.83 veillard 963: xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name);
1.26 daniel 964: #endif
1.10 daniel 965: nodePush(ctxt, ret);
966:
967: /*
968: * Link the child element
969: */
1.26 daniel 970: if (parent != NULL) {
971: if (parent->type == XML_ELEMENT_NODE) {
972: #ifdef DEBUG_SAX_TREE
1.83 veillard 973: xmlGenericError(xmlGenericErrorContext,
974: "adding child %s to %s\n", name, parent->name);
1.26 daniel 975: #endif
976: xmlAddChild(parent, ret);
977: } else {
978: #ifdef DEBUG_SAX_TREE
1.83 veillard 979: xmlGenericError(xmlGenericErrorContext,
980: "adding sibling %s to ", name);
1.26 daniel 981: xmlDebugDumpOneNode(stderr, parent, 0);
982: #endif
983: xmlAddSibling(parent, ret);
984: }
985: }
1.10 daniel 986:
1.54 daniel 987: /*
1.29 daniel 988: * process all the attributes whose name start with "xml"
1.10 daniel 989: */
990: if (atts != NULL) {
991: i = 0;
992: att = atts[i++];
993: value = atts[i++];
1.65 daniel 994: 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);
1.29 daniel 998:
1.65 daniel 999: att = atts[i++];
1000: value = atts[i++];
1001: }
1.29 daniel 1002: }
1003: }
1004:
1005: /*
1.64 daniel 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);
1.75 veillard 1012: 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: }
1.64 daniel 1018: xmlSetNs(ret, ns);
1019:
1020: /*
1.29 daniel 1021: * process all the other attributes
1022: */
1023: if (atts != NULL) {
1024: i = 0;
1025: att = atts[i++];
1026: value = atts[i++];
1.65 daniel 1027: if (ctxt->html) {
1028: while (att != NULL) {
1.29 daniel 1029: attribute(ctxt, att, value);
1.65 daniel 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: }
1.10 daniel 1044: }
1045: }
1046:
1047: /*
1.64 daniel 1048: * If it's the Document root, finish the Dtd validation and
1049: * check the document root element for validity
1.10 daniel 1050: */
1.64 daniel 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: }
1.10 daniel 1056:
1057: if (prefix != NULL)
1.30 daniel 1058: xmlFree(prefix);
1.10 daniel 1059: if (name != NULL)
1.30 daniel 1060: xmlFree(name);
1.10 daniel 1061:
1.1 daniel 1062: }
1063:
1.5 daniel 1064: /**
1065: * endElement:
1.16 daniel 1066: * @ctx: the user data (XML parser context)
1.5 daniel 1067: * @name: The element name
1068: *
1.1 daniel 1069: * called when the end of an element has been detected.
1070: */
1.5 daniel 1071: void
1.34 daniel 1072: endElement(void *ctx, const xmlChar *name)
1.5 daniel 1073: {
1.11 daniel 1074: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 1075: xmlParserNodeInfo node_info;
1076: xmlNodePtr cur = ctxt->node;
1077:
1.2 daniel 1078: #ifdef DEBUG_SAX
1.10 daniel 1079: if (name == NULL)
1.83 veillard 1080: xmlGenericError(xmlGenericErrorContext, "SAX.endElement(NULL)\n");
1.10 daniel 1081: else
1.83 veillard 1082: xmlGenericError(xmlGenericErrorContext, "SAX.endElement(%s)\n", name);
1.10 daniel 1083: #endif
1084:
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: }
1.63 daniel 1092: ctxt->nodemem = -1;
1.10 daniel 1093:
1.23 daniel 1094: if (ctxt->validate && ctxt->wellFormed &&
1095: ctxt->myDoc && ctxt->myDoc->intSubset)
1.22 daniel 1096: ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
1097: cur);
1098:
1099:
1.10 daniel 1100: /*
1101: * end of parsing of this node.
1102: */
1.26 daniel 1103: #ifdef DEBUG_SAX_TREE
1.83 veillard 1104: xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name);
1.26 daniel 1105: #endif
1.10 daniel 1106: nodePop(ctxt);
1.1 daniel 1107: }
1108:
1.5 daniel 1109: /**
1.10 daniel 1110: * reference:
1.16 daniel 1111: * @ctx: the user data (XML parser context)
1.10 daniel 1112: * @name: The entity name
1.5 daniel 1113: *
1.10 daniel 1114: * called when an entity reference is detected.
1.5 daniel 1115: */
1116: void
1.34 daniel 1117: reference(void *ctx, const xmlChar *name)
1.5 daniel 1118: {
1.11 daniel 1119: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 1120: xmlNodePtr ret;
1121:
1.5 daniel 1122: #ifdef DEBUG_SAX
1.83 veillard 1123: xmlGenericError(xmlGenericErrorContext,
1124: "SAX.reference(%s)\n", name);
1.5 daniel 1125: #endif
1.42 daniel 1126: if (name[0] == '#')
1127: ret = xmlNewCharRef(ctxt->myDoc, name);
1128: else
1129: ret = xmlNewReference(ctxt->myDoc, name);
1.26 daniel 1130: #ifdef DEBUG_SAX_TREE
1.83 veillard 1131: xmlGenericError(xmlGenericErrorContext,
1132: "add reference %s to %s \n", name, ctxt->node->name);
1.26 daniel 1133: #endif
1.10 daniel 1134: xmlAddChild(ctxt->node, ret);
1.5 daniel 1135: }
1136:
1137: /**
1138: * characters:
1.16 daniel 1139: * @ctx: the user data (XML parser context)
1.34 daniel 1140: * @ch: a xmlChar string
1141: * @len: the number of xmlChar
1.5 daniel 1142: *
1.1 daniel 1143: * receiving some chars from the parser.
1144: * Question: how much at a time ???
1145: */
1.5 daniel 1146: void
1.34 daniel 1147: characters(void *ctx, const xmlChar *ch, int len)
1.5 daniel 1148: {
1.11 daniel 1149: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2 daniel 1150: xmlNodePtr lastChild;
1151:
1152: #ifdef DEBUG_SAX
1.83 veillard 1153: xmlGenericError(xmlGenericErrorContext,
1154: "SAX.characters(%.30s, %d)\n", ch, len);
1.2 daniel 1155: #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:
1.36 daniel 1162: if (ctxt->node == NULL) {
1163: #ifdef DEBUG_SAX_TREE
1.83 veillard 1164: xmlGenericError(xmlGenericErrorContext,
1165: "add chars: ctxt->node == NULL !\n");
1.36 daniel 1166: #endif
1167: return;
1168: }
1.2 daniel 1169: lastChild = xmlGetLastChild(ctxt->node);
1.26 daniel 1170: #ifdef DEBUG_SAX_TREE
1.83 veillard 1171: xmlGenericError(xmlGenericErrorContext,
1172: "add chars to %s \n", ctxt->node->name);
1.26 daniel 1173: #endif
1.62 daniel 1174:
1175: /*
1176: * Here we needed an accelerator mechanism in case of very large
1177: * elements. Use an attribute in the structure !!!
1178: */
1.63 daniel 1179: if (lastChild == NULL) {
1180: /* first node, first time */
1.10 daniel 1181: xmlNodeAddContentLen(ctxt->node, ch, len);
1.63 daniel 1182: #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 {
1.74 veillard 1189: if ((xmlNodeIsText(lastChild)) && (ctxt->nodemem != 0)) {
1.63 daniel 1190: #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
1.10 daniel 1218: xmlTextConcat(lastChild, ch, len);
1.63 daniel 1219: #endif
1.62 daniel 1220: } else {
1.63 daniel 1221: /* Mixed content, first time */
1.10 daniel 1222: lastChild = xmlNewTextLen(ch, len);
1.2 daniel 1223: xmlAddChild(ctxt->node, lastChild);
1.63 daniel 1224: #ifndef XML_USE_BUFFER_CONTENT
1225: if (ctxt->node->children != NULL) {
1226: ctxt->nodelen = len;
1227: ctxt->nodemem = len + 1;
1228: }
1229: #endif
1.2 daniel 1230: }
1231: }
1.1 daniel 1232: }
1233:
1.5 daniel 1234: /**
1235: * ignorableWhitespace:
1.16 daniel 1236: * @ctx: the user data (XML parser context)
1.34 daniel 1237: * @ch: a xmlChar string
1238: * @len: the number of xmlChar
1.5 daniel 1239: *
1.1 daniel 1240: * receiving some ignorable whitespaces from the parser.
1241: * Question: how much at a time ???
1242: */
1.5 daniel 1243: void
1.34 daniel 1244: ignorableWhitespace(void *ctx, const xmlChar *ch, int len)
1.5 daniel 1245: {
1.11 daniel 1246: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2 daniel 1247: #ifdef DEBUG_SAX
1.83 veillard 1248: xmlGenericError(xmlGenericErrorContext,
1249: "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
1.2 daniel 1250: #endif
1.1 daniel 1251: }
1252:
1.5 daniel 1253: /**
1254: * processingInstruction:
1.16 daniel 1255: * @ctx: the user data (XML parser context)
1.5 daniel 1256: * @target: the target name
1257: * @data: the PI data's
1258: *
1259: * A processing instruction has been parsed.
1260: */
1261: void
1.34 daniel 1262: processingInstruction(void *ctx, const xmlChar *target,
1263: const xmlChar *data)
1.5 daniel 1264: {
1.26 daniel 1265: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1266: xmlNodePtr ret;
1267: xmlNodePtr parent = ctxt->node;
1268:
1.2 daniel 1269: #ifdef DEBUG_SAX
1.83 veillard 1270: xmlGenericError(xmlGenericErrorContext,
1271: "SAX.processingInstruction(%s, %s)\n", target, data);
1.2 daniel 1272: #endif
1.26 daniel 1273:
1274: ret = xmlNewPI(target, data);
1275: if (ret == NULL) return;
1.53 daniel 1276: 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)) {
1.26 daniel 1286: #ifdef DEBUG_SAX_TREE
1.83 veillard 1287: xmlGenericError(xmlGenericErrorContext,
1288: "Setting PI %s as root\n", target);
1.26 daniel 1289: #endif
1.45 daniel 1290: xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1.53 daniel 1291: return;
1.26 daniel 1292: }
1.53 daniel 1293: if (parent->type == XML_ELEMENT_NODE) {
1.26 daniel 1294: #ifdef DEBUG_SAX_TREE
1.83 veillard 1295: xmlGenericError(xmlGenericErrorContext,
1296: "adding PI %s child to %s\n", target, parent->name);
1.26 daniel 1297: #endif
1.53 daniel 1298: xmlAddChild(parent, ret);
1299: } else {
1.26 daniel 1300: #ifdef DEBUG_SAX_TREE
1.83 veillard 1301: xmlGenericError(xmlGenericErrorContext,
1302: "adding PI %s sibling to ", target);
1.53 daniel 1303: xmlDebugDumpOneNode(stderr, parent, 0);
1.26 daniel 1304: #endif
1.53 daniel 1305: xmlAddSibling(parent, ret);
1.26 daniel 1306: }
1.1 daniel 1307: }
1308:
1.10 daniel 1309: /**
1310: * globalNamespace:
1.16 daniel 1311: * @ctx: the user data (XML parser context)
1.10 daniel 1312: * @href: the namespace associated URN
1313: * @prefix: the namespace prefix
1314: *
1315: * An old global namespace has been parsed.
1316: */
1317: void
1.34 daniel 1318: globalNamespace(void *ctx, const xmlChar *href, const xmlChar *prefix)
1.10 daniel 1319: {
1.11 daniel 1320: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 1321: #ifdef DEBUG_SAX
1.83 veillard 1322: xmlGenericError(xmlGenericErrorContext,
1323: "SAX.globalNamespace(%s, %s)\n", href, prefix);
1.10 daniel 1324: #endif
1325: xmlNewGlobalNs(ctxt->myDoc, href, prefix);
1326: }
1327:
1328: /**
1329: * setNamespace:
1.16 daniel 1330: * @ctx: the user data (XML parser context)
1.10 daniel 1331: * @name: the namespace prefix
1332: *
1333: * Set the current element namespace.
1334: */
1.58 daniel 1335:
1.10 daniel 1336: void
1.34 daniel 1337: setNamespace(void *ctx, const xmlChar *name)
1.10 daniel 1338: {
1.11 daniel 1339: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 1340: xmlNsPtr ns;
1341: xmlNodePtr parent;
1342:
1343: #ifdef DEBUG_SAX
1.83 veillard 1344: xmlGenericError(xmlGenericErrorContext, "SAX.setNamespace(%s)\n", name);
1.10 daniel 1345: #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:
1.16 daniel 1359: * @ctx: the user data (XML parser context)
1.10 daniel 1360: *
1361: * Get the current element namespace.
1.58 daniel 1362: *
1363: * Returns the xmlNsPtr or NULL if none
1.10 daniel 1364: */
1.58 daniel 1365:
1.10 daniel 1366: xmlNsPtr
1.11 daniel 1367: getNamespace(void *ctx)
1.10 daniel 1368: {
1.11 daniel 1369: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 1370: xmlNsPtr ret;
1371:
1372: #ifdef DEBUG_SAX
1.83 veillard 1373: xmlGenericError(xmlGenericErrorContext, "SAX.getNamespace()\n");
1.10 daniel 1374: #endif
1375: ret = ctxt->node->ns;
1376: return(ret);
1377: }
1378:
1379: /**
1380: * checkNamespace:
1.16 daniel 1381: * @ctx: the user data (XML parser context)
1.10 daniel 1382: * @namespace: the namespace to check against
1383: *
1384: * Check that the current element namespace is the same as the
1385: * one read upon parsing.
1.58 daniel 1386: *
1387: * Returns 1 if true 0 otherwise
1.10 daniel 1388: */
1.58 daniel 1389:
1.10 daniel 1390: int
1.34 daniel 1391: checkNamespace(void *ctx, xmlChar *namespace)
1.10 daniel 1392: {
1.11 daniel 1393: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 1394: xmlNodePtr cur = ctxt->node;
1395:
1396: #ifdef DEBUG_SAX
1.83 veillard 1397: xmlGenericError(xmlGenericErrorContext,
1398: "SAX.checkNamespace(%s)\n", namespace);
1.10 daniel 1399: #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;
1.79 veillard 1419: } else if (!xmlStrEqual(namespace, cur->ns->prefix)) {
1.10 daniel 1420: 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:
1.16 daniel 1433: * @ctx: the user data (XML parser context)
1.10 daniel 1434: * @href: the namespace associated URN
1435: * @prefix: the namespace prefix
1436: *
1437: * A namespace has been parsed.
1438: */
1439: void
1.34 daniel 1440: namespaceDecl(void *ctx, const xmlChar *href, const xmlChar *prefix)
1.10 daniel 1441: {
1.11 daniel 1442: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 1443: #ifdef DEBUG_SAX
1444: if (prefix == NULL)
1.83 veillard 1445: xmlGenericError(xmlGenericErrorContext,
1446: "SAX.namespaceDecl(%s, NULL)\n", href);
1.10 daniel 1447: else
1.83 veillard 1448: xmlGenericError(xmlGenericErrorContext,
1449: "SAX.namespaceDecl(%s, %s)\n", href, prefix);
1.10 daniel 1450: #endif
1451: xmlNewNs(ctxt->node, href, prefix);
1452: }
1453:
1454: /**
1455: * comment:
1.16 daniel 1456: * @ctx: the user data (XML parser context)
1.10 daniel 1457: * @value: the comment content
1458: *
1459: * A comment has been parsed.
1460: */
1461: void
1.34 daniel 1462: comment(void *ctx, const xmlChar *value)
1.10 daniel 1463: {
1.11 daniel 1464: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.17 daniel 1465: xmlNodePtr ret;
1.27 daniel 1466: xmlNodePtr parent = ctxt->node;
1.17 daniel 1467:
1.10 daniel 1468: #ifdef DEBUG_SAX
1.83 veillard 1469: xmlGenericError(xmlGenericErrorContext, "SAX.comment(%s)\n", value);
1.10 daniel 1470: #endif
1.17 daniel 1471: ret = xmlNewDocComment(ctxt->myDoc, value);
1.27 daniel 1472: if (ret == NULL) return;
1473:
1.53 daniel 1474: 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)) {
1.27 daniel 1482: #ifdef DEBUG_SAX_TREE
1.83 veillard 1483: xmlGenericError(xmlGenericErrorContext,
1484: "Setting comment as root\n");
1.27 daniel 1485: #endif
1.45 daniel 1486: xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1.53 daniel 1487: return;
1.27 daniel 1488: }
1.53 daniel 1489: if (parent->type == XML_ELEMENT_NODE) {
1.27 daniel 1490: #ifdef DEBUG_SAX_TREE
1.83 veillard 1491: xmlGenericError(xmlGenericErrorContext,
1492: "adding comment child to %s\n", parent->name);
1.27 daniel 1493: #endif
1.53 daniel 1494: xmlAddChild(parent, ret);
1495: } else {
1.27 daniel 1496: #ifdef DEBUG_SAX_TREE
1.83 veillard 1497: xmlGenericError(xmlGenericErrorContext,
1498: "adding comment sibling to ");
1.53 daniel 1499: xmlDebugDumpOneNode(stderr, parent, 0);
1.27 daniel 1500: #endif
1.53 daniel 1501: xmlAddSibling(parent, ret);
1.27 daniel 1502: }
1.25 daniel 1503: }
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: */
1513: void
1.34 daniel 1514: cdataBlock(void *ctx, const xmlChar *value, int len)
1.25 daniel 1515: {
1516: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.40 daniel 1517: xmlNodePtr ret, lastChild;
1.25 daniel 1518:
1519: #ifdef DEBUG_SAX
1.83 veillard 1520: xmlGenericError(xmlGenericErrorContext,
1521: "SAX.pcdata(%.10s, %d)\n", value, len);
1.25 daniel 1522: #endif
1.40 daniel 1523: lastChild = xmlGetLastChild(ctxt->node);
1524: #ifdef DEBUG_SAX_TREE
1.83 veillard 1525: xmlGenericError(xmlGenericErrorContext,
1526: "add chars to %s \n", ctxt->node->name);
1.40 daniel 1527: #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: }
1.10 daniel 1535: }
1536:
1.18 daniel 1537: /*
1538: * Default handler for XML, builds the DOM tree
1539: */
1.1 daniel 1540: xmlSAXHandler xmlDefaultSAXHandler = {
1.10 daniel 1541: internalSubset,
1542: isStandalone,
1543: hasInternalSubset,
1544: hasExternalSubset,
1.1 daniel 1545: resolveEntity,
1.10 daniel 1546: getEntity,
1547: entityDecl,
1.1 daniel 1548: notationDecl,
1.10 daniel 1549: attributeDecl,
1550: elementDecl,
1.1 daniel 1551: unparsedEntityDecl,
1552: setDocumentLocator,
1553: startDocument,
1554: endDocument,
1555: startElement,
1556: endElement,
1.10 daniel 1557: reference,
1.1 daniel 1558: characters,
1559: ignorableWhitespace,
1560: processingInstruction,
1.10 daniel 1561: comment,
1.1 daniel 1562: xmlParserWarning,
1563: xmlParserError,
1.2 daniel 1564: xmlParserError,
1.20 daniel 1565: getParameterEntity,
1.25 daniel 1566: cdataBlock,
1.49 daniel 1567: externalSubset,
1.1 daniel 1568: };
1.2 daniel 1569:
1.5 daniel 1570: /**
1571: * xmlDefaultSAXHandlerInit:
1572: *
1573: * Initialize the default SAX handler
1574: */
1575: void
1576: xmlDefaultSAXHandlerInit(void)
1577: {
1.10 daniel 1578: xmlDefaultSAXHandler.internalSubset = internalSubset;
1.49 daniel 1579: xmlDefaultSAXHandler.externalSubset = externalSubset;
1.10 daniel 1580: xmlDefaultSAXHandler.isStandalone = isStandalone;
1581: xmlDefaultSAXHandler.hasInternalSubset = hasInternalSubset;
1582: xmlDefaultSAXHandler.hasExternalSubset = hasExternalSubset;
1.2 daniel 1583: xmlDefaultSAXHandler.resolveEntity = resolveEntity;
1.10 daniel 1584: xmlDefaultSAXHandler.getEntity = getEntity;
1.20 daniel 1585: xmlDefaultSAXHandler.getParameterEntity = getParameterEntity;
1.10 daniel 1586: xmlDefaultSAXHandler.entityDecl = entityDecl;
1587: xmlDefaultSAXHandler.attributeDecl = attributeDecl;
1588: xmlDefaultSAXHandler.elementDecl = elementDecl;
1.2 daniel 1589: 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;
1.10 daniel 1596: xmlDefaultSAXHandler.reference = reference;
1.2 daniel 1597: xmlDefaultSAXHandler.characters = characters;
1.25 daniel 1598: xmlDefaultSAXHandler.cdataBlock = cdataBlock;
1.2 daniel 1599: xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1600: xmlDefaultSAXHandler.processingInstruction = processingInstruction;
1.10 daniel 1601: xmlDefaultSAXHandler.comment = comment;
1.47 daniel 1602: if (xmlGetWarningsDefaultValue == 0)
1603: xmlDefaultSAXHandler.warning = NULL;
1604: else
1605: xmlDefaultSAXHandler.warning = xmlParserWarning;
1.2 daniel 1606: xmlDefaultSAXHandler.error = xmlParserError;
1607: xmlDefaultSAXHandler.fatalError = xmlParserError;
1.18 daniel 1608: }
1609:
1610: /*
1611: * Default handler for HTML, builds the DOM tree
1612: */
1613: xmlSAXHandler htmlDefaultSAXHandler = {
1.66 daniel 1614: internalSubset,
1.18 daniel 1615: 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,
1.20 daniel 1638: getParameterEntity,
1.81 veillard 1639: cdataBlock,
1.49 daniel 1640: NULL,
1.18 daniel 1641: };
1642:
1643: /**
1644: * htmlDefaultSAXHandlerInit:
1645: *
1646: * Initialize the default SAX handler
1647: */
1648: void
1649: htmlDefaultSAXHandlerInit(void)
1650: {
1.66 daniel 1651: htmlDefaultSAXHandler.internalSubset = internalSubset;
1.49 daniel 1652: htmlDefaultSAXHandler.externalSubset = NULL;
1.18 daniel 1653: htmlDefaultSAXHandler.isStandalone = NULL;
1654: htmlDefaultSAXHandler.hasInternalSubset = NULL;
1655: htmlDefaultSAXHandler.hasExternalSubset = NULL;
1656: htmlDefaultSAXHandler.resolveEntity = NULL;
1657: htmlDefaultSAXHandler.getEntity = getEntity;
1.20 daniel 1658: htmlDefaultSAXHandler.getParameterEntity = NULL;
1.18 daniel 1659: 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;
1.84 ! veillard 1671: htmlDefaultSAXHandler.cdataBlock = cdataBlock;
1.18 daniel 1672: htmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1673: htmlDefaultSAXHandler.processingInstruction = NULL;
1674: htmlDefaultSAXHandler.comment = comment;
1675: htmlDefaultSAXHandler.warning = xmlParserWarning;
1676: htmlDefaultSAXHandler.error = xmlParserError;
1677: htmlDefaultSAXHandler.fatalError = xmlParserError;
1.2 daniel 1678: }
1.76 veillard 1679:
1680: /*
1681: * Default handler for HTML, builds the DOM tree
1682: */
1683: xmlSAXHandler 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: */
1718: void
1719: sgmlDefaultSAXHandlerInit(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: }
Webmaster