Annotation of XML/SAX.c, revision 1.14
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.1 daniel 11: #include "tree.h"
12: #include "parser.h"
1.10 daniel 13: #include "parserInternals.h"
14: #include "valid.h"
1.5 daniel 15: #include "entities.h"
1.9 daniel 16: #include "xml-error.h"
1.1 daniel 17:
1.14 ! daniel 18: #define DEBUG_SAX
1.2 daniel 19:
1.5 daniel 20: /**
21: * getPublicId:
22: * @ctxt: An XML parser context
23: *
1.1 daniel 24: * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
1.5 daniel 25: *
1.8 daniel 26: * Returns a CHAR *
1.1 daniel 27: */
1.5 daniel 28: const CHAR *
1.11 daniel 29: getPublicId(void *ctx)
1.5 daniel 30: {
1.11 daniel 31: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.1 daniel 32: return(NULL);
33: }
34:
1.5 daniel 35: /**
36: * getSystemId:
37: * @ctxt: An XML parser context
38: *
1.12 daniel 39: * Return the system ID, basically URL or filename e.g.
1.5 daniel 40: * http://www.sgmlsource.com/dtds/memo.dtd
41: *
1.8 daniel 42: * Returns a CHAR *
1.5 daniel 43: */
44: const CHAR *
1.11 daniel 45: getSystemId(void *ctx)
1.5 daniel 46: {
1.11 daniel 47: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2 daniel 48: return(ctxt->input->filename);
1.1 daniel 49: }
50:
1.5 daniel 51: /**
52: * getLineNumber:
53: * @ctxt: An XML parser context
54: *
1.1 daniel 55: * Return the line number of the current parsing point.
1.5 daniel 56: *
1.8 daniel 57: * Returns an int
1.1 daniel 58: */
1.5 daniel 59: int
1.11 daniel 60: getLineNumber(void *ctx)
1.5 daniel 61: {
1.11 daniel 62: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.1 daniel 63: return(ctxt->input->line);
64: }
1.5 daniel 65:
66: /**
67: * getColumnNumber:
68: * @ctxt: An XML parser context
69: *
1.1 daniel 70: * Return the column number of the current parsing point.
1.5 daniel 71: *
1.8 daniel 72: * Returns an int
1.1 daniel 73: */
1.5 daniel 74: int
1.11 daniel 75: getColumnNumber(void *ctx)
1.5 daniel 76: {
1.11 daniel 77: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.1 daniel 78: return(ctxt->input->col);
79: }
80:
81: /*
82: * The default SAX Locator.
83: */
84:
85: xmlSAXLocator xmlDefaultSAXLocator = {
86: getPublicId, getSystemId, getLineNumber, getColumnNumber
87: };
88:
1.5 daniel 89: /**
1.10 daniel 90: * isStandalone:
91: * @ctxt: An XML parser context
92: *
93: * Is this document tagged standalone ?
94: *
95: * Returns 1 if true
96: */
97: int
1.11 daniel 98: isStandalone(void *ctx)
1.10 daniel 99: {
1.11 daniel 100: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 101: return(ctxt->myDoc->standalone == 1);
102: }
103:
104: /**
105: * hasInternalSubset:
106: * @ctxt: An XML parser context
107: *
108: * Does this document has an internal subset
109: *
110: * Returns 1 if true
111: */
112: int
1.11 daniel 113: hasInternalSubset(void *ctx)
1.10 daniel 114: {
1.11 daniel 115: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 116: return(ctxt->myDoc->intSubset != NULL);
117: }
118:
119: /**
120: * hasExternalSubset:
121: * @ctxt: An XML parser context
122: *
123: * Does this document has an external subset
124: *
125: * Returns 1 if true
126: */
127: int
1.11 daniel 128: hasExternalSubset(void *ctx)
1.10 daniel 129: {
1.11 daniel 130: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 131: return(ctxt->myDoc->extSubset != NULL);
132: }
133:
134: /**
135: * hasInternalSubset:
136: * @ctxt: An XML parser context
137: *
138: * Does this document has an internal subset
139: */
140: void
1.11 daniel 141: internalSubset(void *ctx, const CHAR *name,
1.10 daniel 142: const CHAR *ExternalID, const CHAR *SystemID)
143: {
1.12 daniel 144: xmlDtdPtr externalSubset;
1.11 daniel 145: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 146: #ifdef DEBUG_SAX
147: fprintf(stderr, "SAX.internalSubset(%s, %s, %s)\n",
148: name, ExternalID, SystemID);
149: #endif
150: xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
1.12 daniel 151: if ((ExternalID != NULL) || (SystemID != NULL)) {
152: externalSubset = xmlParseDTD(ExternalID, SystemID);
153: }
1.10 daniel 154: }
155:
156: /**
1.5 daniel 157: * resolveEntity:
158: * @ctxt: An XML parser context
159: * @publicId: The public ID of the entity
160: * @systemId: The system ID of the entity
161: *
1.1 daniel 162: * Special entity resolver, better left to the parser, it has
163: * more context than the application layer.
1.5 daniel 164: * The default behaviour is to NOT resolve the entities, in that case
165: * the ENTITY_REF nodes are built in the structure (and the parameter
1.6 daniel 166: * values).
1.5 daniel 167: *
1.8 daniel 168: * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1.5 daniel 169: */
170: xmlParserInputPtr
1.11 daniel 171: resolveEntity(void *ctx, const CHAR *publicId, const CHAR *systemId)
1.5 daniel 172: {
1.12 daniel 173: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2 daniel 174:
175: #ifdef DEBUG_SAX
176: fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
177: #endif
1.5 daniel 178:
1.10 daniel 179: /*
180: * TODO : not 100% sure that the appropriate handling in that case.
181: */
1.12 daniel 182: if (systemId != NULL) {
183: return(xmlNewInputFromFile(ctxt, systemId));
184: }
1.1 daniel 185: return(NULL);
186: }
187:
1.5 daniel 188: /**
1.10 daniel 189: * getEntity:
190: * @ctxt: An XML parser context
191: * @name: The entity name
192: *
193: * Get an entity by name
194: *
1.13 daniel 195: * Returns the xmlEntityPtr if found.
1.10 daniel 196: */
197: xmlEntityPtr
1.11 daniel 198: getEntity(void *ctx, const CHAR *name)
1.10 daniel 199: {
1.11 daniel 200: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 201: xmlEntityPtr ret;
202:
203: #ifdef DEBUG_SAX
204: fprintf(stderr, "SAX.getEntity(%s)\n", name);
205: #endif
206:
207: ret = xmlGetDocEntity(ctxt->myDoc, name);
208: return(ret);
209: }
210:
211:
212: /**
213: * entityDecl:
214: * @ctxt: An XML parser context
215: * @name: the entity name
216: * @type: the entity type
217: * @publicId: The public ID of the entity
218: * @systemId: The system ID of the entity
219: * @content: the entity value (without processing).
220: *
221: * An entity definition has been parsed
222: */
223: void
1.11 daniel 224: entityDecl(void *ctx, const CHAR *name, int type,
1.10 daniel 225: const CHAR *publicId, const CHAR *systemId, CHAR *content)
226: {
1.11 daniel 227: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 228:
229: #ifdef DEBUG_SAX
230: fprintf(stderr, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
231: name, type, publicId, systemId, content);
232: #endif
233: xmlAddDocEntity(ctxt->myDoc, name, type, publicId, systemId, content);
234: }
235:
236: /**
237: * attributeDecl:
238: * @ctxt: An XML parser context
239: * @name: the attribute name
240: * @type: the attribute type
241: * @publicId: The public ID of the attribute
242: * @systemId: The system ID of the attribute
243: * @content: the attribute value (without processing).
244: *
245: * An attribute definition has been parsed
246: */
247: void
1.11 daniel 248: attributeDecl(void *ctx, const CHAR *elem, const CHAR *name,
1.10 daniel 249: int type, int def, const CHAR *defaultValue,
250: xmlEnumerationPtr tree)
251: {
1.11 daniel 252: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 253:
254: #ifdef DEBUG_SAX
255: fprintf(stderr, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
256: elem, name, type, def, defaultValue);
257: #endif
258: xmlAddAttributeDecl(ctxt->myDoc->intSubset, elem, name, type, def,
259: defaultValue, tree);
260: }
261:
262: /**
263: * elementDecl:
264: * @ctxt: An XML parser context
265: * @name: the element name
266: * @type: the element type
267: * @publicId: The public ID of the element
268: * @systemId: The system ID of the element
269: * @content: the element value (without processing).
270: *
271: * An element definition has been parsed
272: */
273: void
1.11 daniel 274: elementDecl(void *ctx, const CHAR *name, int type,
1.10 daniel 275: xmlElementContentPtr content)
276: {
1.11 daniel 277: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 278:
279: #ifdef DEBUG_SAX
280: fprintf(stderr, "SAX.elementDecl(%s, %d, ...)\n",
281: name, type);
282: #endif
283: xmlAddElementDecl(ctxt->myDoc->intSubset, name, type, content);
284: }
285:
286: /**
1.5 daniel 287: * notationDecl:
288: * @ctxt: An XML parser context
289: * @name: The name of the notation
290: * @publicId: The public ID of the entity
291: * @systemId: The system ID of the entity
292: *
1.1 daniel 293: * What to do when a notation declaration has been parsed.
294: * TODO Not handled currently.
295: */
1.5 daniel 296: void
1.11 daniel 297: notationDecl(void *ctx, const CHAR *name,
1.5 daniel 298: const CHAR *publicId, const CHAR *systemId)
299: {
1.11 daniel 300: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2 daniel 301: #ifdef DEBUG_SAX
302: fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
303: #endif
1.10 daniel 304: xmlAddNotationDecl(ctxt->myDoc->intSubset, name, publicId, systemId);
1.1 daniel 305: }
306:
1.5 daniel 307: /**
308: * unparsedEntityDecl:
309: * @ctxt: An XML parser context
310: * @name: The name of the entity
311: * @publicId: The public ID of the entity
312: * @systemId: The system ID of the entity
313: * @notationName: the name of the notation
314: *
1.1 daniel 315: * What to do when an unparsed entity declaration is parsed
316: * TODO Create an Entity node.
317: */
1.5 daniel 318: void
1.11 daniel 319: unparsedEntityDecl(void *ctx, const CHAR *name,
1.5 daniel 320: const CHAR *publicId, const CHAR *systemId,
321: const CHAR *notationName)
322: {
1.11 daniel 323: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2 daniel 324: #ifdef DEBUG_SAX
325: fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
326: name, publicId, systemId, notationName);
327: #endif
1.1 daniel 328: }
329:
1.5 daniel 330: /**
331: * setDocumentLocator:
332: * @ctxt: An XML parser context
333: * @loc: A SAX Locator
334: *
1.1 daniel 335: * Receive the document locator at startup, actually xmlDefaultSAXLocator
336: * Everything is available on the context, so this is useless in our case.
337: */
1.5 daniel 338: void
1.11 daniel 339: setDocumentLocator(void *ctx, xmlSAXLocatorPtr loc)
1.5 daniel 340: {
1.11 daniel 341: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2 daniel 342: #ifdef DEBUG_SAX
343: fprintf(stderr, "SAX.setDocumentLocator()\n");
344: #endif
1.1 daniel 345: }
346:
1.5 daniel 347: /**
348: * startDocument:
349: * @ctxt: An XML parser context
350: *
1.1 daniel 351: * called when the document start being processed.
352: */
1.5 daniel 353: void
1.11 daniel 354: startDocument(void *ctx)
1.5 daniel 355: {
1.11 daniel 356: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 357: xmlDocPtr doc;
358:
1.2 daniel 359: #ifdef DEBUG_SAX
360: fprintf(stderr, "SAX.startDocument()\n");
361: #endif
1.10 daniel 362: doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
363: if (doc != NULL) {
364: if (ctxt->encoding != NULL)
365: doc->encoding = xmlStrdup(ctxt->encoding);
366: else
367: doc->encoding = NULL;
368: doc->standalone = ctxt->standalone;
369: }
1.1 daniel 370: }
371:
1.5 daniel 372: /**
373: * endDocument:
374: * @ctxt: An XML parser context
375: *
1.1 daniel 376: * called when the document end has been detected.
377: */
1.5 daniel 378: void
1.11 daniel 379: endDocument(void *ctx)
1.5 daniel 380: {
1.11 daniel 381: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2 daniel 382: #ifdef DEBUG_SAX
383: fprintf(stderr, "SAX.endDocument()\n");
384: #endif
1.1 daniel 385: }
386:
1.5 daniel 387: /**
1.10 daniel 388: * attribute:
389: * @ctxt: An XML parser context
390: * @name: The attribute name
391: * @value: The attribute value
392: *
393: * Handle an attribute that has been read by the parser.
394: * The default handling is to convert the attribute into an
395: * DOM subtree and past it in a new xmlAttr element added to
396: * the element.
397: */
398: void
1.11 daniel 399: attribute(void *ctx, const CHAR *fullname, const CHAR *value)
1.10 daniel 400: {
1.11 daniel 401: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 402: xmlAttrPtr ret;
403: CHAR *name;
404: CHAR *ns;
405:
406: /****************
407: #ifdef DEBUG_SAX
408: fprintf(stderr, "SAX.attribute(%s, %s)\n", fullname, value);
409: #endif
410: ****************/
411: /*
412: * Split the full name into a namespace prefix and the tag name
413: */
414: name = xmlSplitQName(fullname, &ns);
415:
416: /*
417: * Check whether it's a namespace definition
418: */
419: if ((ns == NULL) &&
420: (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
421: (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
422: /* a default namespace definition */
423: xmlNewNs(ctxt->node, value, NULL);
424: if (name != NULL)
425: free(name);
426: return;
427: }
428: if ((ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
429: (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
430: /* a standard namespace definition */
431: xmlNewNs(ctxt->node, value, name);
432: free(ns);
433: if (name != NULL)
434: free(name);
435: return;
436: }
437:
438: ret = xmlNewProp(ctxt->node, name, NULL);
1.14 ! daniel 439: if ((ret != NULL) && (ctxt->replaceEntities == 0))
1.10 daniel 440: ret->val = xmlStringGetNodeList(ctxt->myDoc, value);
441: if (name != NULL)
442: free(name);
443: if (ns != NULL)
444: free(ns);
445: }
446:
447: /**
1.5 daniel 448: * startElement:
449: * @ctxt: An XML parser context
450: * @name: The element name
1.10 daniel 451: * @atts: An array of name/value attributes pairs, NULL terminated
1.5 daniel 452: *
1.1 daniel 453: * called when an opening tag has been processed.
454: * TODO We currently have a small pblm with the arguments ...
455: */
1.5 daniel 456: void
1.11 daniel 457: startElement(void *ctx, const CHAR *fullname, const CHAR **atts)
1.5 daniel 458: {
1.11 daniel 459: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 460: xmlNodePtr ret;
461: xmlNodePtr parent = ctxt->node;
462: xmlNsPtr ns;
463: CHAR *name;
464: CHAR *prefix;
465: const CHAR *att;
466: const CHAR *value;
467:
468: int i;
469:
1.2 daniel 470: #ifdef DEBUG_SAX
1.10 daniel 471: fprintf(stderr, "SAX.startElement(%s)\n", fullname);
1.2 daniel 472: #endif
1.10 daniel 473: /*
474: * Split the full name into a namespace prefix and the tag name
475: */
476: name = xmlSplitQName(fullname, &prefix);
477:
478:
479: /*
480: * Note : the namespace resolution is deferred until the end of the
481: * attributes parsing, since local namespace can be defined as
482: * an attribute at this level.
483: */
484: ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
485: if (ret == NULL) return;
486: if (ctxt->myDoc->root == NULL)
487: ctxt->myDoc->root = ret;
488:
489: /*
490: * We are parsing a new node.
491: */
492: nodePush(ctxt, ret);
493:
494: /*
495: * Link the child element
496: */
497: if (parent != NULL)
498: xmlAddChild(parent, ctxt->node);
499:
500: /*
501: * process all the attributes.
502: */
503: if (atts != NULL) {
504: i = 0;
505: att = atts[i++];
506: value = atts[i++];
507: while ((att != NULL) && (value != NULL)) {
508: /*
509: * Handle one pair of attribute/value
510: */
511: attribute(ctxt, att, value);
512:
513: /*
514: * Next ones
515: */
516: att = atts[i++];
517: value = atts[i++];
518: }
519: }
520:
521: /*
522: * Search the namespace, note that since the attributes have been
523: * processed, the local namespaces are available.
524: */
525: ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
526: if ((ns == NULL) && (parent != NULL))
527: ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
528: xmlSetNs(ret, ns);
529:
530: if (prefix != NULL)
531: free(prefix);
532: if (name != NULL)
533: free(name);
534:
1.1 daniel 535: }
536:
1.5 daniel 537: /**
538: * endElement:
539: * @ctxt: An XML parser context
540: * @name: The element name
541: *
1.1 daniel 542: * called when the end of an element has been detected.
543: */
1.5 daniel 544: void
1.11 daniel 545: endElement(void *ctx, const CHAR *name)
1.5 daniel 546: {
1.11 daniel 547: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 548: xmlParserNodeInfo node_info;
549: xmlNodePtr cur = ctxt->node;
550:
1.2 daniel 551: #ifdef DEBUG_SAX
1.10 daniel 552: if (name == NULL)
553: fprintf(stderr, "SAX.endElement(NULL)\n");
554: else
555: fprintf(stderr, "SAX.endElement(%s)\n", name);
556: #endif
557:
558: /* Capture end position and add node */
559: if (cur != NULL && ctxt->record_info) {
560: node_info.end_pos = ctxt->input->cur - ctxt->input->base;
561: node_info.end_line = ctxt->input->line;
562: node_info.node = cur;
563: xmlParserAddNodeInfo(ctxt, &node_info);
564: }
565:
566: /*
567: * end of parsing of this node.
568: */
569: nodePop(ctxt);
1.1 daniel 570: }
571:
1.5 daniel 572: /**
1.10 daniel 573: * reference:
1.5 daniel 574: * @ctxt: An XML parser context
1.10 daniel 575: * @name: The entity name
1.5 daniel 576: *
1.10 daniel 577: * called when an entity reference is detected.
1.5 daniel 578: */
579: void
1.11 daniel 580: reference(void *ctx, const CHAR *name)
1.5 daniel 581: {
1.11 daniel 582: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 583: xmlNodePtr ret;
584:
1.5 daniel 585: #ifdef DEBUG_SAX
1.10 daniel 586: fprintf(stderr, "SAX.reference(%s)\n", name);
1.5 daniel 587: #endif
1.10 daniel 588: ret = xmlNewReference(ctxt->myDoc, name);
589: xmlAddChild(ctxt->node, ret);
1.5 daniel 590: }
591:
592: /**
593: * characters:
594: * @ctxt: An XML parser context
595: * @ch: a CHAR string
596: * @len: the number of CHAR
597: *
1.1 daniel 598: * receiving some chars from the parser.
599: * Question: how much at a time ???
600: */
1.5 daniel 601: void
1.11 daniel 602: characters(void *ctx, const CHAR *ch, int len)
1.5 daniel 603: {
1.11 daniel 604: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.2 daniel 605: xmlNodePtr lastChild;
606:
607: #ifdef DEBUG_SAX
1.10 daniel 608: fprintf(stderr, "SAX.characters(%.30s, %d)\n", ch, len);
1.2 daniel 609: #endif
610: /*
611: * Handle the data if any. If there is no child
612: * add it as content, otherwise if the last child is text,
613: * concatenate it, else create a new node of type text.
614: */
615:
616: lastChild = xmlGetLastChild(ctxt->node);
617: if (lastChild == NULL)
1.10 daniel 618: xmlNodeAddContentLen(ctxt->node, ch, len);
1.2 daniel 619: else {
620: if (xmlNodeIsText(lastChild))
1.10 daniel 621: xmlTextConcat(lastChild, ch, len);
1.2 daniel 622: else {
1.10 daniel 623: lastChild = xmlNewTextLen(ch, len);
1.2 daniel 624: xmlAddChild(ctxt->node, lastChild);
625: }
626: }
1.1 daniel 627: }
628:
1.5 daniel 629: /**
630: * ignorableWhitespace:
631: * @ctxt: An XML parser context
632: * @ch: a CHAR string
633: * @len: the number of CHAR
634: *
1.1 daniel 635: * receiving some ignorable whitespaces from the parser.
636: * Question: how much at a time ???
637: */
1.5 daniel 638: void
1.11 daniel 639: ignorableWhitespace(void *ctx, const CHAR *ch, int len)
1.5 daniel 640: {
1.11 daniel 641: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2 daniel 642: #ifdef DEBUG_SAX
1.10 daniel 643: fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
1.2 daniel 644: #endif
1.1 daniel 645: }
646:
1.5 daniel 647: /**
648: * processingInstruction:
649: * @ctxt: An XML parser context
650: * @target: the target name
651: * @data: the PI data's
652: * @len: the number of CHAR
653: *
654: * A processing instruction has been parsed.
655: */
656: void
1.11 daniel 657: processingInstruction(void *ctx, const CHAR *target,
1.5 daniel 658: const CHAR *data)
659: {
1.11 daniel 660: /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1.2 daniel 661: #ifdef DEBUG_SAX
662: fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
663: #endif
1.1 daniel 664: }
665:
1.10 daniel 666: /**
667: * globalNamespace:
668: * @ctxt: An XML parser context
669: * @href: the namespace associated URN
670: * @prefix: the namespace prefix
671: *
672: * An old global namespace has been parsed.
673: */
674: void
1.11 daniel 675: globalNamespace(void *ctx, const CHAR *href, const CHAR *prefix)
1.10 daniel 676: {
1.11 daniel 677: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 678: #ifdef DEBUG_SAX
679: fprintf(stderr, "SAX.globalNamespace(%s, %s)\n", href, prefix);
680: #endif
681: xmlNewGlobalNs(ctxt->myDoc, href, prefix);
682: }
683:
684: /**
685: * setNamespace:
686: * @ctxt: An XML parser context
687: * @name: the namespace prefix
688: *
689: * Set the current element namespace.
690: */
691: void
1.11 daniel 692: setNamespace(void *ctx, const CHAR *name)
1.10 daniel 693: {
1.11 daniel 694: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 695: xmlNsPtr ns;
696: xmlNodePtr parent;
697:
698: #ifdef DEBUG_SAX
699: fprintf(stderr, "SAX.setNamespace(%s)\n", name);
700: #endif
701: ns = xmlSearchNs(ctxt->myDoc, ctxt->node, name);
702: if (ns == NULL) { /* ctxt->node may not have a parent yet ! */
703: if (ctxt->nodeNr >= 2) {
704: parent = ctxt->nodeTab[ctxt->nodeNr - 2];
705: if (parent != NULL)
706: ns = xmlSearchNs(ctxt->myDoc, parent, name);
707: }
708: }
709: xmlSetNs(ctxt->node, ns);
710: }
711:
712: /**
713: * getNamespace:
714: * @ctxt: An XML parser context
715: *
716: * Get the current element namespace.
717: */
718: xmlNsPtr
1.11 daniel 719: getNamespace(void *ctx)
1.10 daniel 720: {
1.11 daniel 721: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 722: xmlNsPtr ret;
723:
724: #ifdef DEBUG_SAX
725: fprintf(stderr, "SAX.getNamespace()\n");
726: #endif
727: ret = ctxt->node->ns;
728: return(ret);
729: }
730:
731: /**
732: * checkNamespace:
733: * @ctxt: An XML parser context
734: * @namespace: the namespace to check against
735: *
736: * Check that the current element namespace is the same as the
737: * one read upon parsing.
738: */
739: int
1.11 daniel 740: checkNamespace(void *ctx, CHAR *namespace)
1.10 daniel 741: {
1.11 daniel 742: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 743: xmlNodePtr cur = ctxt->node;
744:
745: #ifdef DEBUG_SAX
746: fprintf(stderr, "SAX.checkNamespace(%s)\n", namespace);
747: #endif
748:
749: /*
750: * Check that the Name in the ETag is the same as in the STag.
751: */
752: if (namespace == NULL) {
753: if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
754: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
755: ctxt->sax->error(ctxt,
756: "End tags for %s don't hold the namespace %s\n",
757: cur->name, cur->ns->prefix);
758: ctxt->wellFormed = 0;
759: }
760: } else {
761: if ((cur->ns == NULL) || (cur->ns->prefix == NULL)) {
762: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
763: ctxt->sax->error(ctxt,
764: "End tags %s holds a prefix %s not used by the open tag\n",
765: cur->name, namespace);
766: ctxt->wellFormed = 0;
767: } else if (strcmp(namespace, cur->ns->prefix)) {
768: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
769: ctxt->sax->error(ctxt,
770: "Start and End tags for %s don't use the same namespaces: %s and %s\n",
771: cur->name, cur->ns->prefix, namespace);
772: ctxt->wellFormed = 0;
773: } else
774: return(1);
775: }
776: return(0);
777: }
778:
779: /**
780: * namespaceDecl:
781: * @ctxt: An XML parser context
782: * @href: the namespace associated URN
783: * @prefix: the namespace prefix
784: *
785: * A namespace has been parsed.
786: */
787: void
1.11 daniel 788: namespaceDecl(void *ctx, const CHAR *href, const CHAR *prefix)
1.10 daniel 789: {
1.11 daniel 790: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 791: #ifdef DEBUG_SAX
792: if (prefix == NULL)
793: fprintf(stderr, "SAX.namespaceDecl(%s, NULL)\n", href);
794: else
795: fprintf(stderr, "SAX.namespaceDecl(%s, %s)\n", href, prefix);
796: #endif
797: xmlNewNs(ctxt->node, href, prefix);
798: }
799:
800: /**
801: * comment:
802: * @ctxt: An XML parser context
803: * @value: the comment content
804: *
805: * A comment has been parsed.
806: */
807: void
1.11 daniel 808: comment(void *ctx, const CHAR *value)
1.10 daniel 809: {
1.11 daniel 810: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1.10 daniel 811: #ifdef DEBUG_SAX
812: fprintf(stderr, "SAX.comment(%s)\n", value);
813: #endif
814: xmlNewDocComment(ctxt->myDoc, value);
815: }
816:
1.1 daniel 817: xmlSAXHandler xmlDefaultSAXHandler = {
1.10 daniel 818: internalSubset,
819: isStandalone,
820: hasInternalSubset,
821: hasExternalSubset,
1.1 daniel 822: resolveEntity,
1.10 daniel 823: getEntity,
824: entityDecl,
1.1 daniel 825: notationDecl,
1.10 daniel 826: attributeDecl,
827: elementDecl,
1.1 daniel 828: unparsedEntityDecl,
829: setDocumentLocator,
830: startDocument,
831: endDocument,
832: startElement,
833: endElement,
1.10 daniel 834: reference,
1.1 daniel 835: characters,
836: ignorableWhitespace,
837: processingInstruction,
1.10 daniel 838: comment,
1.1 daniel 839: xmlParserWarning,
840: xmlParserError,
1.2 daniel 841: xmlParserError,
1.1 daniel 842: };
1.2 daniel 843:
1.5 daniel 844: /**
845: * xmlDefaultSAXHandlerInit:
846: *
847: * Initialize the default SAX handler
848: */
849: void
850: xmlDefaultSAXHandlerInit(void)
851: {
1.10 daniel 852: xmlDefaultSAXHandler.internalSubset = internalSubset;
853: xmlDefaultSAXHandler.isStandalone = isStandalone;
854: xmlDefaultSAXHandler.hasInternalSubset = hasInternalSubset;
855: xmlDefaultSAXHandler.hasExternalSubset = hasExternalSubset;
1.2 daniel 856: xmlDefaultSAXHandler.resolveEntity = resolveEntity;
1.10 daniel 857: xmlDefaultSAXHandler.getEntity = getEntity;
858: xmlDefaultSAXHandler.entityDecl = entityDecl;
859: xmlDefaultSAXHandler.attributeDecl = attributeDecl;
860: xmlDefaultSAXHandler.elementDecl = elementDecl;
1.2 daniel 861: xmlDefaultSAXHandler.notationDecl = notationDecl;
862: xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
863: xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
864: xmlDefaultSAXHandler.startDocument = startDocument;
865: xmlDefaultSAXHandler.endDocument = endDocument;
866: xmlDefaultSAXHandler.startElement = startElement;
867: xmlDefaultSAXHandler.endElement = endElement;
1.10 daniel 868: xmlDefaultSAXHandler.reference = reference;
1.2 daniel 869: xmlDefaultSAXHandler.characters = characters;
870: xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
871: xmlDefaultSAXHandler.processingInstruction = processingInstruction;
1.10 daniel 872: xmlDefaultSAXHandler.comment = comment;
1.2 daniel 873: xmlDefaultSAXHandler.warning = xmlParserWarning;
874: xmlDefaultSAXHandler.error = xmlParserError;
875: xmlDefaultSAXHandler.fatalError = xmlParserError;
876: }
Webmaster