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