2 * SAX.c : Default SAX handler to build a tree.
4 * See Copyright for the status of this software.
6 * Daniel Veillard <daniel@veillard.com>
14 #include <libxml/xmlmemory.h>
15 #include <libxml/tree.h>
16 #include <libxml/parser.h>
17 #include <libxml/parserInternals.h>
18 #include <libxml/valid.h>
19 #include <libxml/entities.h>
20 #include <libxml/xmlerror.h>
21 #include <libxml/debugXML.h>
22 #include <libxml/xmlIO.h>
23 #include <libxml/SAX.h>
24 #include <libxml/uri.h>
25 #include <libxml/valid.h>
26 #include <libxml/HTMLtree.h>
27 #include <libxml/globals.h>
29 /* #define DEBUG_SAX */
30 /* #define DEBUG_SAX_TREE */
34 * @ctx: the user data (XML parser context)
36 * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
41 getPublicId(void *ctx ATTRIBUTE_UNUSED)
43 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
49 * @ctx: the user data (XML parser context)
51 * Provides the system ID, basically URL or filename e.g.
52 * http://www.sgmlsource.com/dtds/memo.dtd
57 getSystemId(void *ctx)
59 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
60 return((const xmlChar *) ctxt->input->filename);
65 * @ctx: the user data (XML parser context)
67 * Provide the line number of the current parsing point.
72 getLineNumber(void *ctx)
74 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
75 return(ctxt->input->line);
80 * @ctx: the user data (XML parser context)
82 * Provide the column number of the current parsing point.
87 getColumnNumber(void *ctx)
89 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
90 return(ctxt->input->col);
95 * @ctx: the user data (XML parser context)
97 * Is this document tagged standalone ?
102 isStandalone(void *ctx)
104 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
105 return(ctxt->myDoc->standalone == 1);
110 * @ctx: the user data (XML parser context)
112 * Does this document has an internal subset
117 hasInternalSubset(void *ctx)
119 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
120 return(ctxt->myDoc->intSubset != NULL);
125 * @ctx: the user data (XML parser context)
127 * Does this document has an external subset
132 hasExternalSubset(void *ctx)
134 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
135 return(ctxt->myDoc->extSubset != NULL);
140 * @ctx: the user data (XML parser context)
141 * @name: the root element name
142 * @ExternalID: the external ID
143 * @SystemID: the SYSTEM ID (e.g. filename or URL)
145 * Callback on internal subset declaration.
148 internalSubset(void *ctx, const xmlChar *name,
149 const xmlChar *ExternalID, const xmlChar *SystemID)
151 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
154 xmlGenericError(xmlGenericErrorContext,
155 "SAX.internalSubset(%s, %s, %s)\n",
156 name, ExternalID, SystemID);
159 if (ctxt->myDoc == NULL)
161 dtd = xmlGetIntSubset(ctxt->myDoc);
165 xmlUnlinkNode((xmlNodePtr) dtd);
167 ctxt->myDoc->intSubset = NULL;
169 ctxt->myDoc->intSubset =
170 xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
175 * @ctx: the user data (XML parser context)
176 * @name: the root element name
177 * @ExternalID: the external ID
178 * @SystemID: the SYSTEM ID (e.g. filename or URL)
180 * Callback on external subset declaration.
183 externalSubset(void *ctx, const xmlChar *name,
184 const xmlChar *ExternalID, const xmlChar *SystemID)
186 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
188 xmlGenericError(xmlGenericErrorContext,
189 "SAX.externalSubset(%s, %s, %s)\n",
190 name, ExternalID, SystemID);
192 if (((ExternalID != NULL) || (SystemID != NULL)) &&
193 (((ctxt->validate) || (ctxt->loadsubset != 0)) &&
194 (ctxt->wellFormed && ctxt->myDoc))) {
196 * Try to fetch and parse the external subset.
198 xmlParserInputPtr oldinput;
201 xmlParserInputPtr *oldinputTab;
202 xmlParserInputPtr input = NULL;
207 * Ask the Entity resolver to load the damn thing
209 if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
210 input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
216 xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
219 * make sure we won't destroy the main document context
221 oldinput = ctxt->input;
222 oldinputNr = ctxt->inputNr;
223 oldinputMax = ctxt->inputMax;
224 oldinputTab = ctxt->inputTab;
225 oldcharset = ctxt->charset;
227 ctxt->inputTab = (xmlParserInputPtr *)
228 xmlMalloc(5 * sizeof(xmlParserInputPtr));
229 if (ctxt->inputTab == NULL) {
230 ctxt->errNo = XML_ERR_NO_MEMORY;
231 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
232 ctxt->sax->error(ctxt->userData,
233 "externalSubset: out of memory\n");
234 ctxt->errNo = XML_ERR_NO_MEMORY;
235 ctxt->instate = XML_PARSER_EOF;
236 ctxt->disableSAX = 1;
237 ctxt->input = oldinput;
238 ctxt->inputNr = oldinputNr;
239 ctxt->inputMax = oldinputMax;
240 ctxt->inputTab = oldinputTab;
241 ctxt->charset = oldcharset;
247 xmlPushInput(ctxt, input);
250 * On the fly encoding conversion if needed
252 if (ctxt->input->length >= 4) {
253 enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
254 xmlSwitchEncoding(ctxt, enc);
257 if (input->filename == NULL)
258 input->filename = (char *) xmlCanonicPath(SystemID);
261 input->base = ctxt->input->cur;
262 input->cur = ctxt->input->cur;
266 * let's parse that entity knowing it's an external subset.
268 xmlParseExternalSubset(ctxt, ExternalID, SystemID);
271 * Free up the external entities
274 while (ctxt->inputNr > 1)
276 xmlFreeInputStream(ctxt->input);
277 xmlFree(ctxt->inputTab);
280 * Restore the parsing context of the main entity
282 ctxt->input = oldinput;
283 ctxt->inputNr = oldinputNr;
284 ctxt->inputMax = oldinputMax;
285 ctxt->inputTab = oldinputTab;
286 ctxt->charset = oldcharset;
287 /* ctxt->wellFormed = oldwellFormed; */
293 * @ctx: the user data (XML parser context)
294 * @publicId: The public ID of the entity
295 * @systemId: The system ID of the entity
297 * The entity loader, to control the loading of external entities,
298 * the application can either:
299 * - override this resolveEntity() callback in the SAX block
300 * - or better use the xmlSetExternalEntityLoader() function to
301 * set up it's own entity resolution routine
303 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
306 resolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
308 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
309 xmlParserInputPtr ret;
311 const char *base = NULL;
313 if (ctxt->input != NULL)
314 base = ctxt->input->filename;
316 base = ctxt->directory;
318 URI = xmlBuildURI(systemId, (const xmlChar *) base);
321 xmlGenericError(xmlGenericErrorContext,
322 "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
325 ret = xmlLoadExternalEntity((const char *) URI,
326 (const char *) publicId, ctxt);
334 * @ctx: the user data (XML parser context)
335 * @name: The entity name
337 * Get an entity by name
339 * Returns the xmlEntityPtr if found.
342 getEntity(void *ctx, const xmlChar *name)
344 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
345 xmlEntityPtr ret = NULL;
348 xmlGenericError(xmlGenericErrorContext,
349 "SAX.getEntity(%s)\n", name);
352 if (ctxt->inSubset == 0) {
353 ret = xmlGetPredefinedEntity(name);
357 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1)) {
358 if (ctxt->inSubset == 2) {
359 ctxt->myDoc->standalone = 0;
360 ret = xmlGetDocEntity(ctxt->myDoc, name);
361 ctxt->myDoc->standalone = 1;
363 ret = xmlGetDocEntity(ctxt->myDoc, name);
365 ctxt->myDoc->standalone = 0;
366 ret = xmlGetDocEntity(ctxt->myDoc, name);
368 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
369 ctxt->sax->error(ctxt,
370 "Entity(%s) document marked standalone but require external subset\n",
373 ctxt->wellFormed = 0;
375 ctxt->myDoc->standalone = 1;
379 ret = xmlGetDocEntity(ctxt->myDoc, name);
382 ((ctxt->validate) || (ctxt->replaceEntities)) &&
383 (ret->children == NULL) &&
384 (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
388 * for validation purposes we really need to fetch and
389 * parse the external entity
393 val = xmlParseCtxtExternalEntity(ctxt, ret->URI,
394 ret->ExternalID, &children);
396 xmlAddChildList((xmlNodePtr) ret, children);
398 ctxt->sax->error(ctxt,
399 "Failure to process entity %s\n", name);
400 ctxt->wellFormed = 0;
411 * getParameterEntity:
412 * @ctx: the user data (XML parser context)
413 * @name: The entity name
415 * Get a parameter entity by name
417 * Returns the xmlEntityPtr if found.
420 getParameterEntity(void *ctx, const xmlChar *name)
422 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
426 xmlGenericError(xmlGenericErrorContext,
427 "SAX.getParameterEntity(%s)\n", name);
430 ret = xmlGetParameterEntity(ctxt->myDoc, name);
437 * @ctx: the user data (XML parser context)
438 * @name: the entity name
439 * @type: the entity type
440 * @publicId: The public ID of the entity
441 * @systemId: The system ID of the entity
442 * @content: the entity value (without processing).
444 * An entity definition has been parsed
447 entityDecl(void *ctx, const xmlChar *name, int type,
448 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
451 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
454 xmlGenericError(xmlGenericErrorContext,
455 "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
456 name, type, publicId, systemId, content);
458 if (ctxt->inSubset == 1) {
459 ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
461 if ((ent == NULL) && (ctxt->pedantic) &&
462 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
463 ctxt->sax->warning(ctxt,
464 "Entity(%s) already defined in the internal subset\n", name);
465 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
467 const char *base = NULL;
469 if (ctxt->input != NULL)
470 base = ctxt->input->filename;
472 base = ctxt->directory;
474 URI = xmlBuildURI(systemId, (const xmlChar *) base);
477 } else if (ctxt->inSubset == 2) {
478 ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
480 if ((ent == NULL) && (ctxt->pedantic) &&
481 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
482 ctxt->sax->warning(ctxt,
483 "Entity(%s) already defined in the external subset\n", name);
484 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
486 const char *base = NULL;
488 if (ctxt->input != NULL)
489 base = ctxt->input->filename;
491 base = ctxt->directory;
493 URI = xmlBuildURI(systemId, (const xmlChar *) base);
497 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
498 ctxt->sax->error(ctxt,
499 "SAX.entityDecl(%s) called while not in subset\n", name);
505 * @ctx: the user data (XML parser context)
506 * @elem: the name of the element
507 * @fullname: the attribute name
508 * @type: the attribute type
509 * @def: the type of default value
510 * @defaultValue: the attribute default value
511 * @tree: the tree of enumerated value set
513 * An attribute definition has been parsed
516 attributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
517 int type, int def, const xmlChar *defaultValue,
518 xmlEnumerationPtr tree)
520 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
521 xmlAttributePtr attr;
522 xmlChar *name = NULL, *prefix = NULL;
525 xmlGenericError(xmlGenericErrorContext,
526 "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
527 elem, fullname, type, def, defaultValue);
529 name = xmlSplitQName(ctxt, fullname, &prefix);
530 ctxt->vctxt.valid = 1;
531 if (ctxt->inSubset == 1)
532 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
533 name, prefix, (xmlAttributeType) type,
534 (xmlAttributeDefault) def, defaultValue, tree);
535 else if (ctxt->inSubset == 2)
536 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
537 name, prefix, (xmlAttributeType) type,
538 (xmlAttributeDefault) def, defaultValue, tree);
540 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
541 ctxt->sax->error(ctxt,
542 "SAX.attributeDecl(%s) called while not in subset\n", name);
545 if (ctxt->vctxt.valid == 0)
547 if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) &&
548 (ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset != NULL))
549 ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
559 * @ctx: the user data (XML parser context)
560 * @name: the element name
561 * @type: the element type
562 * @content: the element value tree
564 * An element definition has been parsed
567 elementDecl(void *ctx, const xmlChar * name, int type,
568 xmlElementContentPtr content)
570 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
571 xmlElementPtr elem = NULL;
574 xmlGenericError(xmlGenericErrorContext,
575 "SAX.elementDecl(%s, %d, ...)\n", name, type);
578 if (ctxt->inSubset == 1)
579 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
580 name, (xmlElementTypeVal) type, content);
581 else if (ctxt->inSubset == 2)
582 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
583 name, (xmlElementTypeVal) type, content);
585 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
586 ctxt->sax->error(ctxt,
587 "SAX.elementDecl(%s) called while not in subset\n",
593 if (ctxt->validate && ctxt->wellFormed &&
594 ctxt->myDoc && ctxt->myDoc->intSubset)
596 xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
601 * @ctx: the user data (XML parser context)
602 * @name: The name of the notation
603 * @publicId: The public ID of the entity
604 * @systemId: The system ID of the entity
606 * What to do when a notation declaration has been parsed.
609 notationDecl(void *ctx, const xmlChar *name,
610 const xmlChar *publicId, const xmlChar *systemId)
612 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
613 xmlNotationPtr nota = NULL;
616 xmlGenericError(xmlGenericErrorContext,
617 "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
620 if ((publicId == NULL) && (systemId == NULL)) {
621 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
622 ctxt->sax->error(ctxt,
623 "SAX.notationDecl(%s) externalID or PublicID missing\n", name);
625 ctxt->wellFormed = 0;
627 } else if (ctxt->inSubset == 1)
628 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
630 else if (ctxt->inSubset == 2)
631 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name,
634 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
635 ctxt->sax->error(ctxt,
636 "SAX.notationDecl(%s) called while not in subset\n", name);
639 if (nota == NULL) ctxt->valid = 0;
640 if (ctxt->validate && ctxt->wellFormed &&
641 ctxt->myDoc && ctxt->myDoc->intSubset)
642 ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
647 * unparsedEntityDecl:
648 * @ctx: the user data (XML parser context)
649 * @name: The name of the entity
650 * @publicId: The public ID of the entity
651 * @systemId: The system ID of the entity
652 * @notationName: the name of the notation
654 * What to do when an unparsed entity declaration is parsed
657 unparsedEntityDecl(void *ctx, const xmlChar *name,
658 const xmlChar *publicId, const xmlChar *systemId,
659 const xmlChar *notationName)
662 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
664 xmlGenericError(xmlGenericErrorContext,
665 "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
666 name, publicId, systemId, notationName);
668 if (ctxt->inSubset == 1) {
669 ent = xmlAddDocEntity(ctxt->myDoc, name,
670 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
671 publicId, systemId, notationName);
672 if ((ent == NULL) && (ctxt->pedantic) &&
673 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
674 ctxt->sax->warning(ctxt,
675 "Entity(%s) already defined in the internal subset\n", name);
676 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
678 const char *base = NULL;
680 if (ctxt->input != NULL)
681 base = ctxt->input->filename;
683 base = ctxt->directory;
685 URI = xmlBuildURI(systemId, (const xmlChar *) base);
688 } else if (ctxt->inSubset == 2) {
689 ent = xmlAddDtdEntity(ctxt->myDoc, name,
690 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
691 publicId, systemId, notationName);
692 if ((ent == NULL) && (ctxt->pedantic) &&
693 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
694 ctxt->sax->warning(ctxt,
695 "Entity(%s) already defined in the external subset\n", name);
696 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
698 const char *base = NULL;
700 if (ctxt->input != NULL)
701 base = ctxt->input->filename;
703 base = ctxt->directory;
705 URI = xmlBuildURI(systemId, (const xmlChar *) base);
709 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
710 ctxt->sax->error(ctxt,
711 "SAX.unparsedEntityDecl(%s) called while not in subset\n", name);
716 * setDocumentLocator:
717 * @ctx: the user data (XML parser context)
718 * @loc: A SAX Locator
720 * Receive the document locator at startup, actually xmlDefaultSAXLocator
721 * Everything is available on the context, so this is useless in our case.
724 setDocumentLocator(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
726 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
728 xmlGenericError(xmlGenericErrorContext,
729 "SAX.setDocumentLocator()\n");
735 * @ctx: the user data (XML parser context)
737 * called when the document start being processed.
740 startDocument(void *ctx)
742 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
746 xmlGenericError(xmlGenericErrorContext,
747 "SAX.startDocument()\n");
750 #ifdef LIBXML_HTML_ENABLED
751 if (ctxt->myDoc == NULL)
752 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
753 if (ctxt->myDoc == NULL) {
754 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
755 ctxt->sax->error(ctxt->userData,
756 "SAX.startDocument(): out of memory\n");
757 ctxt->errNo = XML_ERR_NO_MEMORY;
758 ctxt->instate = XML_PARSER_EOF;
759 ctxt->disableSAX = 1;
763 xmlGenericError(xmlGenericErrorContext,
764 "libxml2 built without HTML support\n");
765 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
766 ctxt->instate = XML_PARSER_EOF;
767 ctxt->disableSAX = 1;
771 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
773 if (ctxt->encoding != NULL)
774 doc->encoding = xmlStrdup(ctxt->encoding);
776 doc->encoding = NULL;
777 doc->standalone = ctxt->standalone;
779 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
780 ctxt->sax->error(ctxt->userData,
781 "SAX.startDocument(): out of memory\n");
782 ctxt->errNo = XML_ERR_NO_MEMORY;
783 ctxt->instate = XML_PARSER_EOF;
784 ctxt->disableSAX = 1;
788 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
789 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
790 ctxt->myDoc->URL = xmlCanonicPath((const xmlChar *) ctxt->input->filename);
791 if (ctxt->myDoc->URL == NULL)
792 ctxt->myDoc->URL = xmlStrdup((const xmlChar *) ctxt->input->filename);
798 * @ctx: the user data (XML parser context)
800 * called when the document end has been detected.
803 endDocument(void *ctx)
805 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
807 xmlGenericError(xmlGenericErrorContext,
808 "SAX.endDocument()\n");
810 if (ctxt->validate && ctxt->wellFormed &&
811 ctxt->myDoc && ctxt->myDoc->intSubset)
812 ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
815 * Grab the encoding if it was added on-the-fly
817 if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
818 (ctxt->myDoc->encoding == NULL)) {
819 ctxt->myDoc->encoding = ctxt->encoding;
820 ctxt->encoding = NULL;
822 if ((ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
823 (ctxt->myDoc->encoding == NULL)) {
824 ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
826 if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
827 (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
828 ctxt->myDoc->charset = ctxt->charset;
834 * @ctx: the user data (XML parser context)
835 * @fullname: The attribute name, including namespace prefix
836 * @value: The attribute value
837 * @prefix: the prefix on the element node
839 * Handle an attribute that has been read by the parser.
840 * The default handling is to convert the attribute into an
841 * DOM subtree and past it in a new xmlAttr element added to
845 my_attribute(void *ctx, const xmlChar *fullname, const xmlChar *value,
846 const xmlChar *prefix)
848 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
857 xmlGenericError(xmlGenericErrorContext,
858 "SAX.attribute(%s, %s)\n", fullname, value);
862 * Split the full name into a namespace prefix and the tag name
864 name = xmlSplitQName(ctxt, fullname, &ns);
865 if ((name != NULL) && (name[0] == 0)) {
866 if (xmlStrEqual(ns, BAD_CAST "xmlns")) {
867 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
868 ctxt->sax->error(ctxt->userData,
869 "invalid namespace declaration '%s'\n", fullname);
871 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
872 ctxt->sax->warning(ctxt->userData,
873 "Avoid attribute ending with ':' like '%s'\n", fullname);
879 name = xmlStrdup(fullname);
882 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
883 ctxt->sax->error(ctxt->userData,
884 "SAX.startElement(): out of memory\n");
885 ctxt->errNo = XML_ERR_NO_MEMORY;
886 ctxt->instate = XML_PARSER_EOF;
887 ctxt->disableSAX = 1;
894 * Do the last stage of the attribute normalization
895 * Needed for HTML too:
896 * http://www.w3.org/TR/html4/types.html#h-6.2
898 ctxt->vctxt.valid = 1;
899 nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt,
900 ctxt->myDoc, ctxt->node,
902 if (ctxt->vctxt.valid != 1) {
909 * Check whether it's a namespace definition
911 if ((!ctxt->html) && (ns == NULL) &&
912 (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
913 (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
917 if (!ctxt->replaceEntities) {
919 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
923 val = (xmlChar *) value;
929 uri = xmlParseURI((const char *)val);
931 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
932 ctxt->sax->warning(ctxt->userData,
933 "nmlns: %s not a valid URI\n", val);
935 if (uri->scheme == NULL) {
936 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
937 ctxt->sax->warning(ctxt->userData,
938 "xmlns: URI %s is not absolute\n", val);
944 /* a default namespace definition */
945 nsret = xmlNewNs(ctxt->node, val, NULL);
948 * Validate also for namespace decls, they are attributes from
949 * an XML-1.0 perspective
951 if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
952 ctxt->myDoc && ctxt->myDoc->intSubset)
953 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
954 ctxt->node, prefix, nsret, val);
964 (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
965 (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
969 if (!ctxt->replaceEntities) {
971 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
975 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
976 ctxt->sax->error(ctxt->userData,
977 "SAX.startElement(): out of memory\n");
978 ctxt->errNo = XML_ERR_NO_MEMORY;
979 ctxt->instate = XML_PARSER_EOF;
980 ctxt->disableSAX = 1;
987 val = (xmlChar *) value;
991 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
992 ctxt->sax->error(ctxt->userData,
993 "Empty namespace name for prefix %s\n", name);
995 if ((ctxt->pedantic != 0) && (val[0] != 0)) {
998 uri = xmlParseURI((const char *)val);
1000 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
1001 ctxt->sax->warning(ctxt->userData,
1002 "xmlns:%s: %s not a valid URI\n", name, value);
1004 if (uri->scheme == NULL) {
1005 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
1006 ctxt->sax->warning(ctxt->userData,
1007 "xmlns:%s: URI %s is not absolute\n", name, value);
1013 /* a standard namespace definition */
1014 nsret = xmlNewNs(ctxt->node, val, name);
1017 * Validate also for namespace decls, they are attributes from
1018 * an XML-1.0 perspective
1020 if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
1021 ctxt->myDoc && ctxt->myDoc->intSubset)
1022 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
1023 ctxt->node, prefix, nsret, value);
1035 namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
1037 prop = ctxt->node->properties;
1038 while (prop != NULL) {
1039 if (prop->ns != NULL) {
1040 if ((xmlStrEqual(name, prop->name)) &&
1041 ((namespace == prop->ns) ||
1042 (xmlStrEqual(namespace->href, prop->ns->href)))) {
1043 ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
1044 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1045 ctxt->sax->error(ctxt->userData,
1046 "Attribute %s in %s redefined\n",
1047 name, namespace->href);
1048 ctxt->wellFormed = 0;
1049 if (ctxt->recovery == 0) ctxt->disableSAX = 1;
1059 /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
1060 ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL);
1063 if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
1066 ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
1067 tmp = ret->children;
1068 while (tmp != NULL) {
1069 tmp->parent = (xmlNodePtr) ret;
1070 if (tmp->next == NULL)
1074 } else if (value != NULL) {
1075 ret->children = xmlNewDocText(ctxt->myDoc, value);
1076 ret->last = ret->children;
1077 if (ret->children != NULL)
1078 ret->children->parent = (xmlNodePtr) ret;
1082 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
1083 ctxt->myDoc && ctxt->myDoc->intSubset) {
1086 * If we don't substitute entities, the validation should be
1087 * done on a value with replaced entities anyway.
1089 if (!ctxt->replaceEntities) {
1093 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
1098 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
1099 ctxt->myDoc, ctxt->node, ret, value);
1104 * Do the last stage of the attribute normalization
1105 * It need to be done twice ... it's an extra burden related
1106 * to the ability to keep references in attributes
1108 nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc,
1109 ctxt->node, fullname, val);
1110 if (nvalnorm != NULL) {
1115 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
1116 ctxt->myDoc, ctxt->node, ret, val);
1120 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
1121 ctxt->node, ret, value);
1123 } else if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
1124 (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
1125 ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {
1127 * when validating, the ID registration is done at the attribute
1128 * validation level. Otherwise we have to do specific handling here.
1130 if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
1131 xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
1132 else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
1133 xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
1145 * @ctx: the user data (XML parser context)
1146 * @fullname: The attribute name, including namespace prefix
1147 * @value: The attribute value
1149 * Handle an attribute that has been read by the parser.
1150 * The default handling is to convert the attribute into an
1151 * DOM subtree and past it in a new xmlAttr element added to
1155 attribute(void *ctx, const xmlChar *fullname, const xmlChar *value)
1157 my_attribute(ctx, fullname, value, NULL);
1161 * xmlCheckDefaultedAttributes:
1163 * Check defaulted attributes from the DTD
1166 xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name,
1167 const xmlChar *prefix, const xmlChar **atts) {
1168 xmlElementPtr elemDecl;
1173 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix);
1174 if (elemDecl == NULL) {
1175 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix);
1179 process_external_subset:
1181 if (elemDecl != NULL) {
1182 xmlAttributePtr attr = elemDecl->attributes;
1184 * Check against defaulted attributes from the external subset
1185 * if the document is stamped as standalone
1187 if ((ctxt->myDoc->standalone == 1) &&
1188 (ctxt->myDoc->extSubset != NULL) &&
1190 while (attr != NULL) {
1191 if ((attr->defaultValue != NULL) &&
1192 (xmlGetDtdQAttrDesc(ctxt->myDoc->extSubset,
1193 attr->elem, attr->name,
1194 attr->prefix) == attr) &&
1195 (xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
1196 attr->elem, attr->name,
1197 attr->prefix) == NULL)) {
1200 if (attr->prefix != NULL) {
1201 fulln = xmlStrdup(attr->prefix);
1202 fulln = xmlStrcat(fulln, BAD_CAST ":");
1203 fulln = xmlStrcat(fulln, attr->name);
1205 fulln = xmlStrdup(attr->name);
1209 * Check that the attribute is not declared in the
1216 while (att != NULL) {
1217 if (xmlStrEqual(att, fulln))
1224 if (ctxt->vctxt.error != NULL)
1225 ctxt->vctxt.error(ctxt->vctxt.userData,
1226 "standalone: attribute %s on %s defaulted from external subset\n",
1236 * Actually insert defaulted values when needed
1238 attr = elemDecl->attributes;
1239 while (attr != NULL) {
1241 * Make sure that attributes redefinition occuring in the
1242 * internal subset are not overriden by definitions in the
1245 if (attr->defaultValue != NULL) {
1247 * the element should be instantiated in the tree if:
1248 * - this is a namespace prefix
1249 * - the user required for completion in the tree
1251 * - there isn't already an attribute definition
1252 * in the internal subset overriding it.
1254 if (((attr->prefix != NULL) &&
1255 (xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) ||
1256 ((attr->prefix == NULL) &&
1257 (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) ||
1258 (ctxt->loadsubset & XML_COMPLETE_ATTRS)) {
1259 xmlAttributePtr tst;
1261 tst = xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
1262 attr->elem, attr->name,
1264 if ((tst == attr) || (tst == NULL)) {
1268 fulln = xmlBuildQName(attr->name, attr->prefix, fn, 50);
1269 if (fulln == NULL) {
1270 if ((ctxt->sax != NULL) &&
1271 (ctxt->sax->error != NULL))
1272 ctxt->sax->error(ctxt->userData,
1273 "SAX.startElement(): out of memory\n");
1274 ctxt->errNo = XML_ERR_NO_MEMORY;
1275 ctxt->instate = XML_PARSER_EOF;
1276 ctxt->disableSAX = 1;
1281 * Check that the attribute is not declared in the
1288 while (att != NULL) {
1289 if (xmlStrEqual(att, fulln))
1296 my_attribute(ctxt, fulln, attr->defaultValue,
1299 if ((fulln != fn) && (fulln != attr->name))
1306 if (internal == 1) {
1307 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset,
1310 goto process_external_subset;
1317 * @ctx: the user data (XML parser context)
1318 * @fullname: The element name, including namespace prefix
1319 * @atts: An array of name/value attributes pairs, NULL terminated
1321 * called when an opening tag has been processed.
1324 startElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
1326 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1328 xmlNodePtr parent = ctxt->node;
1333 const xmlChar *value;
1337 xmlGenericError(xmlGenericErrorContext,
1338 "SAX.startElement(%s)\n", fullname);
1342 * First check on validity:
1344 if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
1345 ((ctxt->myDoc->intSubset == NULL) ||
1346 ((ctxt->myDoc->intSubset->notations == NULL) &&
1347 (ctxt->myDoc->intSubset->elements == NULL) &&
1348 (ctxt->myDoc->intSubset->attributes == NULL) &&
1349 (ctxt->myDoc->intSubset->entities == NULL)))) {
1350 if (ctxt->vctxt.error != NULL) {
1351 ctxt->vctxt.error(ctxt->vctxt.userData,
1352 "Validation failed: no DTD found !\n");
1356 ctxt->errNo = XML_ERR_NO_DTD;
1361 * Split the full name into a namespace prefix and the tag name
1363 name = xmlSplitQName(ctxt, fullname, &prefix);
1367 * Note : the namespace resolution is deferred until the end of the
1368 * attributes parsing, since local namespace can be defined as
1369 * an attribute at this level.
1371 ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL);
1375 ctxt->errNo = XML_ERR_NO_MEMORY;
1376 ctxt->instate = XML_PARSER_EOF;
1377 ctxt->disableSAX = 1;
1380 if (ctxt->myDoc->children == NULL) {
1381 #ifdef DEBUG_SAX_TREE
1382 xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name);
1384 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1385 } else if (parent == NULL) {
1386 parent = ctxt->myDoc->children;
1389 if (ctxt->linenumbers) {
1390 if (ctxt->input != NULL)
1391 ret->content = (void *) (long) ctxt->input->line;
1395 * We are parsing a new node.
1397 #ifdef DEBUG_SAX_TREE
1398 xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name);
1400 nodePush(ctxt, ret);
1403 * Link the child element
1405 if (parent != NULL) {
1406 if (parent->type == XML_ELEMENT_NODE) {
1407 #ifdef DEBUG_SAX_TREE
1408 xmlGenericError(xmlGenericErrorContext,
1409 "adding child %s to %s\n", name, parent->name);
1411 xmlAddChild(parent, ret);
1413 #ifdef DEBUG_SAX_TREE
1414 xmlGenericError(xmlGenericErrorContext,
1415 "adding sibling %s to ", name);
1416 xmlDebugDumpOneNode(stderr, parent, 0);
1418 xmlAddSibling(parent, ret);
1423 * Insert all the defaulted attributes from the DTD especially namespaces
1425 if ((!ctxt->html) &&
1426 ((ctxt->myDoc->intSubset != NULL) ||
1427 (ctxt->myDoc->extSubset != NULL))) {
1428 xmlCheckDefaultedAttributes(ctxt, name, prefix, atts);
1432 * process all the attributes whose name start with "xmlns"
1439 while ((att != NULL) && (value != NULL)) {
1440 if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') &&
1441 (att[3] == 'n') && (att[4] == 's'))
1442 my_attribute(ctxt, att, value, prefix);
1451 * Search the namespace, note that since the attributes have been
1452 * processed, the local namespaces are available.
1454 ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
1455 if ((ns == NULL) && (parent != NULL))
1456 ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
1457 if ((prefix != NULL) && (ns == NULL)) {
1458 ns = xmlNewNs(ret, NULL, prefix);
1459 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
1460 ctxt->sax->warning(ctxt->userData,
1461 "Namespace prefix %s is not defined\n", prefix);
1465 * set the namespace node, making sure that if the default namspace
1466 * is unbound on a parent we simply kee it NULL
1468 if ((ns != NULL) && (ns->href != NULL) &&
1469 ((ns->href[0] != 0) || (ns->prefix != NULL)))
1473 * process all the other attributes
1480 while (att != NULL) {
1481 attribute(ctxt, att, value);
1486 while ((att != NULL) && (value != NULL)) {
1487 if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l') ||
1488 (att[3] != 'n') || (att[4] != 's'))
1489 attribute(ctxt, att, value);
1501 * If it's the Document root, finish the DTD validation and
1502 * check the document root element for validity
1504 if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) {
1507 chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
1511 ctxt->wellFormed = 0;
1512 ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
1513 ctxt->vctxt.finishDtd = 1;
1523 * @ctx: the user data (XML parser context)
1524 * @name: The element name
1526 * called when the end of an element has been detected.
1529 endElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
1531 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1532 xmlParserNodeInfo node_info;
1533 xmlNodePtr cur = ctxt->node;
1537 xmlGenericError(xmlGenericErrorContext, "SAX.endElement(NULL)\n");
1539 xmlGenericError(xmlGenericErrorContext, "SAX.endElement(%s)\n", name);
1542 /* Capture end position and add node */
1543 if (cur != NULL && ctxt->record_info) {
1544 node_info.end_pos = ctxt->input->cur - ctxt->input->base;
1545 node_info.end_line = ctxt->input->line;
1546 node_info.node = cur;
1547 xmlParserAddNodeInfo(ctxt, &node_info);
1551 if (ctxt->validate && ctxt->wellFormed &&
1552 ctxt->myDoc && ctxt->myDoc->intSubset)
1553 ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
1558 * end of parsing of this node.
1560 #ifdef DEBUG_SAX_TREE
1561 xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name);
1568 * @ctx: the user data (XML parser context)
1569 * @name: The entity name
1571 * called when an entity reference is detected.
1574 reference(void *ctx, const xmlChar *name)
1576 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1580 xmlGenericError(xmlGenericErrorContext,
1581 "SAX.reference(%s)\n", name);
1584 ret = xmlNewCharRef(ctxt->myDoc, name);
1586 ret = xmlNewReference(ctxt->myDoc, name);
1587 #ifdef DEBUG_SAX_TREE
1588 xmlGenericError(xmlGenericErrorContext,
1589 "add reference %s to %s \n", name, ctxt->node->name);
1591 xmlAddChild(ctxt->node, ret);
1596 * @ctx: the user data (XML parser context)
1597 * @ch: a xmlChar string
1598 * @len: the number of xmlChar
1600 * receiving some chars from the parser.
1603 characters(void *ctx, const xmlChar *ch, int len)
1605 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1606 xmlNodePtr lastChild;
1609 xmlGenericError(xmlGenericErrorContext,
1610 "SAX.characters(%.30s, %d)\n", ch, len);
1613 * Handle the data if any. If there is no child
1614 * add it as content, otherwise if the last child is text,
1615 * concatenate it, else create a new node of type text.
1618 if (ctxt->node == NULL) {
1619 #ifdef DEBUG_SAX_TREE
1620 xmlGenericError(xmlGenericErrorContext,
1621 "add chars: ctxt->node == NULL !\n");
1625 lastChild = xmlGetLastChild(ctxt->node);
1626 #ifdef DEBUG_SAX_TREE
1627 xmlGenericError(xmlGenericErrorContext,
1628 "add chars to %s \n", ctxt->node->name);
1632 * Here we needed an accelerator mechanism in case of very large
1633 * elements. Use an attribute in the structure !!!
1635 if (lastChild == NULL) {
1636 /* first node, first time */
1637 xmlNodeAddContentLen(ctxt->node, ch, len);
1638 if (ctxt->node->children != NULL) {
1639 ctxt->nodelen = len;
1640 ctxt->nodemem = len + 1;
1643 int coalesceText = (lastChild != NULL) &&
1644 (lastChild->type == XML_TEXT_NODE) &&
1645 (lastChild->name == xmlStringText);
1646 if ((coalesceText) && (ctxt->nodemem != 0)) {
1648 * The whole point of maintaining nodelen and nodemem,
1649 * xmlTextConcat is too costly, i.e. compute length,
1650 * reallocate a new buffer, move data, append ch. Here
1651 * We try to minimaze realloc() uses and avoid copying
1652 * and recomputing length over and over.
1654 if (ctxt->nodelen + len >= ctxt->nodemem) {
1658 size = ctxt->nodemem + len;
1660 newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
1661 if (newbuf == NULL) {
1662 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1663 ctxt->sax->error(ctxt->userData,
1664 "SAX.characters(): out of memory\n");
1665 ctxt->errNo = XML_ERR_NO_MEMORY;
1666 ctxt->instate = XML_PARSER_EOF;
1667 ctxt->disableSAX = 1;
1670 ctxt->nodemem = size;
1671 lastChild->content = newbuf;
1673 memcpy(&lastChild->content[ctxt->nodelen], ch, len);
1674 ctxt->nodelen += len;
1675 lastChild->content[ctxt->nodelen] = 0;
1676 } else if (coalesceText) {
1677 if (xmlTextConcat(lastChild, ch, len)) {
1678 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1679 ctxt->sax->error(ctxt->userData,
1680 "SAX.characters(): out of memory\n");
1681 ctxt->errNo = XML_ERR_NO_MEMORY;
1682 ctxt->instate = XML_PARSER_EOF;
1683 ctxt->disableSAX = 1;
1685 if (ctxt->node->children != NULL) {
1686 ctxt->nodelen = xmlStrlen(lastChild->content);
1687 ctxt->nodemem = ctxt->nodelen + 1;
1690 /* Mixed content, first time */
1691 lastChild = xmlNewTextLen(ch, len);
1692 if (lastChild == NULL) {
1693 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1694 ctxt->sax->error(ctxt->userData,
1695 "SAX.characters(): out of memory\n");
1696 ctxt->errNo = XML_ERR_NO_MEMORY;
1697 ctxt->instate = XML_PARSER_EOF;
1698 ctxt->disableSAX = 1;
1700 xmlAddChild(ctxt->node, lastChild);
1701 if (ctxt->node->children != NULL) {
1702 ctxt->nodelen = len;
1703 ctxt->nodemem = len + 1;
1711 * ignorableWhitespace:
1712 * @ctx: the user data (XML parser context)
1713 * @ch: a xmlChar string
1714 * @len: the number of xmlChar
1716 * receiving some ignorable whitespaces from the parser.
1717 * UNUSED: by default the DOM building will use characters
1720 ignorableWhitespace(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED)
1722 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1724 xmlGenericError(xmlGenericErrorContext,
1725 "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
1730 * processingInstruction:
1731 * @ctx: the user data (XML parser context)
1732 * @target: the target name
1733 * @data: the PI data's
1735 * A processing instruction has been parsed.
1738 processingInstruction(void *ctx, const xmlChar *target,
1739 const xmlChar *data)
1741 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1743 xmlNodePtr parent = ctxt->node;
1746 xmlGenericError(xmlGenericErrorContext,
1747 "SAX.processingInstruction(%s, %s)\n", target, data);
1750 ret = xmlNewPI(target, data);
1751 if (ret == NULL) return;
1752 parent = ctxt->node;
1754 if (ctxt->inSubset == 1) {
1755 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
1757 } else if (ctxt->inSubset == 2) {
1758 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
1761 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
1762 #ifdef DEBUG_SAX_TREE
1763 xmlGenericError(xmlGenericErrorContext,
1764 "Setting PI %s as root\n", target);
1766 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1769 if (parent->type == XML_ELEMENT_NODE) {
1770 #ifdef DEBUG_SAX_TREE
1771 xmlGenericError(xmlGenericErrorContext,
1772 "adding PI %s child to %s\n", target, parent->name);
1774 xmlAddChild(parent, ret);
1776 #ifdef DEBUG_SAX_TREE
1777 xmlGenericError(xmlGenericErrorContext,
1778 "adding PI %s sibling to ", target);
1779 xmlDebugDumpOneNode(stderr, parent, 0);
1781 xmlAddSibling(parent, ret);
1787 * @ctx: the user data (XML parser context)
1788 * @href: the namespace associated URN
1789 * @prefix: the namespace prefix
1791 * An old global namespace has been parsed.
1794 globalNamespace(void *ctx, const xmlChar *href, const xmlChar *prefix)
1796 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1798 xmlGenericError(xmlGenericErrorContext,
1799 "SAX.globalNamespace(%s, %s)\n", href, prefix);
1801 xmlNewGlobalNs(ctxt->myDoc, href, prefix);
1806 * @ctx: the user data (XML parser context)
1807 * @name: the namespace prefix
1809 * Set the current element namespace.
1813 setNamespace(void *ctx, const xmlChar *name)
1815 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1820 xmlGenericError(xmlGenericErrorContext, "SAX.setNamespace(%s)\n", name);
1822 ns = xmlSearchNs(ctxt->myDoc, ctxt->node, name);
1823 if (ns == NULL) { /* ctxt->node may not have a parent yet ! */
1824 if (ctxt->nodeNr >= 2) {
1825 parent = ctxt->nodeTab[ctxt->nodeNr - 2];
1827 ns = xmlSearchNs(ctxt->myDoc, parent, name);
1830 xmlSetNs(ctxt->node, ns);
1835 * @ctx: the user data (XML parser context)
1837 * Get the current element namespace.
1839 * Returns the xmlNsPtr or NULL if none
1843 getNamespace(void *ctx)
1845 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1849 xmlGenericError(xmlGenericErrorContext, "SAX.getNamespace()\n");
1851 ret = ctxt->node->ns;
1857 * @ctx: the user data (XML parser context)
1858 * @namespace: the namespace to check against
1860 * Check that the current element namespace is the same as the
1861 * one read upon parsing.
1863 * Returns 1 if true 0 otherwise
1867 checkNamespace(void *ctx, xmlChar *namespace)
1869 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1870 xmlNodePtr cur = ctxt->node;
1873 xmlGenericError(xmlGenericErrorContext,
1874 "SAX.checkNamespace(%s)\n", namespace);
1878 * Check that the Name in the ETag is the same as in the STag.
1880 if (namespace == NULL) {
1881 if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
1882 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1883 ctxt->sax->error(ctxt,
1884 "End tags for %s don't hold the namespace %s\n",
1885 cur->name, cur->ns->prefix);
1886 ctxt->wellFormed = 0;
1889 if ((cur->ns == NULL) || (cur->ns->prefix == NULL)) {
1890 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1891 ctxt->sax->error(ctxt,
1892 "End tags %s holds a prefix %s not used by the open tag\n",
1893 cur->name, namespace);
1894 ctxt->wellFormed = 0;
1895 } else if (!xmlStrEqual(namespace, cur->ns->prefix)) {
1896 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
1897 ctxt->sax->error(ctxt,
1898 "Start and End tags for %s don't use the same namespaces: %s and %s\n",
1899 cur->name, cur->ns->prefix, namespace);
1900 ctxt->wellFormed = 0;
1909 * @ctx: the user data (XML parser context)
1910 * @href: the namespace associated URN
1911 * @prefix: the namespace prefix
1913 * A namespace has been parsed.
1916 namespaceDecl(void *ctx, const xmlChar *href, const xmlChar *prefix)
1918 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1921 xmlGenericError(xmlGenericErrorContext,
1922 "SAX.namespaceDecl(%s, NULL)\n", href);
1924 xmlGenericError(xmlGenericErrorContext,
1925 "SAX.namespaceDecl(%s, %s)\n", href, prefix);
1927 xmlNewNs(ctxt->node, href, prefix);
1932 * @ctx: the user data (XML parser context)
1933 * @value: the comment content
1935 * A comment has been parsed.
1938 comment(void *ctx, const xmlChar *value)
1940 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1942 xmlNodePtr parent = ctxt->node;
1945 xmlGenericError(xmlGenericErrorContext, "SAX.comment(%s)\n", value);
1947 ret = xmlNewDocComment(ctxt->myDoc, value);
1948 if (ret == NULL) return;
1950 if (ctxt->inSubset == 1) {
1951 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
1953 } else if (ctxt->inSubset == 2) {
1954 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
1957 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
1958 #ifdef DEBUG_SAX_TREE
1959 xmlGenericError(xmlGenericErrorContext,
1960 "Setting comment as root\n");
1962 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1965 if (parent->type == XML_ELEMENT_NODE) {
1966 #ifdef DEBUG_SAX_TREE
1967 xmlGenericError(xmlGenericErrorContext,
1968 "adding comment child to %s\n", parent->name);
1970 xmlAddChild(parent, ret);
1972 #ifdef DEBUG_SAX_TREE
1973 xmlGenericError(xmlGenericErrorContext,
1974 "adding comment sibling to ");
1975 xmlDebugDumpOneNode(stderr, parent, 0);
1977 xmlAddSibling(parent, ret);
1983 * @ctx: the user data (XML parser context)
1984 * @value: The pcdata content
1985 * @len: the block length
1987 * called when a pcdata block has been parsed
1990 cdataBlock(void *ctx, const xmlChar *value, int len)
1992 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1993 xmlNodePtr ret, lastChild;
1996 xmlGenericError(xmlGenericErrorContext,
1997 "SAX.pcdata(%.10s, %d)\n", value, len);
1999 lastChild = xmlGetLastChild(ctxt->node);
2000 #ifdef DEBUG_SAX_TREE
2001 xmlGenericError(xmlGenericErrorContext,
2002 "add chars to %s \n", ctxt->node->name);
2004 if ((lastChild != NULL) &&
2005 (lastChild->type == XML_CDATA_SECTION_NODE)) {
2006 xmlTextConcat(lastChild, value, len);
2008 ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
2009 xmlAddChild(ctxt->node, ret);
2014 * initxmlDefaultSAXHandler:
2015 * @hdlr: the SAX handler
2016 * @warning: flag if non-zero sets the handler warning procedure
2018 * Initialize the default XML SAX handler
2021 initxmlDefaultSAXHandler(xmlSAXHandler *hdlr, int warning)
2023 if(hdlr->initialized == 1)
2026 hdlr->internalSubset = internalSubset;
2027 hdlr->externalSubset = externalSubset;
2028 hdlr->isStandalone = isStandalone;
2029 hdlr->hasInternalSubset = hasInternalSubset;
2030 hdlr->hasExternalSubset = hasExternalSubset;
2031 hdlr->resolveEntity = resolveEntity;
2032 hdlr->getEntity = getEntity;
2033 hdlr->getParameterEntity = getParameterEntity;
2034 hdlr->entityDecl = entityDecl;
2035 hdlr->attributeDecl = attributeDecl;
2036 hdlr->elementDecl = elementDecl;
2037 hdlr->notationDecl = notationDecl;
2038 hdlr->unparsedEntityDecl = unparsedEntityDecl;
2039 hdlr->setDocumentLocator = setDocumentLocator;
2040 hdlr->startDocument = startDocument;
2041 hdlr->endDocument = endDocument;
2042 hdlr->startElement = startElement;
2043 hdlr->endElement = endElement;
2044 hdlr->reference = reference;
2045 hdlr->characters = characters;
2046 hdlr->cdataBlock = cdataBlock;
2047 hdlr->ignorableWhitespace = characters;
2048 hdlr->processingInstruction = processingInstruction;
2049 hdlr->comment = comment;
2050 /* if (xmlGetWarningsDefaultValue == 0) */
2052 hdlr->warning = NULL;
2054 hdlr->warning = xmlParserWarning;
2055 hdlr->error = xmlParserError;
2056 hdlr->fatalError = xmlParserError;
2058 hdlr->initialized = 1;
2062 * xmlDefaultSAXHandlerInit:
2064 * Initialize the default SAX handler
2067 xmlDefaultSAXHandlerInit(void)
2069 initxmlDefaultSAXHandler(&xmlDefaultSAXHandler, xmlGetWarningsDefaultValue);
2072 #ifdef LIBXML_HTML_ENABLED
2075 * inithtmlDefaultSAXHandler:
2076 * @hdlr: the SAX handler
2078 * Initialize the default HTML SAX handler
2081 inithtmlDefaultSAXHandler(xmlSAXHandler *hdlr)
2083 if(hdlr->initialized == 1)
2086 hdlr->internalSubset = internalSubset;
2087 hdlr->externalSubset = NULL;
2088 hdlr->isStandalone = NULL;
2089 hdlr->hasInternalSubset = NULL;
2090 hdlr->hasExternalSubset = NULL;
2091 hdlr->resolveEntity = NULL;
2092 hdlr->getEntity = getEntity;
2093 hdlr->getParameterEntity = NULL;
2094 hdlr->entityDecl = NULL;
2095 hdlr->attributeDecl = NULL;
2096 hdlr->elementDecl = NULL;
2097 hdlr->notationDecl = NULL;
2098 hdlr->unparsedEntityDecl = NULL;
2099 hdlr->setDocumentLocator = setDocumentLocator;
2100 hdlr->startDocument = startDocument;
2101 hdlr->endDocument = endDocument;
2102 hdlr->startElement = startElement;
2103 hdlr->endElement = endElement;
2104 hdlr->reference = NULL;
2105 hdlr->characters = characters;
2106 hdlr->cdataBlock = cdataBlock;
2107 hdlr->ignorableWhitespace = ignorableWhitespace;
2108 hdlr->processingInstruction = NULL;
2109 hdlr->comment = comment;
2110 hdlr->warning = xmlParserWarning;
2111 hdlr->error = xmlParserError;
2112 hdlr->fatalError = xmlParserError;
2114 hdlr->initialized = 1;
2118 * htmlDefaultSAXHandlerInit:
2120 * Initialize the default SAX handler
2123 htmlDefaultSAXHandlerInit(void)
2125 inithtmlDefaultSAXHandler(&htmlDefaultSAXHandler);
2128 #endif /* LIBXML_HTML_ENABLED */
2130 #ifdef LIBXML_DOCB_ENABLED
2133 * initdocbDefaultSAXHandler:
2134 * @hdlr: the SAX handler
2136 * Initialize the default DocBook SAX handler
2139 initdocbDefaultSAXHandler(xmlSAXHandler *hdlr)
2141 if(hdlr->initialized == 1)
2144 hdlr->internalSubset = internalSubset;
2145 hdlr->externalSubset = NULL;
2146 hdlr->isStandalone = isStandalone;
2147 hdlr->hasInternalSubset = hasInternalSubset;
2148 hdlr->hasExternalSubset = hasExternalSubset;
2149 hdlr->resolveEntity = resolveEntity;
2150 hdlr->getEntity = getEntity;
2151 hdlr->getParameterEntity = NULL;
2152 hdlr->entityDecl = entityDecl;
2153 hdlr->attributeDecl = NULL;
2154 hdlr->elementDecl = NULL;
2155 hdlr->notationDecl = NULL;
2156 hdlr->unparsedEntityDecl = NULL;
2157 hdlr->setDocumentLocator = setDocumentLocator;
2158 hdlr->startDocument = startDocument;
2159 hdlr->endDocument = endDocument;
2160 hdlr->startElement = startElement;
2161 hdlr->endElement = endElement;
2162 hdlr->reference = reference;
2163 hdlr->characters = characters;
2164 hdlr->cdataBlock = NULL;
2165 hdlr->ignorableWhitespace = ignorableWhitespace;
2166 hdlr->processingInstruction = NULL;
2167 hdlr->comment = comment;
2168 hdlr->warning = xmlParserWarning;
2169 hdlr->error = xmlParserError;
2170 hdlr->fatalError = xmlParserError;
2172 hdlr->initialized = 1;
2176 * docbDefaultSAXHandlerInit:
2178 * Initialize the default SAX handler
2181 docbDefaultSAXHandlerInit(void)
2183 initdocbDefaultSAXHandler(&docbDefaultSAXHandler);
2186 #endif /* LIBXML_DOCB_ENABLED */