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