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