Annotation of XML/SAX.c, revision 1.45
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.30 daniel 17: #include "xmlmemory.h"
1.1 daniel 18: #include "tree.h"
19: #include "parser.h"
1.10 daniel 20: #include "parserInternals.h"
21: #include "valid.h"
1.5 daniel 22: #include "entities.h"
1.9 daniel 23: #include "xml-error.h"
1.26 daniel 24: #include "debugXML.h"
1.41 daniel 25: #include "xmlIO.h"
1.37 daniel 26: #include "SAX.h"
1.1 daniel 27:
1.15 daniel 28: /* #define DEBUG_SAX */
1.26 daniel 29: /* #define DEBUG_SAX_TREE */
1.2 daniel 30:
1.5 daniel 31: /**
32: * getPublicId:
1.16 daniel 33: * @ctx: the user data (XML parser context)
1.5 daniel 34: *
1.1 daniel 35: * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
1.5 daniel 36: *
1.34 daniel 37: * Returns a xmlChar *
1.1 daniel 38: */
1.34 daniel 39: const xmlChar *
1.11 daniel 40: getPublicId(void *ctx)
1.5 daniel 41: {
1.11 daniel 42: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.1 daniel 43: return(NULL);
44: }
45:
1.5 daniel 46: /**
47: * getSystemId:
1.16 daniel 48: * @ctx: the user data (XML parser context)
1.5 daniel 49: *
1.12 daniel 50: * Return the system ID, basically URL or filename e.g.
1.5 daniel 51: * http://www.sgmlsource.com/dtds/memo.dtd
52: *
1.34 daniel 53: * Returns a xmlChar *
1.5 daniel 54: */
1.34 daniel 55: const xmlChar *
1.11 daniel 56: getSystemId(void *ctx)
1.5 daniel 57: {
1.11 daniel 58: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.28 daniel 59: return(BAD_CAST ctxt->input->filename);
1.1 daniel 60: }
61:
1.5 daniel 62: /**
63: * getLineNumber:
1.16 daniel 64: * @ctx: the user data (XML parser context)
1.5 daniel 65: *
1.1 daniel 66: * Return the line number of the current parsing point.
1.5 daniel 67: *
1.8 daniel 68: * Returns an int
1.1 daniel 69: */
1.5 daniel 70: int
1.11 daniel 71: getLineNumber(void *ctx)
1.5 daniel 72: {
1.11 daniel 73: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.1 daniel 74: return(ctxt->input->line);
75: }
1.5 daniel 76:
77: /**
78: * getColumnNumber:
1.16 daniel 79: * @ctx: the user data (XML parser context)
1.5 daniel 80: *
1.1 daniel 81: * Return the column number of the current parsing point.
1.5 daniel 82: *
1.8 daniel 83: * Returns an int
1.1 daniel 84: */
1.5 daniel 85: int
1.11 daniel 86: getColumnNumber(void *ctx)
1.5 daniel 87: {
1.11 daniel 88: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.1 daniel 89: return(ctxt->input->col);
90: }
91:
92: /*
93: * The default SAX Locator.
94: */
95:
96: xmlSAXLocator xmlDefaultSAXLocator = {
97: getPublicId, getSystemId, getLineNumber, getColumnNumber
98: };
99:
1.5 daniel 100: /**
1.10 daniel 101: * isStandalone:
1.16 daniel 102: * @ctx: the user data (XML parser context)
1.10 daniel 103: *
104: * Is this document tagged standalone ?
105: *
106: * Returns 1 if true
107: */
108: int
1.11 daniel 109: isStandalone(void *ctx)
1.10 daniel 110: {
1.11 daniel 111: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 112: return(ctxt->myDoc->standalone == 1);
113: }
114:
115: /**
116: * hasInternalSubset:
1.16 daniel 117: * @ctx: the user data (XML parser context)
1.10 daniel 118: *
119: * Does this document has an internal subset
120: *
121: * Returns 1 if true
122: */
123: int
1.11 daniel 124: hasInternalSubset(void *ctx)
1.10 daniel 125: {
1.11 daniel 126: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 127: return(ctxt->myDoc->intSubset != NULL);
128: }
129:
130: /**
131: * hasExternalSubset:
1.16 daniel 132: * @ctx: the user data (XML parser context)
1.10 daniel 133: *
134: * Does this document has an external subset
135: *
136: * Returns 1 if true
137: */
138: int
1.11 daniel 139: hasExternalSubset(void *ctx)
1.10 daniel 140: {
1.11 daniel 141: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 142: return(ctxt->myDoc->extSubset != NULL);
143: }
144:
145: /**
1.19 veillard 146: * internalSubset:
1.16 daniel 147: * @ctx: the user data (XML parser context)
1.10 daniel 148: *
1.41 daniel 149: * Callback on internal subset declaration.
1.10 daniel 150: */
151: void
1.34 daniel 152: internalSubset(void *ctx, const xmlChar *name,
153: const xmlChar *ExternalID, const xmlChar *SystemID)
1.10 daniel 154: {
1.11 daniel 155: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 156: #ifdef DEBUG_SAX
157: fprintf(stderr, "SAX.internalSubset(%s, %s, %s)\n",
158: name, ExternalID, SystemID);
159: #endif
160: xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
1.24 daniel 161: if (((ExternalID != NULL) || (SystemID != NULL)) &&
162: (ctxt->validate && ctxt->wellFormed && ctxt->myDoc)) {
163: /*
164: * Try to fetch and parse the external subset.
165: */
166: xmlDtdPtr ret = NULL;
167: xmlParserCtxtPtr dtdCtxt;
168: xmlParserInputPtr input = NULL;
169: xmlCharEncoding enc;
170:
171: dtdCtxt = xmlNewParserCtxt();
172: if (dtdCtxt == NULL) return;
173:
174: /*
175: * Ask the Entity resolver to load the damn thing
176: */
177: if ((ctxt->directory != NULL) && (dtdCtxt->directory == NULL))
1.28 daniel 178: dtdCtxt->directory = (char *) xmlStrdup(BAD_CAST ctxt->directory);
1.24 daniel 179:
180: if ((dtdCtxt->sax != NULL) && (dtdCtxt->sax->resolveEntity != NULL))
181: input = dtdCtxt->sax->resolveEntity(dtdCtxt->userData, ExternalID,
182: SystemID);
183: if (input == NULL) {
184: xmlFreeParserCtxt(dtdCtxt);
185: return;
186: }
187:
1.43 daniel 188: xmlPushInput(dtdCtxt, input);
189:
1.24 daniel 190: /*
1.43 daniel 191: * On the fly encoding conversion if needed
1.24 daniel 192: */
1.43 daniel 193: enc = xmlDetectCharEncoding(dtdCtxt->input->cur, 4);
1.24 daniel 194: xmlSwitchEncoding(dtdCtxt, enc);
195:
196: if (input->filename == NULL)
1.28 daniel 197: input->filename = (char *) xmlStrdup(SystemID);
1.24 daniel 198: input->line = 1;
199: input->col = 1;
200: input->base = dtdCtxt->input->cur;
201: input->cur = dtdCtxt->input->cur;
202: input->free = NULL;
203:
204: /*
205: * let's parse that entity knowing it's an external subset.
206: */
207: xmlParseExternalSubset(dtdCtxt, ExternalID, SystemID);
208:
209: if (dtdCtxt->myDoc != NULL) {
210: if (dtdCtxt->wellFormed) {
211: ret = dtdCtxt->myDoc->intSubset;
212: dtdCtxt->myDoc->intSubset = NULL;
213: } else {
214: ret = NULL;
215: }
216: xmlFreeDoc(dtdCtxt->myDoc);
217: dtdCtxt->myDoc = NULL;
218: }
219: xmlFreeParserCtxt(dtdCtxt);
220:
221: ctxt->myDoc->extSubset = ret;
1.12 daniel 222: }
1.10 daniel 223: }
224:
225: /**
1.5 daniel 226: * resolveEntity:
1.16 daniel 227: * @ctx: the user data (XML parser context)
1.5 daniel 228: * @publicId: The public ID of the entity
229: * @systemId: The system ID of the entity
230: *
1.41 daniel 231: * The entity loader, to control the loading of external entities,
232: * the application can either:
233: * - override this resolveEntity() callback in the SAX block
234: * - or better use the xmlSetExternalEntityLoader() function to
235: * set up it's own entity resolution routine
1.5 daniel 236: *
1.8 daniel 237: * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1.5 daniel 238: */
239: xmlParserInputPtr
1.34 daniel 240: resolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
1.5 daniel 241: {
1.12 daniel 242: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2 daniel 243:
244: #ifdef DEBUG_SAX
245: fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
246: #endif
1.5 daniel 247:
1.41 daniel 248: return(xmlLoadExternalEntity((const char *) systemId,
249: (const char *) publicId, ctxt));
1.1 daniel 250: }
251:
1.5 daniel 252: /**
1.10 daniel 253: * getEntity:
1.16 daniel 254: * @ctx: the user data (XML parser context)
1.10 daniel 255: * @name: The entity name
256: *
257: * Get an entity by name
258: *
1.13 daniel 259: * Returns the xmlEntityPtr if found.
1.10 daniel 260: */
261: xmlEntityPtr
1.34 daniel 262: getEntity(void *ctx, const xmlChar *name)
1.10 daniel 263: {
1.11 daniel 264: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 265: xmlEntityPtr ret;
266:
267: #ifdef DEBUG_SAX
268: fprintf(stderr, "SAX.getEntity(%s)\n", name);
269: #endif
270:
271: ret = xmlGetDocEntity(ctxt->myDoc, name);
272: return(ret);
273: }
274:
1.20 daniel 275: /**
276: * getParameterEntity:
277: * @ctx: the user data (XML parser context)
278: * @name: The entity name
279: *
280: * Get a parameter entity by name
281: *
282: * Returns the xmlEntityPtr if found.
283: */
284: xmlEntityPtr
1.34 daniel 285: getParameterEntity(void *ctx, const xmlChar *name)
1.20 daniel 286: {
287: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
288: xmlEntityPtr ret;
289:
290: #ifdef DEBUG_SAX
291: fprintf(stderr, "SAX.getParameterEntity(%s)\n", name);
292: #endif
293:
294: ret = xmlGetParameterEntity(ctxt->myDoc, name);
295: return(ret);
296: }
297:
1.10 daniel 298:
299: /**
300: * entityDecl:
1.16 daniel 301: * @ctx: the user data (XML parser context)
1.10 daniel 302: * @name: the entity name
303: * @type: the entity type
304: * @publicId: The public ID of the entity
305: * @systemId: The system ID of the entity
306: * @content: the entity value (without processing).
307: *
308: * An entity definition has been parsed
309: */
310: void
1.34 daniel 311: entityDecl(void *ctx, const xmlChar *name, int type,
312: const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1.10 daniel 313: {
1.11 daniel 314: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 315:
316: #ifdef DEBUG_SAX
317: fprintf(stderr, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
318: name, type, publicId, systemId, content);
319: #endif
320: xmlAddDocEntity(ctxt->myDoc, name, type, publicId, systemId, content);
321: }
322:
323: /**
324: * attributeDecl:
1.16 daniel 325: * @ctx: the user data (XML parser context)
1.10 daniel 326: * @name: the attribute name
327: * @type: the attribute type
328: * @publicId: The public ID of the attribute
329: * @systemId: The system ID of the attribute
330: * @content: the attribute value (without processing).
331: *
332: * An attribute definition has been parsed
333: */
334: void
1.34 daniel 335: attributeDecl(void *ctx, const xmlChar *elem, const xmlChar *name,
336: int type, int def, const xmlChar *defaultValue,
1.10 daniel 337: xmlEnumerationPtr tree)
338: {
1.11 daniel 339: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.21 daniel 340: xmlAttributePtr attr;
1.10 daniel 341:
342: #ifdef DEBUG_SAX
343: fprintf(stderr, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
344: elem, name, type, def, defaultValue);
345: #endif
1.21 daniel 346: attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
347: name, type, def, defaultValue, tree);
348: if (attr == 0) ctxt->valid = 0;
1.23 daniel 349: if (ctxt->validate && ctxt->wellFormed &&
350: ctxt->myDoc && ctxt->myDoc->intSubset)
1.21 daniel 351: ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
352: attr);
1.10 daniel 353: }
354:
355: /**
356: * elementDecl:
1.16 daniel 357: * @ctx: the user data (XML parser context)
1.10 daniel 358: * @name: the element name
359: * @type: the element type
360: * @publicId: The public ID of the element
361: * @systemId: The system ID of the element
362: * @content: the element value (without processing).
363: *
364: * An element definition has been parsed
365: */
366: void
1.34 daniel 367: elementDecl(void *ctx, const xmlChar *name, int type,
1.10 daniel 368: xmlElementContentPtr content)
369: {
1.11 daniel 370: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.21 daniel 371: xmlElementPtr elem;
1.10 daniel 372:
373: #ifdef DEBUG_SAX
374: fprintf(stderr, "SAX.elementDecl(%s, %d, ...)\n",
375: name, type);
376: #endif
1.21 daniel 377:
378: elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
379: name, type, content);
380: if (elem == 0) ctxt->valid = 0;
1.23 daniel 381: if (ctxt->validate && ctxt->wellFormed &&
382: ctxt->myDoc && ctxt->myDoc->intSubset)
1.21 daniel 383: ctxt->valid &= xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
1.10 daniel 384: }
385:
386: /**
1.5 daniel 387: * notationDecl:
1.16 daniel 388: * @ctx: the user data (XML parser context)
1.5 daniel 389: * @name: The name of the notation
390: * @publicId: The public ID of the entity
391: * @systemId: The system ID of the entity
392: *
1.1 daniel 393: * What to do when a notation declaration has been parsed.
394: */
1.5 daniel 395: void
1.34 daniel 396: notationDecl(void *ctx, const xmlChar *name,
397: const xmlChar *publicId, const xmlChar *systemId)
1.5 daniel 398: {
1.11 daniel 399: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.21 daniel 400: xmlNotationPtr nota;
401:
1.2 daniel 402: #ifdef DEBUG_SAX
403: fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
404: #endif
1.21 daniel 405:
406: nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
407: publicId, systemId);
408: if (nota == 0) ctxt->valid = 0;
1.23 daniel 409: if (ctxt->validate && ctxt->wellFormed &&
410: ctxt->myDoc && ctxt->myDoc->intSubset)
1.21 daniel 411: ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
412: nota);
1.1 daniel 413: }
414:
1.5 daniel 415: /**
416: * unparsedEntityDecl:
1.16 daniel 417: * @ctx: the user data (XML parser context)
1.5 daniel 418: * @name: The name of the entity
419: * @publicId: The public ID of the entity
420: * @systemId: The system ID of the entity
421: * @notationName: the name of the notation
422: *
1.1 daniel 423: * What to do when an unparsed entity declaration is parsed
424: */
1.5 daniel 425: void
1.34 daniel 426: unparsedEntityDecl(void *ctx, const xmlChar *name,
427: const xmlChar *publicId, const xmlChar *systemId,
428: const xmlChar *notationName)
1.5 daniel 429: {
1.28 daniel 430: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2 daniel 431: #ifdef DEBUG_SAX
432: fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
433: name, publicId, systemId, notationName);
434: #endif
1.28 daniel 435: if (ctxt->validate && ctxt->wellFormed &&
436: ctxt->myDoc && ctxt->myDoc->intSubset)
437: ctxt->valid &= xmlValidateNotationUse(&ctxt->vctxt, ctxt->myDoc,
438: notationName);
439: xmlAddDocEntity(ctxt->myDoc, name,
440: XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
441: publicId, systemId, notationName);
1.1 daniel 442: }
443:
1.5 daniel 444: /**
445: * setDocumentLocator:
1.16 daniel 446: * @ctx: the user data (XML parser context)
1.5 daniel 447: * @loc: A SAX Locator
448: *
1.1 daniel 449: * Receive the document locator at startup, actually xmlDefaultSAXLocator
450: * Everything is available on the context, so this is useless in our case.
451: */
1.5 daniel 452: void
1.11 daniel 453: setDocumentLocator(void *ctx, xmlSAXLocatorPtr loc)
1.5 daniel 454: {
1.11 daniel 455: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2 daniel 456: #ifdef DEBUG_SAX
457: fprintf(stderr, "SAX.setDocumentLocator()\n");
458: #endif
1.1 daniel 459: }
460:
1.5 daniel 461: /**
462: * startDocument:
1.16 daniel 463: * @ctx: the user data (XML parser context)
1.5 daniel 464: *
1.1 daniel 465: * called when the document start being processed.
466: */
1.5 daniel 467: void
1.11 daniel 468: startDocument(void *ctx)
1.5 daniel 469: {
1.11 daniel 470: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 471: xmlDocPtr doc;
472:
1.2 daniel 473: #ifdef DEBUG_SAX
474: fprintf(stderr, "SAX.startDocument()\n");
475: #endif
1.10 daniel 476: doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
477: if (doc != NULL) {
478: if (ctxt->encoding != NULL)
479: doc->encoding = xmlStrdup(ctxt->encoding);
480: else
481: doc->encoding = NULL;
482: doc->standalone = ctxt->standalone;
483: }
1.1 daniel 484: }
485:
1.5 daniel 486: /**
487: * endDocument:
1.16 daniel 488: * @ctx: the user data (XML parser context)
1.5 daniel 489: *
1.1 daniel 490: * called when the document end has been detected.
491: */
1.5 daniel 492: void
1.11 daniel 493: endDocument(void *ctx)
1.5 daniel 494: {
1.31 daniel 495: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2 daniel 496: #ifdef DEBUG_SAX
497: fprintf(stderr, "SAX.endDocument()\n");
498: #endif
1.31 daniel 499: if (ctxt->validate && ctxt->wellFormed &&
500: ctxt->myDoc && ctxt->myDoc->intSubset)
501: ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
1.1 daniel 502: }
503:
1.5 daniel 504: /**
1.10 daniel 505: * attribute:
1.16 daniel 506: * @ctx: the user data (XML parser context)
1.10 daniel 507: * @name: The attribute name
508: * @value: The attribute value
509: *
510: * Handle an attribute that has been read by the parser.
511: * The default handling is to convert the attribute into an
512: * DOM subtree and past it in a new xmlAttr element added to
513: * the element.
514: */
515: void
1.34 daniel 516: attribute(void *ctx, const xmlChar *fullname, const xmlChar *value)
1.10 daniel 517: {
1.11 daniel 518: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 519: xmlAttrPtr ret;
1.34 daniel 520: xmlChar *name;
521: xmlChar *ns;
1.29 daniel 522: xmlNsPtr namespace;
1.10 daniel 523:
524: /****************
525: #ifdef DEBUG_SAX
526: fprintf(stderr, "SAX.attribute(%s, %s)\n", fullname, value);
527: #endif
528: ****************/
529: /*
530: * Split the full name into a namespace prefix and the tag name
531: */
532: name = xmlSplitQName(fullname, &ns);
533:
534: /*
535: * Check whether it's a namespace definition
536: */
537: if ((ns == NULL) &&
538: (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
539: (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
540: /* a default namespace definition */
541: xmlNewNs(ctxt->node, value, NULL);
542: if (name != NULL)
1.30 daniel 543: xmlFree(name);
1.10 daniel 544: return;
545: }
546: if ((ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
547: (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
548: /* a standard namespace definition */
549: xmlNewNs(ctxt->node, value, name);
1.30 daniel 550: xmlFree(ns);
1.10 daniel 551: if (name != NULL)
1.30 daniel 552: xmlFree(name);
1.10 daniel 553: return;
554: }
555:
1.38 daniel 556: if (ns != NULL)
557: namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
558: else {
559: namespace = NULL;
560: }
561:
1.29 daniel 562: /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
563: ret = xmlNewNsProp(ctxt->node, namespace, name, NULL);
1.22 daniel 564:
1.26 daniel 565: if (ret != NULL) {
1.35 daniel 566: if ((ctxt->replaceEntities == 0) && (!ctxt->html))
1.44 daniel 567: ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
1.26 daniel 568: else
1.44 daniel 569: ret->children = xmlNewDocText(ctxt->myDoc, value);
1.26 daniel 570: }
1.22 daniel 571:
1.23 daniel 572: if (ctxt->validate && ctxt->wellFormed &&
573: ctxt->myDoc && ctxt->myDoc->intSubset)
1.22 daniel 574: ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
575: ctxt->node, ret, value);
1.26 daniel 576: else {
577: /*
578: * when validating, the ID registration is done at the attribute
579: * validation level. Otherwise we have to do specific handling here.
580: */
581: if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
582: xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
1.31 daniel 583: else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
584: xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
1.26 daniel 585: }
1.22 daniel 586:
1.10 daniel 587: if (name != NULL)
1.30 daniel 588: xmlFree(name);
1.10 daniel 589: if (ns != NULL)
1.30 daniel 590: xmlFree(ns);
1.10 daniel 591: }
592:
593: /**
1.5 daniel 594: * startElement:
1.16 daniel 595: * @ctx: the user data (XML parser context)
1.5 daniel 596: * @name: The element name
1.10 daniel 597: * @atts: An array of name/value attributes pairs, NULL terminated
1.5 daniel 598: *
1.1 daniel 599: * called when an opening tag has been processed.
600: */
1.5 daniel 601: void
1.34 daniel 602: startElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
1.5 daniel 603: {
1.11 daniel 604: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 605: xmlNodePtr ret;
606: xmlNodePtr parent = ctxt->node;
607: xmlNsPtr ns;
1.34 daniel 608: xmlChar *name;
609: xmlChar *prefix;
610: const xmlChar *att;
611: const xmlChar *value;
1.10 daniel 612: int i;
613:
1.2 daniel 614: #ifdef DEBUG_SAX
1.10 daniel 615: fprintf(stderr, "SAX.startElement(%s)\n", fullname);
1.2 daniel 616: #endif
1.33 daniel 617:
618: /*
619: * First check on validity:
620: */
621: if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
622: ((ctxt->myDoc->intSubset == NULL) ||
623: ((ctxt->myDoc->intSubset->notations == NULL) &&
624: (ctxt->myDoc->intSubset->elements == NULL) &&
625: (ctxt->myDoc->intSubset->attributes == NULL) &&
626: (ctxt->myDoc->intSubset->entities == NULL)))) {
627: if (ctxt->vctxt.error != NULL) {
628: ctxt->vctxt.error(ctxt->vctxt.userData,
629: "Validation failed: no DTD found !\n");
630: }
631: ctxt->validate = 0;
632: }
633:
634:
1.10 daniel 635: /*
636: * Split the full name into a namespace prefix and the tag name
637: */
638: name = xmlSplitQName(fullname, &prefix);
639:
640:
641: /*
642: * Note : the namespace resolution is deferred until the end of the
643: * attributes parsing, since local namespace can be defined as
644: * an attribute at this level.
645: */
646: ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
647: if (ret == NULL) return;
1.44 daniel 648: if (ctxt->myDoc->children == NULL) {
1.26 daniel 649: #ifdef DEBUG_SAX_TREE
650: fprintf(stderr, "Setting %s as root\n", name);
651: #endif
1.45 ! daniel 652: xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1.26 daniel 653: } else if (parent == NULL) {
1.44 daniel 654: parent = ctxt->myDoc->children;
1.26 daniel 655: }
1.10 daniel 656:
657: /*
658: * We are parsing a new node.
659: */
1.26 daniel 660: #ifdef DEBUG_SAX_TREE
661: fprintf(stderr, "pushing(%s)\n", name);
662: #endif
1.10 daniel 663: nodePush(ctxt, ret);
664:
665: /*
666: * Link the child element
667: */
1.26 daniel 668: if (parent != NULL) {
669: if (parent->type == XML_ELEMENT_NODE) {
670: #ifdef DEBUG_SAX_TREE
671: fprintf(stderr, "adding child %s to %s\n", name, parent->name);
672: #endif
673: xmlAddChild(parent, ret);
674: } else {
675: #ifdef DEBUG_SAX_TREE
676: fprintf(stderr, "adding sibling %s to ", name);
677: xmlDebugDumpOneNode(stderr, parent, 0);
678: #endif
679: xmlAddSibling(parent, ret);
680: }
681: }
1.10 daniel 682:
683: /*
1.29 daniel 684: * process all the attributes whose name start with "xml"
1.10 daniel 685: */
686: if (atts != NULL) {
687: i = 0;
688: att = atts[i++];
689: value = atts[i++];
690: while ((att != NULL) && (value != NULL)) {
1.29 daniel 691: if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l'))
692: attribute(ctxt, att, value);
693:
694: att = atts[i++];
695: value = atts[i++];
696: }
697: }
698:
699: /*
700: * process all the other attributes
701: */
702: if (atts != NULL) {
703: i = 0;
704: att = atts[i++];
705: value = atts[i++];
706: while ((att != NULL) && (value != NULL)) {
707: if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l'))
708: attribute(ctxt, att, value);
1.10 daniel 709:
710: /*
711: * Next ones
712: */
713: att = atts[i++];
714: value = atts[i++];
715: }
716: }
717:
718: /*
719: * Search the namespace, note that since the attributes have been
720: * processed, the local namespaces are available.
721: */
722: ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
723: if ((ns == NULL) && (parent != NULL))
724: ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
725: xmlSetNs(ret, ns);
726:
727: if (prefix != NULL)
1.30 daniel 728: xmlFree(prefix);
1.10 daniel 729: if (name != NULL)
1.30 daniel 730: xmlFree(name);
1.10 daniel 731:
1.1 daniel 732: }
733:
1.5 daniel 734: /**
735: * endElement:
1.16 daniel 736: * @ctx: the user data (XML parser context)
1.5 daniel 737: * @name: The element name
738: *
1.1 daniel 739: * called when the end of an element has been detected.
740: */
1.5 daniel 741: void
1.34 daniel 742: endElement(void *ctx, const xmlChar *name)
1.5 daniel 743: {
1.11 daniel 744: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 745: xmlParserNodeInfo node_info;
746: xmlNodePtr cur = ctxt->node;
747:
1.2 daniel 748: #ifdef DEBUG_SAX
1.10 daniel 749: if (name == NULL)
750: fprintf(stderr, "SAX.endElement(NULL)\n");
751: else
752: fprintf(stderr, "SAX.endElement(%s)\n", name);
753: #endif
754:
755: /* Capture end position and add node */
756: if (cur != NULL && ctxt->record_info) {
757: node_info.end_pos = ctxt->input->cur - ctxt->input->base;
758: node_info.end_line = ctxt->input->line;
759: node_info.node = cur;
760: xmlParserAddNodeInfo(ctxt, &node_info);
761: }
762:
1.23 daniel 763: if (ctxt->validate && ctxt->wellFormed &&
764: ctxt->myDoc && ctxt->myDoc->intSubset)
1.22 daniel 765: ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
766: cur);
767:
768:
1.10 daniel 769: /*
770: * end of parsing of this node.
771: */
1.26 daniel 772: #ifdef DEBUG_SAX_TREE
773: fprintf(stderr, "popping(%s)\n", cur->name);
774: #endif
1.10 daniel 775: nodePop(ctxt);
1.1 daniel 776: }
777:
1.5 daniel 778: /**
1.10 daniel 779: * reference:
1.16 daniel 780: * @ctx: the user data (XML parser context)
1.10 daniel 781: * @name: The entity name
1.5 daniel 782: *
1.10 daniel 783: * called when an entity reference is detected.
1.5 daniel 784: */
785: void
1.34 daniel 786: reference(void *ctx, const xmlChar *name)
1.5 daniel 787: {
1.11 daniel 788: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 789: xmlNodePtr ret;
790:
1.5 daniel 791: #ifdef DEBUG_SAX
1.10 daniel 792: fprintf(stderr, "SAX.reference(%s)\n", name);
1.5 daniel 793: #endif
1.42 daniel 794: if (name[0] == '#')
795: ret = xmlNewCharRef(ctxt->myDoc, name);
796: else
797: ret = xmlNewReference(ctxt->myDoc, name);
1.26 daniel 798: #ifdef DEBUG_SAX_TREE
799: fprintf(stderr, "add reference %s to %s \n", name, ctxt->node->name);
800: #endif
1.10 daniel 801: xmlAddChild(ctxt->node, ret);
1.5 daniel 802: }
803:
804: /**
805: * characters:
1.16 daniel 806: * @ctx: the user data (XML parser context)
1.34 daniel 807: * @ch: a xmlChar string
808: * @len: the number of xmlChar
1.5 daniel 809: *
1.1 daniel 810: * receiving some chars from the parser.
811: * Question: how much at a time ???
812: */
1.5 daniel 813: void
1.34 daniel 814: characters(void *ctx, const xmlChar *ch, int len)
1.5 daniel 815: {
1.11 daniel 816: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2 daniel 817: xmlNodePtr lastChild;
818:
819: #ifdef DEBUG_SAX
1.10 daniel 820: fprintf(stderr, "SAX.characters(%.30s, %d)\n", ch, len);
1.2 daniel 821: #endif
822: /*
823: * Handle the data if any. If there is no child
824: * add it as content, otherwise if the last child is text,
825: * concatenate it, else create a new node of type text.
826: */
827:
1.36 daniel 828: if (ctxt->node == NULL) {
829: #ifdef DEBUG_SAX_TREE
830: fprintf(stderr, "add chars: ctxt->node == NULL !\n");
831: #endif
832: return;
833: }
1.2 daniel 834: lastChild = xmlGetLastChild(ctxt->node);
1.26 daniel 835: #ifdef DEBUG_SAX_TREE
836: fprintf(stderr, "add chars to %s \n", ctxt->node->name);
837: #endif
1.2 daniel 838: if (lastChild == NULL)
1.10 daniel 839: xmlNodeAddContentLen(ctxt->node, ch, len);
1.2 daniel 840: else {
841: if (xmlNodeIsText(lastChild))
1.10 daniel 842: xmlTextConcat(lastChild, ch, len);
1.2 daniel 843: else {
1.10 daniel 844: lastChild = xmlNewTextLen(ch, len);
1.2 daniel 845: xmlAddChild(ctxt->node, lastChild);
846: }
847: }
1.1 daniel 848: }
849:
1.5 daniel 850: /**
851: * ignorableWhitespace:
1.16 daniel 852: * @ctx: the user data (XML parser context)
1.34 daniel 853: * @ch: a xmlChar string
854: * @len: the number of xmlChar
1.5 daniel 855: *
1.1 daniel 856: * receiving some ignorable whitespaces from the parser.
857: * Question: how much at a time ???
858: */
1.5 daniel 859: void
1.34 daniel 860: ignorableWhitespace(void *ctx, const xmlChar *ch, int len)
1.5 daniel 861: {
1.11 daniel 862: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2 daniel 863: #ifdef DEBUG_SAX
1.10 daniel 864: fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
1.2 daniel 865: #endif
1.1 daniel 866: }
867:
1.5 daniel 868: /**
869: * processingInstruction:
1.16 daniel 870: * @ctx: the user data (XML parser context)
1.5 daniel 871: * @target: the target name
872: * @data: the PI data's
1.34 daniel 873: * @len: the number of xmlChar
1.5 daniel 874: *
875: * A processing instruction has been parsed.
876: */
877: void
1.34 daniel 878: processingInstruction(void *ctx, const xmlChar *target,
879: const xmlChar *data)
1.5 daniel 880: {
1.26 daniel 881: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
882: xmlNodePtr ret;
883: xmlNodePtr parent = ctxt->node;
884:
1.2 daniel 885: #ifdef DEBUG_SAX
886: fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
887: #endif
1.26 daniel 888:
889: ret = xmlNewPI(target, data);
890: if (ret == NULL) return;
891: ret->doc = ctxt->myDoc;
1.44 daniel 892: if (ctxt->myDoc->children == NULL) {
1.26 daniel 893: #ifdef DEBUG_SAX_TREE
894: fprintf(stderr, "Setting PI %s as root\n", target);
895: #endif
1.45 ! daniel 896: xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1.26 daniel 897: } else if (parent == NULL) {
1.44 daniel 898: parent = ctxt->myDoc->children;
1.26 daniel 899: }
900: if (parent != NULL) {
901: if (parent->type == XML_ELEMENT_NODE) {
902: #ifdef DEBUG_SAX_TREE
903: fprintf(stderr, "adding PI child %s to %s\n", target, parent->name);
904: #endif
905: xmlAddChild(parent, ret);
906: } else {
907: #ifdef DEBUG_SAX_TREE
908: fprintf(stderr, "adding PI sibling %s to ", target);
909: xmlDebugDumpOneNode(stderr, parent, 0);
910: #endif
911: xmlAddSibling(parent, ret);
912: }
913: }
914:
1.1 daniel 915: }
916:
1.10 daniel 917: /**
918: * globalNamespace:
1.16 daniel 919: * @ctx: the user data (XML parser context)
1.10 daniel 920: * @href: the namespace associated URN
921: * @prefix: the namespace prefix
922: *
923: * An old global namespace has been parsed.
924: */
925: void
1.34 daniel 926: globalNamespace(void *ctx, const xmlChar *href, const xmlChar *prefix)
1.10 daniel 927: {
1.11 daniel 928: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 929: #ifdef DEBUG_SAX
930: fprintf(stderr, "SAX.globalNamespace(%s, %s)\n", href, prefix);
931: #endif
932: xmlNewGlobalNs(ctxt->myDoc, href, prefix);
933: }
934:
935: /**
936: * setNamespace:
1.16 daniel 937: * @ctx: the user data (XML parser context)
1.10 daniel 938: * @name: the namespace prefix
939: *
940: * Set the current element namespace.
941: */
942: void
1.34 daniel 943: setNamespace(void *ctx, const xmlChar *name)
1.10 daniel 944: {
1.11 daniel 945: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 946: xmlNsPtr ns;
947: xmlNodePtr parent;
948:
949: #ifdef DEBUG_SAX
950: fprintf(stderr, "SAX.setNamespace(%s)\n", name);
951: #endif
952: ns = xmlSearchNs(ctxt->myDoc, ctxt->node, name);
953: if (ns == NULL) { /* ctxt->node may not have a parent yet ! */
954: if (ctxt->nodeNr >= 2) {
955: parent = ctxt->nodeTab[ctxt->nodeNr - 2];
956: if (parent != NULL)
957: ns = xmlSearchNs(ctxt->myDoc, parent, name);
958: }
959: }
960: xmlSetNs(ctxt->node, ns);
961: }
962:
963: /**
964: * getNamespace:
1.16 daniel 965: * @ctx: the user data (XML parser context)
1.10 daniel 966: *
967: * Get the current element namespace.
968: */
969: xmlNsPtr
1.11 daniel 970: getNamespace(void *ctx)
1.10 daniel 971: {
1.11 daniel 972: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 973: xmlNsPtr ret;
974:
975: #ifdef DEBUG_SAX
976: fprintf(stderr, "SAX.getNamespace()\n");
977: #endif
978: ret = ctxt->node->ns;
979: return(ret);
980: }
981:
982: /**
983: * checkNamespace:
1.16 daniel 984: * @ctx: the user data (XML parser context)
1.10 daniel 985: * @namespace: the namespace to check against
986: *
987: * Check that the current element namespace is the same as the
988: * one read upon parsing.
989: */
990: int
1.34 daniel 991: checkNamespace(void *ctx, xmlChar *namespace)
1.10 daniel 992: {
1.11 daniel 993: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 994: xmlNodePtr cur = ctxt->node;
995:
996: #ifdef DEBUG_SAX
997: fprintf(stderr, "SAX.checkNamespace(%s)\n", namespace);
998: #endif
999:
1000: /*
1001: * Check that the Name in the ETag is the same as in the STag.
1002: */
1003: if (namespace == NULL) {
1004: if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
1005: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1006: ctxt->sax->error(ctxt,
1007: "End tags for %s don't hold the namespace %s\n",
1008: cur->name, cur->ns->prefix);
1009: ctxt->wellFormed = 0;
1010: }
1011: } else {
1012: if ((cur->ns == NULL) || (cur->ns->prefix == NULL)) {
1013: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1014: ctxt->sax->error(ctxt,
1015: "End tags %s holds a prefix %s not used by the open tag\n",
1016: cur->name, namespace);
1017: ctxt->wellFormed = 0;
1.28 daniel 1018: } else if (xmlStrcmp(namespace, cur->ns->prefix)) {
1.10 daniel 1019: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1020: ctxt->sax->error(ctxt,
1021: "Start and End tags for %s don't use the same namespaces: %s and %s\n",
1022: cur->name, cur->ns->prefix, namespace);
1023: ctxt->wellFormed = 0;
1024: } else
1025: return(1);
1026: }
1027: return(0);
1028: }
1029:
1030: /**
1031: * namespaceDecl:
1.16 daniel 1032: * @ctx: the user data (XML parser context)
1.10 daniel 1033: * @href: the namespace associated URN
1034: * @prefix: the namespace prefix
1035: *
1036: * A namespace has been parsed.
1037: */
1038: void
1.34 daniel 1039: namespaceDecl(void *ctx, const xmlChar *href, const xmlChar *prefix)
1.10 daniel 1040: {
1.11 daniel 1041: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 1042: #ifdef DEBUG_SAX
1043: if (prefix == NULL)
1044: fprintf(stderr, "SAX.namespaceDecl(%s, NULL)\n", href);
1045: else
1046: fprintf(stderr, "SAX.namespaceDecl(%s, %s)\n", href, prefix);
1047: #endif
1048: xmlNewNs(ctxt->node, href, prefix);
1049: }
1050:
1051: /**
1052: * comment:
1.16 daniel 1053: * @ctx: the user data (XML parser context)
1.10 daniel 1054: * @value: the comment content
1055: *
1056: * A comment has been parsed.
1057: */
1058: void
1.34 daniel 1059: comment(void *ctx, const xmlChar *value)
1.10 daniel 1060: {
1.11 daniel 1061: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.17 daniel 1062: xmlNodePtr ret;
1.27 daniel 1063: xmlNodePtr parent = ctxt->node;
1.17 daniel 1064:
1.10 daniel 1065: #ifdef DEBUG_SAX
1066: fprintf(stderr, "SAX.comment(%s)\n", value);
1067: #endif
1.17 daniel 1068: ret = xmlNewDocComment(ctxt->myDoc, value);
1.27 daniel 1069: if (ret == NULL) return;
1070:
1.44 daniel 1071: if (ctxt->myDoc->children == NULL) {
1.27 daniel 1072: #ifdef DEBUG_SAX_TREE
1073: fprintf(stderr, "Setting comment as root\n");
1074: #endif
1.45 ! daniel 1075: xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1.27 daniel 1076: } else if (parent == NULL) {
1.44 daniel 1077: parent = ctxt->myDoc->children;
1.27 daniel 1078: }
1079: if (parent != NULL) {
1080: if (parent->type == XML_ELEMENT_NODE) {
1081: #ifdef DEBUG_SAX_TREE
1082: fprintf(stderr, "adding comment child to %s\n", parent->name);
1083: #endif
1084: xmlAddChild(parent, ret);
1085: } else {
1086: #ifdef DEBUG_SAX_TREE
1087: fprintf(stderr, "adding comment sibling to ");
1088: xmlDebugDumpOneNode(stderr, parent, 0);
1089: #endif
1090: xmlAddSibling(parent, ret);
1091: }
1092: }
1.25 daniel 1093: }
1094:
1095: /**
1096: * cdataBlock:
1097: * @ctx: the user data (XML parser context)
1098: * @value: The pcdata content
1099: * @len: the block length
1100: *
1101: * called when a pcdata block has been parsed
1102: */
1103: void
1.34 daniel 1104: cdataBlock(void *ctx, const xmlChar *value, int len)
1.25 daniel 1105: {
1106: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.40 daniel 1107: xmlNodePtr ret, lastChild;
1.25 daniel 1108:
1109: #ifdef DEBUG_SAX
1.26 daniel 1110: fprintf(stderr, "SAX.pcdata(%.10s, %d)\n", value, len);
1.25 daniel 1111: #endif
1.40 daniel 1112: lastChild = xmlGetLastChild(ctxt->node);
1113: #ifdef DEBUG_SAX_TREE
1114: fprintf(stderr, "add chars to %s \n", ctxt->node->name);
1115: #endif
1116: if ((lastChild != NULL) &&
1117: (lastChild->type == XML_CDATA_SECTION_NODE)) {
1118: xmlTextConcat(lastChild, value, len);
1119: } else {
1120: ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
1121: xmlAddChild(ctxt->node, ret);
1122: }
1.10 daniel 1123: }
1124:
1.18 daniel 1125: /*
1126: * Default handler for XML, builds the DOM tree
1127: */
1.1 daniel 1128: xmlSAXHandler xmlDefaultSAXHandler = {
1.10 daniel 1129: internalSubset,
1130: isStandalone,
1131: hasInternalSubset,
1132: hasExternalSubset,
1.1 daniel 1133: resolveEntity,
1.10 daniel 1134: getEntity,
1135: entityDecl,
1.1 daniel 1136: notationDecl,
1.10 daniel 1137: attributeDecl,
1138: elementDecl,
1.1 daniel 1139: unparsedEntityDecl,
1140: setDocumentLocator,
1141: startDocument,
1142: endDocument,
1143: startElement,
1144: endElement,
1.10 daniel 1145: reference,
1.1 daniel 1146: characters,
1147: ignorableWhitespace,
1148: processingInstruction,
1.10 daniel 1149: comment,
1.1 daniel 1150: xmlParserWarning,
1151: xmlParserError,
1.2 daniel 1152: xmlParserError,
1.20 daniel 1153: getParameterEntity,
1.25 daniel 1154: cdataBlock,
1.1 daniel 1155: };
1.2 daniel 1156:
1.5 daniel 1157: /**
1158: * xmlDefaultSAXHandlerInit:
1159: *
1160: * Initialize the default SAX handler
1161: */
1162: void
1163: xmlDefaultSAXHandlerInit(void)
1164: {
1.10 daniel 1165: xmlDefaultSAXHandler.internalSubset = internalSubset;
1166: xmlDefaultSAXHandler.isStandalone = isStandalone;
1167: xmlDefaultSAXHandler.hasInternalSubset = hasInternalSubset;
1168: xmlDefaultSAXHandler.hasExternalSubset = hasExternalSubset;
1.2 daniel 1169: xmlDefaultSAXHandler.resolveEntity = resolveEntity;
1.10 daniel 1170: xmlDefaultSAXHandler.getEntity = getEntity;
1.20 daniel 1171: xmlDefaultSAXHandler.getParameterEntity = getParameterEntity;
1.10 daniel 1172: xmlDefaultSAXHandler.entityDecl = entityDecl;
1173: xmlDefaultSAXHandler.attributeDecl = attributeDecl;
1174: xmlDefaultSAXHandler.elementDecl = elementDecl;
1.2 daniel 1175: xmlDefaultSAXHandler.notationDecl = notationDecl;
1176: xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
1177: xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1178: xmlDefaultSAXHandler.startDocument = startDocument;
1179: xmlDefaultSAXHandler.endDocument = endDocument;
1180: xmlDefaultSAXHandler.startElement = startElement;
1181: xmlDefaultSAXHandler.endElement = endElement;
1.10 daniel 1182: xmlDefaultSAXHandler.reference = reference;
1.2 daniel 1183: xmlDefaultSAXHandler.characters = characters;
1.25 daniel 1184: xmlDefaultSAXHandler.cdataBlock = cdataBlock;
1.2 daniel 1185: xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1186: xmlDefaultSAXHandler.processingInstruction = processingInstruction;
1.10 daniel 1187: xmlDefaultSAXHandler.comment = comment;
1.2 daniel 1188: xmlDefaultSAXHandler.warning = xmlParserWarning;
1189: xmlDefaultSAXHandler.error = xmlParserError;
1190: xmlDefaultSAXHandler.fatalError = xmlParserError;
1.18 daniel 1191: }
1192:
1193: /*
1194: * Default handler for HTML, builds the DOM tree
1195: */
1196: xmlSAXHandler htmlDefaultSAXHandler = {
1197: NULL,
1198: NULL,
1199: NULL,
1200: NULL,
1201: NULL,
1202: getEntity,
1203: NULL,
1204: NULL,
1205: NULL,
1206: NULL,
1207: NULL,
1208: setDocumentLocator,
1209: startDocument,
1210: endDocument,
1211: startElement,
1212: endElement,
1213: NULL,
1214: characters,
1215: ignorableWhitespace,
1216: NULL,
1217: comment,
1218: xmlParserWarning,
1219: xmlParserError,
1220: xmlParserError,
1.20 daniel 1221: getParameterEntity,
1.25 daniel 1222: NULL,
1.18 daniel 1223: };
1224:
1225: /**
1226: * htmlDefaultSAXHandlerInit:
1227: *
1228: * Initialize the default SAX handler
1229: */
1230: void
1231: htmlDefaultSAXHandlerInit(void)
1232: {
1233: htmlDefaultSAXHandler.internalSubset = NULL;
1234: htmlDefaultSAXHandler.isStandalone = NULL;
1235: htmlDefaultSAXHandler.hasInternalSubset = NULL;
1236: htmlDefaultSAXHandler.hasExternalSubset = NULL;
1237: htmlDefaultSAXHandler.resolveEntity = NULL;
1238: htmlDefaultSAXHandler.getEntity = getEntity;
1.20 daniel 1239: htmlDefaultSAXHandler.getParameterEntity = NULL;
1.18 daniel 1240: htmlDefaultSAXHandler.entityDecl = NULL;
1241: htmlDefaultSAXHandler.attributeDecl = NULL;
1242: htmlDefaultSAXHandler.elementDecl = NULL;
1243: htmlDefaultSAXHandler.notationDecl = NULL;
1244: htmlDefaultSAXHandler.unparsedEntityDecl = NULL;
1245: htmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
1246: htmlDefaultSAXHandler.startDocument = startDocument;
1247: htmlDefaultSAXHandler.endDocument = endDocument;
1248: htmlDefaultSAXHandler.startElement = startElement;
1249: htmlDefaultSAXHandler.endElement = endElement;
1250: htmlDefaultSAXHandler.reference = NULL;
1251: htmlDefaultSAXHandler.characters = characters;
1.25 daniel 1252: htmlDefaultSAXHandler.cdataBlock = NULL;
1.18 daniel 1253: htmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
1254: htmlDefaultSAXHandler.processingInstruction = NULL;
1255: htmlDefaultSAXHandler.comment = comment;
1256: htmlDefaultSAXHandler.warning = xmlParserWarning;
1257: htmlDefaultSAXHandler.error = xmlParserError;
1258: htmlDefaultSAXHandler.fatalError = xmlParserError;
1.2 daniel 1259: }
Webmaster