Annotation of XML/SAX.c, revision 1.80
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
164: fprintf(stderr, "SAX.internalSubset(%s, %s, %s)\n",
165: name, ExternalID, SystemID);
166: #endif
1.66 daniel 167:
1.67 daniel 168: if (ctxt->myDoc == NULL)
169: return;
1.66 daniel 170: dtd = xmlGetIntSubset(ctxt->myDoc);
171: if (dtd != NULL) {
1.72 veillard 172: if (ctxt->html)
173: return;
1.66 daniel 174: xmlUnlinkNode((xmlNodePtr) dtd);
175: xmlFreeDtd(dtd);
1.67 daniel 176: ctxt->myDoc->intSubset = NULL;
1.66 daniel 177: }
1.67 daniel 178: ctxt->myDoc->intSubset =
179: xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
1.49 daniel 180: }
181:
182: /**
183: * externalSubset:
184: * @ctx: the user data (XML parser context)
1.58 daniel 185: * @name: the root element name
186: * @ExternalID: the external ID
187: * @SystemID: the SYSTEM ID (e.g. filename or URL)
1.49 daniel 188: *
189: * Callback on external subset declaration.
190: */
191: void
192: externalSubset(void *ctx, const xmlChar *name,
193: const xmlChar *ExternalID, const xmlChar *SystemID)
194: {
195: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
196: #ifdef DEBUG_SAX
197: fprintf(stderr, "SAX.externalSubset(%s, %s, %s)\n",
198: name, ExternalID, SystemID);
199: #endif
1.24 daniel 200: if (((ExternalID != NULL) || (SystemID != NULL)) &&
201: (ctxt->validate && ctxt->wellFormed && ctxt->myDoc)) {
202: /*
203: * Try to fetch and parse the external subset.
204: */
1.49 daniel 205: xmlParserInputPtr oldinput;
206: int oldinputNr;
207: int oldinputMax;
208: xmlParserInputPtr *oldinputTab;
1.50 daniel 209: int oldwellFormed;
1.24 daniel 210: xmlParserInputPtr input = NULL;
211: xmlCharEncoding enc;
1.68 veillard 212: int oldcharset;
1.24 daniel 213:
214: /*
215: * Ask the Entity resolver to load the damn thing
216: */
1.49 daniel 217: if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
218: input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
1.24 daniel 219: SystemID);
220: if (input == NULL) {
221: return;
222: }
223:
1.50 daniel 224: xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
225:
1.49 daniel 226: /*
227: * make sure we won't destroy the main document context
228: */
229: oldinput = ctxt->input;
230: oldinputNr = ctxt->inputNr;
231: oldinputMax = ctxt->inputMax;
232: oldinputTab = ctxt->inputTab;
1.50 daniel 233: oldwellFormed = ctxt->wellFormed;
1.62 daniel 234: oldcharset = ctxt->charset;
1.49 daniel 235:
236: ctxt->inputTab = (xmlParserInputPtr *)
237: xmlMalloc(5 * sizeof(xmlParserInputPtr));
238: if (ctxt->inputTab == NULL) {
239: ctxt->errNo = XML_ERR_NO_MEMORY;
240: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
241: ctxt->sax->error(ctxt->userData,
242: "externalSubset: out of memory\n");
243: ctxt->errNo = XML_ERR_NO_MEMORY;
244: ctxt->input = oldinput;
245: ctxt->inputNr = oldinputNr;
246: ctxt->inputMax = oldinputMax;
247: ctxt->inputTab = oldinputTab;
1.62 daniel 248: ctxt->charset = oldcharset;
1.49 daniel 249: return;
250: }
251: ctxt->inputNr = 0;
252: ctxt->inputMax = 5;
253: ctxt->input = NULL;
254: xmlPushInput(ctxt, input);
1.43 daniel 255:
1.24 daniel 256: /*
1.43 daniel 257: * On the fly encoding conversion if needed
1.24 daniel 258: */
1.49 daniel 259: enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
260: xmlSwitchEncoding(ctxt, enc);
1.24 daniel 261:
262: if (input->filename == NULL)
1.28 daniel 263: input->filename = (char *) xmlStrdup(SystemID);
1.24 daniel 264: input->line = 1;
265: input->col = 1;
1.49 daniel 266: input->base = ctxt->input->cur;
267: input->cur = ctxt->input->cur;
1.24 daniel 268: input->free = NULL;
269:
270: /*
271: * let's parse that entity knowing it's an external subset.
272: */
1.49 daniel 273: xmlParseExternalSubset(ctxt, ExternalID, SystemID);
274:
275: /*
276: * Free up the external entities
277: */
1.24 daniel 278:
1.49 daniel 279: while (ctxt->inputNr > 1)
280: xmlPopInput(ctxt);
281: xmlFreeInputStream(ctxt->input);
282: xmlFree(ctxt->inputTab);
283:
284: /*
285: * Restore the parsing context of the main entity
286: */
287: ctxt->input = oldinput;
288: ctxt->inputNr = oldinputNr;
289: ctxt->inputMax = oldinputMax;
290: ctxt->inputTab = oldinputTab;
1.62 daniel 291: ctxt->charset = oldcharset;
1.52 daniel 292: /* ctxt->wellFormed = oldwellFormed; */
1.12 daniel 293: }
1.10 daniel 294: }
295:
296: /**
1.5 daniel 297: * resolveEntity:
1.16 daniel 298: * @ctx: the user data (XML parser context)
1.5 daniel 299: * @publicId: The public ID of the entity
300: * @systemId: The system ID of the entity
301: *
1.41 daniel 302: * The entity loader, to control the loading of external entities,
303: * the application can either:
304: * - override this resolveEntity() callback in the SAX block
305: * - or better use the xmlSetExternalEntityLoader() function to
306: * set up it's own entity resolution routine
1.5 daniel 307: *
1.8 daniel 308: * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1.5 daniel 309: */
310: xmlParserInputPtr
1.34 daniel 311: resolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
1.5 daniel 312: {
1.12 daniel 313: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.77 veillard 314: xmlParserInputPtr ret;
1.78 veillard 315: xmlChar *URI;
1.77 veillard 316: const char *base = NULL;
317:
318: if (ctxt->input != NULL)
319: base = ctxt->input->filename;
320: if (base == NULL)
321: base = ctxt->directory;
322:
1.78 veillard 323: URI = xmlBuildURI(systemId, (const xmlChar *) base);
1.2 daniel 324:
325: #ifdef DEBUG_SAX
326: fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
327: #endif
1.5 daniel 328:
1.77 veillard 329: ret = xmlLoadExternalEntity((const char *) URI,
330: (const char *) publicId, ctxt);
331: if (URI != NULL)
332: xmlFree(URI);
333: return(ret);
1.1 daniel 334: }
335:
1.5 daniel 336: /**
1.10 daniel 337: * getEntity:
1.16 daniel 338: * @ctx: the user data (XML parser context)
1.10 daniel 339: * @name: The entity name
340: *
341: * Get an entity by name
342: *
1.13 daniel 343: * Returns the xmlEntityPtr if found.
1.10 daniel 344: */
345: xmlEntityPtr
1.34 daniel 346: getEntity(void *ctx, const xmlChar *name)
1.10 daniel 347: {
1.11 daniel 348: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 349: xmlEntityPtr ret;
350:
351: #ifdef DEBUG_SAX
352: fprintf(stderr, "SAX.getEntity(%s)\n", name);
353: #endif
354:
355: ret = xmlGetDocEntity(ctxt->myDoc, name);
1.71 veillard 356: if ((ret != NULL) && (ctxt->validate) && (ret->children == NULL) &&
357: (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
358: /*
359: * for validation purposes we really need to fetch and
360: * parse the external entity
361: */
362: int parse;
363: xmlNodePtr children;
364:
365: parse = xmlParseCtxtExternalEntity(ctxt,
366: ret->SystemID, ret->ExternalID, &children);
367: xmlAddChildList((xmlNodePtr) ret, children);
368: }
1.10 daniel 369: return(ret);
370: }
371:
1.20 daniel 372: /**
373: * getParameterEntity:
374: * @ctx: the user data (XML parser context)
375: * @name: The entity name
376: *
377: * Get a parameter entity by name
378: *
379: * Returns the xmlEntityPtr if found.
380: */
381: xmlEntityPtr
1.34 daniel 382: getParameterEntity(void *ctx, const xmlChar *name)
1.20 daniel 383: {
384: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
385: xmlEntityPtr ret;
386:
387: #ifdef DEBUG_SAX
388: fprintf(stderr, "SAX.getParameterEntity(%s)\n", name);
389: #endif
390:
391: ret = xmlGetParameterEntity(ctxt->myDoc, name);
392: return(ret);
393: }
394:
1.10 daniel 395:
396: /**
397: * entityDecl:
1.16 daniel 398: * @ctx: the user data (XML parser context)
1.10 daniel 399: * @name: the entity name
400: * @type: the entity type
401: * @publicId: The public ID of the entity
402: * @systemId: The system ID of the entity
403: * @content: the entity value (without processing).
404: *
405: * An entity definition has been parsed
406: */
407: void
1.34 daniel 408: entityDecl(void *ctx, const xmlChar *name, int type,
409: const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1.10 daniel 410: {
1.73 veillard 411: xmlEntityPtr ent;
1.11 daniel 412: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 413:
414: #ifdef DEBUG_SAX
415: fprintf(stderr, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
416: name, type, publicId, systemId, content);
417: #endif
1.73 veillard 418: if (ctxt->inSubset == 1) {
419: ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
1.51 daniel 420: systemId, content);
1.73 veillard 421: if ((ent == NULL) && (ctxt->pedantic) &&
422: (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
423: ctxt->sax->warning(ctxt,
424: "Entity(%s) already defined in the internal subset\n", name);
1.77 veillard 425: if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
1.78 veillard 426: xmlChar *URI;
1.77 veillard 427: const char *base = NULL;
428:
429: if (ctxt->input != NULL)
430: base = ctxt->input->filename;
431: if (base == NULL)
432: base = ctxt->directory;
433:
1.78 veillard 434: URI = xmlBuildURI(systemId, (const xmlChar *) base);
1.77 veillard 435: ent->URI = URI;
436: }
1.73 veillard 437: } else if (ctxt->inSubset == 2) {
438: ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
1.51 daniel 439: systemId, content);
1.73 veillard 440: if ((ent == NULL) && (ctxt->pedantic) &&
441: (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
442: ctxt->sax->warning(ctxt,
443: "Entity(%s) already defined in the external subset\n", name);
1.77 veillard 444: if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
1.78 veillard 445: xmlChar *URI;
1.77 veillard 446: const char *base = NULL;
447:
448: if (ctxt->input != NULL)
449: base = ctxt->input->filename;
450: if (base == NULL)
451: base = ctxt->directory;
452:
1.78 veillard 453: URI = xmlBuildURI(systemId, (const xmlChar *) base);
1.77 veillard 454: ent->URI = URI;
455: }
1.73 veillard 456: } else {
1.50 daniel 457: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
458: ctxt->sax->error(ctxt,
459: "SAX.entityDecl(%s) called while not in subset\n", name);
460: }
1.10 daniel 461: }
462:
463: /**
464: * attributeDecl:
1.16 daniel 465: * @ctx: the user data (XML parser context)
1.58 daniel 466: * @elem: the name of the element
1.48 daniel 467: * @fullname: the attribute name
1.10 daniel 468: * @type: the attribute type
1.58 daniel 469: * @def: the type of default value
470: * @defaultValue: the attribute default value
471: * @tree: the tree of enumerated value set
1.10 daniel 472: *
473: * An attribute definition has been parsed
474: */
475: void
1.48 daniel 476: attributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
1.34 daniel 477: int type, int def, const xmlChar *defaultValue,
1.10 daniel 478: xmlEnumerationPtr tree)
479: {
1.11 daniel 480: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.21 daniel 481: xmlAttributePtr attr;
1.48 daniel 482: xmlChar *name = NULL, *prefix = NULL;
1.10 daniel 483:
484: #ifdef DEBUG_SAX
485: fprintf(stderr, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1.48 daniel 486: elem, fullname, type, def, defaultValue);
1.10 daniel 487: #endif
1.48 daniel 488: name = xmlSplitQName(ctxt, fullname, &prefix);
1.50 daniel 489: if (ctxt->inSubset == 1)
490: attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
1.68 veillard 491: name, prefix, (xmlAttributeType) type,
492: (xmlAttributeDefault) def, defaultValue, tree);
1.50 daniel 493: else if (ctxt->inSubset == 2)
494: attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
1.68 veillard 495: name, prefix, (xmlAttributeType) type,
496: (xmlAttributeDefault) def, defaultValue, tree);
1.50 daniel 497: else {
498: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
499: ctxt->sax->error(ctxt,
500: "SAX.attributeDecl(%s) called while not in subset\n", name);
501: return;
502: }
1.21 daniel 503: if (attr == 0) ctxt->valid = 0;
1.23 daniel 504: if (ctxt->validate && ctxt->wellFormed &&
505: ctxt->myDoc && ctxt->myDoc->intSubset)
1.21 daniel 506: ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
507: attr);
1.48 daniel 508: if (prefix != NULL)
509: xmlFree(prefix);
510: if (name != NULL)
511: xmlFree(name);
1.10 daniel 512: }
513:
514: /**
515: * elementDecl:
1.16 daniel 516: * @ctx: the user data (XML parser context)
1.10 daniel 517: * @name: the element name
518: * @type: the element type
1.58 daniel 519: * @content: the element value tree
1.10 daniel 520: *
521: * An element definition has been parsed
522: */
523: void
1.34 daniel 524: elementDecl(void *ctx, const xmlChar *name, int type,
1.10 daniel 525: xmlElementContentPtr content)
526: {
1.11 daniel 527: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.50 daniel 528: xmlElementPtr elem = NULL;
1.10 daniel 529:
530: #ifdef DEBUG_SAX
531: fprintf(stderr, "SAX.elementDecl(%s, %d, ...)\n",
1.48 daniel 532: fullname, type);
1.10 daniel 533: #endif
1.21 daniel 534:
1.50 daniel 535: if (ctxt->inSubset == 1)
536: elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
1.68 veillard 537: name, (xmlElementTypeVal) type, content);
1.50 daniel 538: else if (ctxt->inSubset == 2)
539: elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
1.68 veillard 540: name, (xmlElementTypeVal) type, content);
1.50 daniel 541: else {
542: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
543: ctxt->sax->error(ctxt,
544: "SAX.elementDecl(%s) called while not in subset\n", name);
545: return;
546: }
547: if (elem == NULL) ctxt->valid = 0;
1.23 daniel 548: if (ctxt->validate && ctxt->wellFormed &&
549: ctxt->myDoc && ctxt->myDoc->intSubset)
1.21 daniel 550: ctxt->valid &= xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
1.10 daniel 551: }
552:
553: /**
1.5 daniel 554: * notationDecl:
1.16 daniel 555: * @ctx: the user data (XML parser context)
1.5 daniel 556: * @name: The name of the notation
557: * @publicId: The public ID of the entity
558: * @systemId: The system ID of the entity
559: *
1.1 daniel 560: * What to do when a notation declaration has been parsed.
561: */
1.5 daniel 562: void
1.34 daniel 563: notationDecl(void *ctx, const xmlChar *name,
564: const xmlChar *publicId, const xmlChar *systemId)
1.5 daniel 565: {
1.11 daniel 566: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.50 daniel 567: xmlNotationPtr nota = NULL;
1.21 daniel 568:
1.2 daniel 569: #ifdef DEBUG_SAX
570: fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
571: #endif
1.21 daniel 572:
1.50 daniel 573: if (ctxt->inSubset == 1)
574: nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
575: publicId, systemId);
576: else if (ctxt->inSubset == 2)
577: nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
1.21 daniel 578: publicId, systemId);
1.50 daniel 579: else {
580: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
581: ctxt->sax->error(ctxt,
582: "SAX.notationDecl(%s) called while not in subset\n", name);
583: return;
584: }
585: if (nota == NULL) ctxt->valid = 0;
1.23 daniel 586: if (ctxt->validate && ctxt->wellFormed &&
587: ctxt->myDoc && ctxt->myDoc->intSubset)
1.21 daniel 588: ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
589: nota);
1.1 daniel 590: }
591:
1.5 daniel 592: /**
593: * unparsedEntityDecl:
1.16 daniel 594: * @ctx: the user data (XML parser context)
1.5 daniel 595: * @name: The name of the entity
596: * @publicId: The public ID of the entity
597: * @systemId: The system ID of the entity
598: * @notationName: the name of the notation
599: *
1.1 daniel 600: * What to do when an unparsed entity declaration is parsed
601: */
1.5 daniel 602: void
1.34 daniel 603: unparsedEntityDecl(void *ctx, const xmlChar *name,
604: const xmlChar *publicId, const xmlChar *systemId,
605: const xmlChar *notationName)
1.5 daniel 606: {
1.28 daniel 607: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2 daniel 608: #ifdef DEBUG_SAX
609: fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
610: name, publicId, systemId, notationName);
611: #endif
1.28 daniel 612: if (ctxt->validate && ctxt->wellFormed &&
613: ctxt->myDoc && ctxt->myDoc->intSubset)
614: ctxt->valid &= xmlValidateNotationUse(&ctxt->vctxt, ctxt->myDoc,
615: notationName);
616: xmlAddDocEntity(ctxt->myDoc, name,
617: XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
618: publicId, systemId, notationName);
1.1 daniel 619: }
620:
1.5 daniel 621: /**
622: * setDocumentLocator:
1.16 daniel 623: * @ctx: the user data (XML parser context)
1.5 daniel 624: * @loc: A SAX Locator
625: *
1.1 daniel 626: * Receive the document locator at startup, actually xmlDefaultSAXLocator
627: * Everything is available on the context, so this is useless in our case.
628: */
1.5 daniel 629: void
1.11 daniel 630: setDocumentLocator(void *ctx, xmlSAXLocatorPtr loc)
1.5 daniel 631: {
1.11 daniel 632: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2 daniel 633: #ifdef DEBUG_SAX
634: fprintf(stderr, "SAX.setDocumentLocator()\n");
635: #endif
1.1 daniel 636: }
637:
1.5 daniel 638: /**
639: * startDocument:
1.16 daniel 640: * @ctx: the user data (XML parser context)
1.5 daniel 641: *
1.1 daniel 642: * called when the document start being processed.
643: */
1.5 daniel 644: void
1.11 daniel 645: startDocument(void *ctx)
1.5 daniel 646: {
1.11 daniel 647: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 648: xmlDocPtr doc;
649:
1.2 daniel 650: #ifdef DEBUG_SAX
651: fprintf(stderr, "SAX.startDocument()\n");
652: #endif
1.66 daniel 653: if (ctxt->html) {
654: if (ctxt->myDoc == NULL)
1.69 veillard 655: #ifdef LIBXML_HTML_ENABLED
1.72 veillard 656: ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
1.69 veillard 657: #else
658: fprintf(stderr, "libxml2 built without HTML support\n");
659: #endif
1.66 daniel 660: } else {
661: doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
662: if (doc != NULL) {
663: if (ctxt->encoding != NULL)
664: doc->encoding = xmlStrdup(ctxt->encoding);
665: else
666: doc->encoding = NULL;
667: doc->standalone = ctxt->standalone;
668: }
1.10 daniel 669: }
1.70 veillard 670: if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
671: (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
672: ctxt->myDoc->URL = xmlStrdup((xmlChar *) ctxt->input->filename);
673: }
1.1 daniel 674: }
675:
1.5 daniel 676: /**
677: * endDocument:
1.16 daniel 678: * @ctx: the user data (XML parser context)
1.5 daniel 679: *
1.1 daniel 680: * called when the document end has been detected.
681: */
1.5 daniel 682: void
1.11 daniel 683: endDocument(void *ctx)
1.5 daniel 684: {
1.31 daniel 685: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2 daniel 686: #ifdef DEBUG_SAX
687: fprintf(stderr, "SAX.endDocument()\n");
688: #endif
1.31 daniel 689: if (ctxt->validate && ctxt->wellFormed &&
690: ctxt->myDoc && ctxt->myDoc->intSubset)
691: ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
1.59 daniel 692:
693: /*
694: * Grab the encoding if it was added on-the-fly
695: */
696: if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
697: (ctxt->myDoc->encoding == NULL)) {
698: ctxt->myDoc->encoding = ctxt->encoding;
699: ctxt->encoding = NULL;
700: }
1.62 daniel 701: if ((ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
702: (ctxt->myDoc->encoding == NULL)) {
703: ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
704: }
705: if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
706: (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
707: ctxt->myDoc->charset = ctxt->charset;
708: }
1.1 daniel 709: }
710:
1.5 daniel 711: /**
1.10 daniel 712: * attribute:
1.16 daniel 713: * @ctx: the user data (XML parser context)
1.58 daniel 714: * @fullname: The attribute name, including namespace prefix
1.10 daniel 715: * @value: The attribute value
716: *
717: * Handle an attribute that has been read by the parser.
718: * The default handling is to convert the attribute into an
719: * DOM subtree and past it in a new xmlAttr element added to
720: * the element.
721: */
722: void
1.34 daniel 723: attribute(void *ctx, const xmlChar *fullname, const xmlChar *value)
1.10 daniel 724: {
1.11 daniel 725: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 726: xmlAttrPtr ret;
1.34 daniel 727: xmlChar *name;
728: xmlChar *ns;
1.56 daniel 729: xmlChar *nval;
1.29 daniel 730: xmlNsPtr namespace;
1.10 daniel 731:
732: /****************
733: #ifdef DEBUG_SAX
734: fprintf(stderr, "SAX.attribute(%s, %s)\n", fullname, value);
735: #endif
736: ****************/
737: /*
738: * Split the full name into a namespace prefix and the tag name
739: */
1.48 daniel 740: name = xmlSplitQName(ctxt, fullname, &ns);
1.10 daniel 741:
742: /*
1.55 daniel 743: * Do the last stave of the attribute normalization
744: */
1.65 daniel 745: if (ctxt->html)
746: nval = NULL;
747: else
748: nval = xmlValidNormalizeAttributeValue(ctxt->myDoc,
1.56 daniel 749: ctxt->node, fullname, value);
750: if (nval != NULL)
751: value = nval;
1.55 daniel 752:
753: /*
1.10 daniel 754: * Check whether it's a namespace definition
755: */
1.65 daniel 756: if ((!ctxt->html) && (ns == NULL) &&
1.10 daniel 757: (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
758: (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
1.60 daniel 759: xmlURIPtr uri;
760:
761: uri = xmlParseURI((const char *)value);
762: if (uri == NULL) {
763: if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
764: ctxt->sax->warning(ctxt->userData,
765: "nmlns: %s not a valid URI\n", value);
766: } else {
1.61 daniel 767: if (uri->scheme == NULL) {
1.60 daniel 768: if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
769: ctxt->sax->warning(ctxt->userData,
770: "nmlns: URI %s is not absolute\n", value);
771: }
772: xmlFreeURI(uri);
773: }
774:
1.10 daniel 775: /* a default namespace definition */
776: xmlNewNs(ctxt->node, value, NULL);
777: if (name != NULL)
1.30 daniel 778: xmlFree(name);
1.55 daniel 779: if (nval != NULL)
780: xmlFree(nval);
1.10 daniel 781: return;
782: }
1.65 daniel 783: if ((!ctxt->html) &&
784: (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
1.10 daniel 785: (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
1.54 daniel 786: /*
787: * Validate also for namespace decls, they are attributes from
788: * an XML-1.0 perspective
789: TODO ... doesn't map well with current API
790: if (ctxt->validate && ctxt->wellFormed &&
791: ctxt->myDoc && ctxt->myDoc->intSubset)
792: ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
793: ctxt->node, ret, value);
794: */
1.10 daniel 795: /* a standard namespace definition */
796: xmlNewNs(ctxt->node, value, name);
1.30 daniel 797: xmlFree(ns);
1.10 daniel 798: if (name != NULL)
1.30 daniel 799: xmlFree(name);
1.55 daniel 800: if (nval != NULL)
801: xmlFree(nval);
1.10 daniel 802: return;
803: }
804:
1.38 daniel 805: if (ns != NULL)
806: namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
807: else {
808: namespace = NULL;
809: }
810:
1.29 daniel 811: /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
812: ret = xmlNewNsProp(ctxt->node, namespace, name, NULL);
1.22 daniel 813:
1.26 daniel 814: if (ret != NULL) {
1.46 daniel 815: if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
816: xmlNodePtr tmp;
817:
1.44 daniel 818: ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
1.46 daniel 819: tmp = ret->children;
820: while (tmp != NULL) {
821: tmp->parent = (xmlNodePtr) ret;
822: if (tmp->next == NULL)
823: ret->last = tmp;
824: tmp = tmp->next;
825: }
1.65 daniel 826: } else if (value != NULL) {
1.44 daniel 827: ret->children = xmlNewDocText(ctxt->myDoc, value);
1.46 daniel 828: ret->last = ret->children;
829: if (ret->children != NULL)
830: ret->children->parent = (xmlNodePtr) ret;
831: }
1.26 daniel 832: }
1.22 daniel 833:
1.65 daniel 834: if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
1.56 daniel 835: ctxt->myDoc && ctxt->myDoc->intSubset) {
836:
837: /*
838: * If we don't substitute entities, the validation should be
839: * done on a value with replaced entities anyway.
840: */
841: if (!ctxt->replaceEntities) {
842: xmlChar *val;
843:
844: ctxt->depth++;
845: val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
846: 0,0,0);
847: ctxt->depth--;
848: if (val == NULL)
849: ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
850: ctxt->myDoc, ctxt->node, ret, value);
851: else {
852: ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
853: ctxt->myDoc, ctxt->node, ret, val);
854: xmlFree(val);
855: }
856: } else {
857: ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
1.22 daniel 858: ctxt->node, ret, value);
1.56 daniel 859: }
860: } else {
1.26 daniel 861: /*
862: * when validating, the ID registration is done at the attribute
863: * validation level. Otherwise we have to do specific handling here.
864: */
865: if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
866: xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
1.31 daniel 867: else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
868: xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
1.26 daniel 869: }
1.22 daniel 870:
1.55 daniel 871: if (nval != NULL)
872: xmlFree(nval);
1.10 daniel 873: if (name != NULL)
1.30 daniel 874: xmlFree(name);
1.10 daniel 875: if (ns != NULL)
1.30 daniel 876: xmlFree(ns);
1.10 daniel 877: }
878:
879: /**
1.5 daniel 880: * startElement:
1.16 daniel 881: * @ctx: the user data (XML parser context)
1.58 daniel 882: * @fullname: The element name, including namespace prefix
1.10 daniel 883: * @atts: An array of name/value attributes pairs, NULL terminated
1.5 daniel 884: *
1.1 daniel 885: * called when an opening tag has been processed.
886: */
1.5 daniel 887: void
1.34 daniel 888: startElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
1.5 daniel 889: {
1.11 daniel 890: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 891: xmlNodePtr ret;
892: xmlNodePtr parent = ctxt->node;
893: xmlNsPtr ns;
1.34 daniel 894: xmlChar *name;
895: xmlChar *prefix;
896: const xmlChar *att;
897: const xmlChar *value;
1.10 daniel 898: int i;
899:
1.2 daniel 900: #ifdef DEBUG_SAX
1.10 daniel 901: fprintf(stderr, "SAX.startElement(%s)\n", fullname);
1.2 daniel 902: #endif
1.33 daniel 903:
904: /*
905: * First check on validity:
906: */
907: if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
908: ((ctxt->myDoc->intSubset == NULL) ||
909: ((ctxt->myDoc->intSubset->notations == NULL) &&
910: (ctxt->myDoc->intSubset->elements == NULL) &&
911: (ctxt->myDoc->intSubset->attributes == NULL) &&
912: (ctxt->myDoc->intSubset->entities == NULL)))) {
913: if (ctxt->vctxt.error != NULL) {
914: ctxt->vctxt.error(ctxt->vctxt.userData,
915: "Validation failed: no DTD found !\n");
916: }
917: ctxt->validate = 0;
918: }
919:
920:
1.10 daniel 921: /*
922: * Split the full name into a namespace prefix and the tag name
923: */
1.48 daniel 924: name = xmlSplitQName(ctxt, fullname, &prefix);
1.10 daniel 925:
926:
927: /*
928: * Note : the namespace resolution is deferred until the end of the
929: * attributes parsing, since local namespace can be defined as
930: * an attribute at this level.
931: */
932: ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
933: if (ret == NULL) return;
1.44 daniel 934: if (ctxt->myDoc->children == NULL) {
1.26 daniel 935: #ifdef DEBUG_SAX_TREE
936: fprintf(stderr, "Setting %s as root\n", name);
937: #endif
1.45 daniel 938: xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1.26 daniel 939: } else if (parent == NULL) {
1.44 daniel 940: parent = ctxt->myDoc->children;
1.26 daniel 941: }
1.63 daniel 942: ctxt->nodemem = -1;
1.10 daniel 943:
944: /*
945: * We are parsing a new node.
946: */
1.26 daniel 947: #ifdef DEBUG_SAX_TREE
948: fprintf(stderr, "pushing(%s)\n", name);
949: #endif
1.10 daniel 950: nodePush(ctxt, ret);
951:
952: /*
953: * Link the child element
954: */
1.26 daniel 955: if (parent != NULL) {
956: if (parent->type == XML_ELEMENT_NODE) {
957: #ifdef DEBUG_SAX_TREE
958: fprintf(stderr, "adding child %s to %s\n", name, parent->name);
959: #endif
960: xmlAddChild(parent, ret);
961: } else {
962: #ifdef DEBUG_SAX_TREE
963: fprintf(stderr, "adding sibling %s to ", name);
964: xmlDebugDumpOneNode(stderr, parent, 0);
965: #endif
966: xmlAddSibling(parent, ret);
967: }
968: }
1.10 daniel 969:
1.54 daniel 970: /*
1.29 daniel 971: * process all the attributes whose name start with "xml"
1.10 daniel 972: */
973: if (atts != NULL) {
974: i = 0;
975: att = atts[i++];
976: value = atts[i++];
1.65 daniel 977: if (!ctxt->html) {
978: while ((att != NULL) && (value != NULL)) {
979: if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l'))
980: attribute(ctxt, att, value);
1.29 daniel 981:
1.65 daniel 982: att = atts[i++];
983: value = atts[i++];
984: }
1.29 daniel 985: }
986: }
987:
988: /*
1.64 daniel 989: * Search the namespace, note that since the attributes have been
990: * processed, the local namespaces are available.
991: */
992: ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
993: if ((ns == NULL) && (parent != NULL))
994: ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
1.75 veillard 995: if ((prefix != NULL) && (ns == NULL)) {
996: ns = xmlNewNs(ret, NULL, prefix);
997: if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
998: ctxt->sax->warning(ctxt->userData,
999: "Namespace prefix %s is not defined\n", prefix);
1000: }
1.64 daniel 1001: xmlSetNs(ret, ns);
1002:
1003: /*
1.29 daniel 1004: * process all the other attributes
1005: */
1006: if (atts != NULL) {
1007: i = 0;
1008: att = atts[i++];
1009: value = atts[i++];
1.65 daniel 1010: if (ctxt->html) {
1011: while (att != NULL) {
1.29 daniel 1012: attribute(ctxt, att, value);
1.65 daniel 1013: att = atts[i++];
1014: value = atts[i++];
1015: }
1016: } else {
1017: while ((att != NULL) && (value != NULL)) {
1018: if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l'))
1019: attribute(ctxt, att, value);
1020:
1021: /*
1022: * Next ones
1023: */
1024: att = atts[i++];
1025: value = atts[i++];
1026: }
1.10 daniel 1027: }
1028: }
1029:
1030: /*
1.64 daniel 1031: * If it's the Document root, finish the Dtd validation and
1032: * check the document root element for validity
1.10 daniel 1033: */
1.64 daniel 1034: if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) {
1035: ctxt->valid &= xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
1036: ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
1037: ctxt->vctxt.finishDtd = 1;
1038: }
1.10 daniel 1039:
1040: if (prefix != NULL)
1.30 daniel 1041: xmlFree(prefix);
1.10 daniel 1042: if (name != NULL)
1.30 daniel 1043: xmlFree(name);
1.10 daniel 1044:
1.1 daniel 1045: }
1046:
1.5 daniel 1047: /**
1048: * endElement:
1.16 daniel 1049: * @ctx: the user data (XML parser context)
1.5 daniel 1050: * @name: The element name
1051: *
1.1 daniel 1052: * called when the end of an element has been detected.
1053: */
1.5 daniel 1054: void
1.34 daniel 1055: endElement(void *ctx, const xmlChar *name)
1.5 daniel 1056: {
1.11 daniel 1057: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 1058: xmlParserNodeInfo node_info;
1059: xmlNodePtr cur = ctxt->node;
1060:
1.2 daniel 1061: #ifdef DEBUG_SAX
1.10 daniel 1062: if (name == NULL)
1063: fprintf(stderr, "SAX.endElement(NULL)\n");
1064: else
1065: fprintf(stderr, "SAX.endElement(%s)\n", name);
1066: #endif
1067:
1068: /* Capture end position and add node */
1069: if (cur != NULL && ctxt->record_info) {
1070: node_info.end_pos = ctxt->input->cur - ctxt->input->base;
1071: node_info.end_line = ctxt->input->line;
1072: node_info.node = cur;
1073: xmlParserAddNodeInfo(ctxt, &node_info);
1074: }
1.63 daniel 1075: ctxt->nodemem = -1;
1.10 daniel 1076:
1.23 daniel 1077: if (ctxt->validate && ctxt->wellFormed &&
1078: ctxt->myDoc && ctxt->myDoc->intSubset)
1.22 daniel 1079: ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
1080: cur);
1081:
1082:
1.10 daniel 1083: /*
1084: * end of parsing of this node.
1085: */
1.26 daniel 1086: #ifdef DEBUG_SAX_TREE
1087: fprintf(stderr, "popping(%s)\n", cur->name);
1088: #endif
1.10 daniel 1089: nodePop(ctxt);
1.1 daniel 1090: }
1091:
1.5 daniel 1092: /**
1.10 daniel 1093: * reference:
1.16 daniel 1094: * @ctx: the user data (XML parser context)
1.10 daniel 1095: * @name: The entity name
1.5 daniel 1096: *
1.10 daniel 1097: * called when an entity reference is detected.
1.5 daniel 1098: */
1099: void
1.34 daniel 1100: reference(void *ctx, const xmlChar *name)
1.5 daniel 1101: {
1.11 daniel 1102: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 1103: xmlNodePtr ret;
1104:
1.5 daniel 1105: #ifdef DEBUG_SAX
1.10 daniel 1106: fprintf(stderr, "SAX.reference(%s)\n", name);
1.5 daniel 1107: #endif
1.42 daniel 1108: if (name[0] == '#')
1109: ret = xmlNewCharRef(ctxt->myDoc, name);
1110: else
1111: ret = xmlNewReference(ctxt->myDoc, name);
1.26 daniel 1112: #ifdef DEBUG_SAX_TREE
1113: fprintf(stderr, "add reference %s to %s \n", name, ctxt->node->name);
1114: #endif
1.10 daniel 1115: xmlAddChild(ctxt->node, ret);
1.5 daniel 1116: }
1117:
1118: /**
1119: * characters:
1.16 daniel 1120: * @ctx: the user data (XML parser context)
1.34 daniel 1121: * @ch: a xmlChar string
1122: * @len: the number of xmlChar
1.5 daniel 1123: *
1.1 daniel 1124: * receiving some chars from the parser.
1125: * Question: how much at a time ???
1126: */
1.5 daniel 1127: void
1.34 daniel 1128: characters(void *ctx, const xmlChar *ch, int len)
1.5 daniel 1129: {
1.11 daniel 1130: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2 daniel 1131: xmlNodePtr lastChild;
1132:
1133: #ifdef DEBUG_SAX
1.10 daniel 1134: fprintf(stderr, "SAX.characters(%.30s, %d)\n", ch, len);
1.2 daniel 1135: #endif
1136: /*
1137: * Handle the data if any. If there is no child
1138: * add it as content, otherwise if the last child is text,
1139: * concatenate it, else create a new node of type text.
1140: */
1141:
1.36 daniel 1142: if (ctxt->node == NULL) {
1143: #ifdef DEBUG_SAX_TREE
1144: fprintf(stderr, "add chars: ctxt->node == NULL !\n");
1145: #endif
1146: return;
1147: }
1.2 daniel 1148: lastChild = xmlGetLastChild(ctxt->node);
1.26 daniel 1149: #ifdef DEBUG_SAX_TREE
1150: fprintf(stderr, "add chars to %s \n", ctxt->node->name);
1151: #endif
1.62 daniel 1152:
1153: /*
1154: * Here we needed an accelerator mechanism in case of very large
1155: * elements. Use an attribute in the structure !!!
1156: */
1.63 daniel 1157: if (lastChild == NULL) {
1158: /* first node, first time */
1.10 daniel 1159: xmlNodeAddContentLen(ctxt->node, ch, len);
1.63 daniel 1160: #ifndef XML_USE_BUFFER_CONTENT
1161: if (ctxt->node->children != NULL) {
1162: ctxt->nodelen = len;
1163: ctxt->nodemem = len + 1;
1164: }
1165: #endif
1166: } else {
1.74 veillard 1167: if ((xmlNodeIsText(lastChild)) && (ctxt->nodemem != 0)) {
1.63 daniel 1168: #ifndef XML_USE_BUFFER_CONTENT
1169: /*
1170: * The whole point of maintaining nodelen and nodemem,
1171: * xmlTextConcat is too costly, i.e. compute lenght,
1172: * reallocate a new buffer, move data, append ch. Here
1173: * We try to minimaze realloc() uses and avoid copying
1174: * and recomputing lenght over and over.
1175: */
1176: if (ctxt->nodelen + len >= ctxt->nodemem) {
1177: xmlChar *newbuf;
1178: int size;
1179:
1180: size = ctxt->nodemem + len;
1181: size *= 2;
1182: newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
1183: if (newbuf == NULL) {
1184: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1185: ctxt->sax->error(ctxt->userData,
1186: "SAX.characters(): out of memory\n");
1187: return;
1188: }
1189: ctxt->nodemem = size;
1190: lastChild->content = newbuf;
1191: }
1192: memcpy(&lastChild->content[ctxt->nodelen], ch, len);
1193: ctxt->nodelen += len;
1194: lastChild->content[ctxt->nodelen] = 0;
1195: #else
1.10 daniel 1196: xmlTextConcat(lastChild, ch, len);
1.63 daniel 1197: #endif
1.62 daniel 1198: } else {
1.63 daniel 1199: /* Mixed content, first time */
1.10 daniel 1200: lastChild = xmlNewTextLen(ch, len);
1.2 daniel 1201: xmlAddChild(ctxt->node, lastChild);
1.63 daniel 1202: #ifndef XML_USE_BUFFER_CONTENT
1203: if (ctxt->node->children != NULL) {
1204: ctxt->nodelen = len;
1205: ctxt->nodemem = len + 1;
1206: }
1207: #endif
1.2 daniel 1208: }
1209: }
1.1 daniel 1210: }
1211:
1.5 daniel 1212: /**
1213: * ignorableWhitespace:
1.16 daniel 1214: * @ctx: the user data (XML parser context)
1.34 daniel 1215: * @ch: a xmlChar string
1216: * @len: the number of xmlChar
1.5 daniel 1217: *
1.1 daniel 1218: * receiving some ignorable whitespaces from the parser.
1219: * Question: how much at a time ???
1220: */
1.5 daniel 1221: void
1.34 daniel 1222: ignorableWhitespace(void *ctx, const xmlChar *ch, int len)
1.5 daniel 1223: {
1.11 daniel 1224: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2 daniel 1225: #ifdef DEBUG_SAX
1.10 daniel 1226: fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
1.2 daniel 1227: #endif
1.1 daniel 1228: }
1229:
1.5 daniel 1230: /**
1231: * processingInstruction:
1.16 daniel 1232: * @ctx: the user data (XML parser context)
1.5 daniel 1233: * @target: the target name
1234: * @data: the PI data's
1235: *
1236: * A processing instruction has been parsed.
1237: */
1238: void
1.34 daniel 1239: processingInstruction(void *ctx, const xmlChar *target,
1240: const xmlChar *data)
1.5 daniel 1241: {
1.26 daniel 1242: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1243: xmlNodePtr ret;
1244: xmlNodePtr parent = ctxt->node;
1245:
1.2 daniel 1246: #ifdef DEBUG_SAX
1247: fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
1248: #endif
1.26 daniel 1249:
1250: ret = xmlNewPI(target, data);
1251: if (ret == NULL) return;
1.53 daniel 1252: parent = ctxt->node;
1253:
1254: if (ctxt->inSubset == 1) {
1255: xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
1256: return;
1257: } else if (ctxt->inSubset == 2) {
1258: xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
1259: return;
1260: }
1261: if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
1.26 daniel 1262: #ifdef DEBUG_SAX_TREE
1263: fprintf(stderr, "Setting PI %s as root\n", target);
1264: #endif
1.45 daniel 1265: xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1.53 daniel 1266: return;
1.26 daniel 1267: }
1.53 daniel 1268: if (parent->type == XML_ELEMENT_NODE) {
1.26 daniel 1269: #ifdef DEBUG_SAX_TREE
1.53 daniel 1270: fprintf(stderr, "adding PI %s child to %s\n", target, parent->name);
1.26 daniel 1271: #endif
1.53 daniel 1272: xmlAddChild(parent, ret);
1273: } else {
1.26 daniel 1274: #ifdef DEBUG_SAX_TREE
1.53 daniel 1275: fprintf(stderr, "adding PI %s sibling to ", target);
1276: xmlDebugDumpOneNode(stderr, parent, 0);
1.26 daniel 1277: #endif
1.53 daniel 1278: xmlAddSibling(parent, ret);
1.26 daniel 1279: }
1.1 daniel 1280: }
1281:
1.10 daniel 1282: /**
1283: * globalNamespace:
1.16 daniel 1284: * @ctx: the user data (XML parser context)
1.10 daniel 1285: * @href: the namespace associated URN
1286: * @prefix: the namespace prefix
1287: *
1288: * An old global namespace has been parsed.
1289: */
1290: void
1.34 daniel 1291: globalNamespace(void *ctx, const xmlChar *href, const xmlChar *prefix)
1.10 daniel 1292: {
1.11 daniel 1293: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 1294: #ifdef DEBUG_SAX
1295: fprintf(stderr, "SAX.globalNamespace(%s, %s)\n", href, prefix);
1296: #endif
1297: xmlNewGlobalNs(ctxt->myDoc, href, prefix);
1298: }
1299:
1300: /**
1301: * setNamespace:
1.16 daniel 1302: * @ctx: the user data (XML parser context)
1.10 daniel 1303: * @name: the namespace prefix
1304: *
1305: * Set the current element namespace.
1306: */
1.58 daniel 1307:
1.10 daniel 1308: void
1.34 daniel 1309: setNamespace(void *ctx, const xmlChar *name)
1.10 daniel 1310: {
1.11 daniel 1311: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 1312: xmlNsPtr ns;
1313: xmlNodePtr parent;
1314:
1315: #ifdef DEBUG_SAX
1316: fprintf(stderr, "SAX.setNamespace(%s)\n", name);
1317: #endif
1318: ns = xmlSearchNs(ctxt->myDoc, ctxt->node, name);
1319: if (ns == NULL) { /* ctxt->node may not have a parent yet ! */
1320: if (ctxt->nodeNr >= 2) {
1321: parent = ctxt->nodeTab[ctxt->nodeNr - 2];
1322: if (parent != NULL)
1323: ns = xmlSearchNs(ctxt->myDoc, parent, name);
1324: }
1325: }
1326: xmlSetNs(ctxt->node, ns);
1327: }
1328:
1329: /**
1330: * getNamespace:
1.16 daniel 1331: * @ctx: the user data (XML parser context)
1.10 daniel 1332: *
1333: * Get the current element namespace.
1.58 daniel 1334: *
1335: * Returns the xmlNsPtr or NULL if none
1.10 daniel 1336: */
1.58 daniel 1337:
1.10 daniel 1338: xmlNsPtr
1.11 daniel 1339: getNamespace(void *ctx)
1.10 daniel 1340: {
1.11 daniel 1341: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 1342: xmlNsPtr ret;
1343:
1344: #ifdef DEBUG_SAX
1345: fprintf(stderr, "SAX.getNamespace()\n");
1346: #endif
1347: ret = ctxt->node->ns;
1348: return(ret);
1349: }
1350:
1351: /**
1352: * checkNamespace:
1.16 daniel 1353: * @ctx: the user data (XML parser context)
1.10 daniel 1354: * @namespace: the namespace to check against
1355: *
1356: * Check that the current element namespace is the same as the
1357: * one read upon parsing.
1.58 daniel 1358: *
1359: * Returns 1 if true 0 otherwise
1.10 daniel 1360: */
1.58 daniel 1361:
1.10 daniel 1362: int
1.34 daniel 1363: checkNamespace(void *ctx, xmlChar *namespace)
1.10 daniel 1364: {
1.11 daniel 1365: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 1366: xmlNodePtr cur = ctxt->node;
1367:
1368: #ifdef DEBUG_SAX
1369: fprintf(stderr, "SAX.checkNamespace(%s)\n", namespace);
1370: #endif
1371:
1372: /*
1373: * Check that the Name in the ETag is the same as in the STag.
1374: */
1375: if (namespace == NULL) {
1376: if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
1377: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1378: ctxt->sax->error(ctxt,
1379: "End tags for %s don't hold the namespace %s\n",
1380: cur->name, cur->ns->prefix);
1381: ctxt->wellFormed = 0;
1382: }
1383: } else {
1384: if ((cur->ns == NULL) || (cur->ns->prefix == NULL)) {
1385: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1386: ctxt->sax->error(ctxt,
1387: "End tags %s holds a prefix %s not used by the open tag\n",
1388: cur->name, namespace);
1389: ctxt->wellFormed = 0;
1.79 veillard 1390: } else if (!xmlStrEqual(namespace, cur->ns->prefix)) {
1.10 daniel 1391: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1392: ctxt->sax->error(ctxt,
1393: "Start and End tags for %s don't use the same namespaces: %s and %s\n",
1394: cur->name, cur->ns->prefix, namespace);
1395: ctxt->wellFormed = 0;
1396: } else
1397: return(1);
1398: }
1399: return(0);
1400: }
1401:
1402: /**
1403: * namespaceDecl:
1.16 daniel 1404: * @ctx: the user data (XML parser context)
1.10 daniel 1405: * @href: the namespace associated URN
1406: * @prefix: the namespace prefix
1407: *
1408: * A namespace has been parsed.
1409: */
1410: void
1.34 daniel 1411: namespaceDecl(void *ctx, const xmlChar *href, const xmlChar *prefix)
1.10 daniel 1412: {
1.11 daniel 1413: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 1414: #ifdef DEBUG_SAX
1415: if (prefix == NULL)
1416: fprintf(stderr, "SAX.namespaceDecl(%s, NULL)\n", href);
1417: else
1418: fprintf(stderr, "SAX.namespaceDecl(%s, %s)\n", href, prefix);
1419: #endif
1420: xmlNewNs(ctxt->node, href, prefix);
1421: }
1422:
1423: /**
1424: * comment:
1.16 daniel 1425: * @ctx: the user data (XML parser context)
1.10 daniel 1426: * @value: the comment content
1427: *
1428: * A comment has been parsed.
1429: */
1430: void
1.34 daniel 1431: comment(void *ctx, const xmlChar *value)
1.10 daniel 1432: {
1.11 daniel 1433: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.17 daniel 1434: xmlNodePtr ret;
1.27 daniel 1435: xmlNodePtr parent = ctxt->node;
1.17 daniel 1436:
1.10 daniel 1437: #ifdef DEBUG_SAX
1438: fprintf(stderr, "SAX.comment(%s)\n", value);
1439: #endif
1.17 daniel 1440: ret = xmlNewDocComment(ctxt->myDoc, value);
1.27 daniel 1441: if (ret == NULL) return;
1442:
1.53 daniel 1443: if (ctxt->inSubset == 1) {
1444: xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
1445: return;
1446: } else if (ctxt->inSubset == 2) {
1447: xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
1448: return;
1449: }
1450: if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
1.27 daniel 1451: #ifdef DEBUG_SAX_TREE
1452: fprintf(stderr, "Setting comment as root\n");
1453: #endif
1.45 daniel 1454: xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1.53 daniel 1455: return;
1.27 daniel 1456: }
1.53 daniel 1457: if (parent->type == XML_ELEMENT_NODE) {
1.27 daniel 1458: #ifdef DEBUG_SAX_TREE
1.53 daniel 1459: fprintf(stderr, "adding comment child to %s\n", parent->name);
1.27 daniel 1460: #endif
1.53 daniel 1461: xmlAddChild(parent, ret);
1462: } else {
1.27 daniel 1463: #ifdef DEBUG_SAX_TREE
1.53 daniel 1464: fprintf(stderr, "adding comment sibling to ");
1465: xmlDebugDumpOneNode(stderr, parent, 0);
1.27 daniel 1466: #endif
1.53 daniel 1467: xmlAddSibling(parent, ret);
1.27 daniel 1468: }
1.25 daniel 1469: }
1470:
1471: /**
1472: * cdataBlock:
1473: * @ctx: the user data (XML parser context)
1474: * @value: The pcdata content
1475: * @len: the block length
1476: *
1477: * called when a pcdata block has been parsed
1478: */
1479: void
1.34 daniel 1480: cdataBlock(void *ctx, const xmlChar *value, int len)
1.25 daniel 1481: {
1482: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.40 daniel 1483: xmlNodePtr ret, lastChild;
1.25 daniel 1484:
1485: #ifdef DEBUG_SAX
1.26 daniel 1486: fprintf(stderr, "SAX.pcdata(%.10s, %d)\n", value, len);
1.25 daniel 1487: #endif
1.40 daniel 1488: lastChild = xmlGetLastChild(ctxt->node);
1489: #ifdef DEBUG_SAX_TREE
1490: fprintf(stderr, "add chars to %s \n", ctxt->node->name);
1491: #endif
1492: if ((lastChild != NULL) &&
1493: (lastChild->type == XML_CDATA_SECTION_NODE)) {
1494: xmlTextConcat(lastChild, value, len);
1495: } else {
1496: ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
1497: xmlAddChild(ctxt->node, ret);
1498: }
1.10 daniel 1499: }
1500:
1.18 daniel 1501: /*
1502: * Default handler for XML, builds the DOM tree
1503: */
1.1 daniel 1504: xmlSAXHandler xmlDefaultSAXHandler = {
1.10 daniel 1505: internalSubset,
1506: isStandalone,
1507: hasInternalSubset,
1508: hasExternalSubset,
1.1 daniel 1509: resolveEntity,
1.10 daniel 1510: getEntity,
1511: entityDecl,
1.1 daniel 1512: notationDecl,
1.10 daniel 1513: attributeDecl,
1514: elementDecl,
1.1 daniel 1515: unparsedEntityDecl,
1516: setDocumentLocator,
1517: startDocument,
1518: endDocument,
1519: startElement,
1520: endElement,
1.10 daniel 1521: reference,
1.1 daniel 1522: characters,
1523: ignorableWhitespace,
1524: processingInstruction,
1.10 daniel 1525: comment,
1.1 daniel 1526: xmlParserWarning,
1527: xmlParserError,
1.2 daniel 1528: xmlParserError,
1.20 daniel 1529: getParameterEntity,
1.25 daniel 1530: cdataBlock,
1.49 daniel 1531: externalSubset,
1.1 daniel 1532: };
1.2 daniel 1533:
1.5 daniel 1534: /**
1535: * xmlDefaultSAXHandlerInit:
1536: *
1537: * Initialize the default SAX handler
1538: */
1539: void
1540: xmlDefaultSAXHandlerInit(void)
1541: {
1.10 daniel 1542: xmlDefaultSAXHandler.internalSubset = internalSubset;
1.49 daniel 1543: xmlDefaultSAXHandler.externalSubset = externalSubset;
1.10 daniel 1544: xmlDefaultSAXHandler.isStandalone = isStandalone;
1545: xmlDefaultSAXHandler.hasInternalSubset = hasInternalSubset;
1546: xmlDefaultSAXHandler.hasExternalSubset = hasExternalSubset;
1.2 daniel 1547: xmlDefaultSAXHandler.resolveEntity = resolveEntity;
1.10 daniel 1548: xmlDefaultSAXHandler.getEntity = getEntity;
1.20 daniel 1549: xmlDefaultSAXHandler.getParameterEntity = getParameterEntity;
1.10 daniel 1550: xmlDefaultSAXHandler.entityDecl = entityDecl;
1551: xmlDefaultSAXHandler.attributeDecl = attributeDecl;
1552: xmlDefaultSAXHandler.elementDecl = elementDecl;
1.2 daniel 1553: xmlDefaultSAXHandler.notationDecl = notationDecl;
1554: xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
1555: xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1556: xmlDefaultSAXHandler.startDocument = startDocument;
1557: xmlDefaultSAXHandler.endDocument = endDocument;
1558: xmlDefaultSAXHandler.startElement = startElement;
1559: xmlDefaultSAXHandler.endElement = endElement;
1.10 daniel 1560: xmlDefaultSAXHandler.reference = reference;
1.2 daniel 1561: xmlDefaultSAXHandler.characters = characters;
1.25 daniel 1562: xmlDefaultSAXHandler.cdataBlock = cdataBlock;
1.2 daniel 1563: xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1564: xmlDefaultSAXHandler.processingInstruction = processingInstruction;
1.10 daniel 1565: xmlDefaultSAXHandler.comment = comment;
1.47 daniel 1566: if (xmlGetWarningsDefaultValue == 0)
1567: xmlDefaultSAXHandler.warning = NULL;
1568: else
1569: xmlDefaultSAXHandler.warning = xmlParserWarning;
1.2 daniel 1570: xmlDefaultSAXHandler.error = xmlParserError;
1571: xmlDefaultSAXHandler.fatalError = xmlParserError;
1.18 daniel 1572: }
1573:
1574: /*
1575: * Default handler for HTML, builds the DOM tree
1576: */
1577: xmlSAXHandler htmlDefaultSAXHandler = {
1.66 daniel 1578: internalSubset,
1.18 daniel 1579: NULL,
1580: NULL,
1581: NULL,
1582: NULL,
1583: getEntity,
1584: NULL,
1585: NULL,
1586: NULL,
1587: NULL,
1588: NULL,
1589: setDocumentLocator,
1590: startDocument,
1591: endDocument,
1592: startElement,
1593: endElement,
1594: NULL,
1595: characters,
1596: ignorableWhitespace,
1597: NULL,
1598: comment,
1599: xmlParserWarning,
1600: xmlParserError,
1601: xmlParserError,
1.20 daniel 1602: getParameterEntity,
1.25 daniel 1603: NULL,
1.49 daniel 1604: NULL,
1.18 daniel 1605: };
1606:
1607: /**
1608: * htmlDefaultSAXHandlerInit:
1609: *
1610: * Initialize the default SAX handler
1611: */
1612: void
1613: htmlDefaultSAXHandlerInit(void)
1614: {
1.66 daniel 1615: htmlDefaultSAXHandler.internalSubset = internalSubset;
1.49 daniel 1616: htmlDefaultSAXHandler.externalSubset = NULL;
1.18 daniel 1617: htmlDefaultSAXHandler.isStandalone = NULL;
1618: htmlDefaultSAXHandler.hasInternalSubset = NULL;
1619: htmlDefaultSAXHandler.hasExternalSubset = NULL;
1620: htmlDefaultSAXHandler.resolveEntity = NULL;
1621: htmlDefaultSAXHandler.getEntity = getEntity;
1.20 daniel 1622: htmlDefaultSAXHandler.getParameterEntity = NULL;
1.18 daniel 1623: htmlDefaultSAXHandler.entityDecl = NULL;
1624: htmlDefaultSAXHandler.attributeDecl = NULL;
1625: htmlDefaultSAXHandler.elementDecl = NULL;
1626: htmlDefaultSAXHandler.notationDecl = NULL;
1627: htmlDefaultSAXHandler.unparsedEntityDecl = NULL;
1628: htmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1629: htmlDefaultSAXHandler.startDocument = startDocument;
1630: htmlDefaultSAXHandler.endDocument = endDocument;
1631: htmlDefaultSAXHandler.startElement = startElement;
1632: htmlDefaultSAXHandler.endElement = endElement;
1633: htmlDefaultSAXHandler.reference = NULL;
1634: htmlDefaultSAXHandler.characters = characters;
1.25 daniel 1635: htmlDefaultSAXHandler.cdataBlock = NULL;
1.18 daniel 1636: htmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1637: htmlDefaultSAXHandler.processingInstruction = NULL;
1638: htmlDefaultSAXHandler.comment = comment;
1639: htmlDefaultSAXHandler.warning = xmlParserWarning;
1640: htmlDefaultSAXHandler.error = xmlParserError;
1641: htmlDefaultSAXHandler.fatalError = xmlParserError;
1.2 daniel 1642: }
1.76 veillard 1643:
1644: /*
1645: * Default handler for HTML, builds the DOM tree
1646: */
1647: xmlSAXHandler sgmlDefaultSAXHandler = {
1648: internalSubset,
1649: NULL,
1650: NULL,
1651: NULL,
1652: NULL,
1653: getEntity,
1654: NULL,
1655: NULL,
1656: NULL,
1657: NULL,
1658: NULL,
1659: setDocumentLocator,
1660: startDocument,
1661: endDocument,
1662: startElement,
1663: endElement,
1664: NULL,
1665: characters,
1666: ignorableWhitespace,
1667: NULL,
1668: comment,
1669: xmlParserWarning,
1670: xmlParserError,
1671: xmlParserError,
1672: getParameterEntity,
1673: NULL,
1674: NULL,
1675: };
1676:
1677: /**
1678: * sgmlDefaultSAXHandlerInit:
1679: *
1680: * Initialize the default SAX handler
1681: */
1682: void
1683: sgmlDefaultSAXHandlerInit(void)
1684: {
1685: sgmlDefaultSAXHandler.internalSubset = internalSubset;
1686: sgmlDefaultSAXHandler.externalSubset = NULL;
1687: sgmlDefaultSAXHandler.isStandalone = NULL;
1688: sgmlDefaultSAXHandler.hasInternalSubset = NULL;
1689: sgmlDefaultSAXHandler.hasExternalSubset = NULL;
1690: sgmlDefaultSAXHandler.resolveEntity = NULL;
1691: sgmlDefaultSAXHandler.getEntity = getEntity;
1692: sgmlDefaultSAXHandler.getParameterEntity = NULL;
1693: sgmlDefaultSAXHandler.entityDecl = NULL;
1694: sgmlDefaultSAXHandler.attributeDecl = NULL;
1695: sgmlDefaultSAXHandler.elementDecl = NULL;
1696: sgmlDefaultSAXHandler.notationDecl = NULL;
1697: sgmlDefaultSAXHandler.unparsedEntityDecl = NULL;
1698: sgmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1699: sgmlDefaultSAXHandler.startDocument = startDocument;
1700: sgmlDefaultSAXHandler.endDocument = endDocument;
1701: sgmlDefaultSAXHandler.startElement = startElement;
1702: sgmlDefaultSAXHandler.endElement = endElement;
1703: sgmlDefaultSAXHandler.reference = NULL;
1704: sgmlDefaultSAXHandler.characters = characters;
1705: sgmlDefaultSAXHandler.cdataBlock = NULL;
1706: sgmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1707: sgmlDefaultSAXHandler.processingInstruction = NULL;
1708: sgmlDefaultSAXHandler.comment = comment;
1709: sgmlDefaultSAXHandler.warning = xmlParserWarning;
1710: sgmlDefaultSAXHandler.error = xmlParserError;
1711: sgmlDefaultSAXHandler.fatalError = xmlParserError;
1712: }
Webmaster