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