dmband: Download segment tracks if performance auto-download is set.
[wine.git] / libs / xml2 / SAX2.c
blobb6be1a6c488a21562fda2a532e982b45457e883c
1 /*
2 * SAX2.c : Default SAX2 handler to build a tree.
4 * See Copyright for the status of this software.
6 * Daniel Veillard <daniel@veillard.com>
7 */
10 #define IN_LIBXML
11 #include "libxml.h"
12 #include <stdlib.h>
13 #include <string.h>
14 #include <limits.h>
15 #include <stddef.h>
16 #include <libxml/xmlmemory.h>
17 #include <libxml/tree.h>
18 #include <libxml/parser.h>
19 #include <libxml/parserInternals.h>
20 #include <libxml/valid.h>
21 #include <libxml/entities.h>
22 #include <libxml/xmlerror.h>
23 #include <libxml/debugXML.h>
24 #include <libxml/xmlIO.h>
25 #include <libxml/SAX.h>
26 #include <libxml/uri.h>
27 #include <libxml/valid.h>
28 #include <libxml/HTMLtree.h>
29 #include <libxml/globals.h>
31 #include "private/error.h"
32 #include "private/parser.h"
33 #include "private/tree.h"
35 /* #define DEBUG_SAX2 */
36 /* #define DEBUG_SAX2_TREE */
38 /**
39 * TODO:
41 * macro to flag unimplemented blocks
42 * XML_CATALOG_PREFER user env to select between system/public preferred
43 * option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk>
44 *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with
45 *> values "system" and "public". I have made the default be "system" to
46 *> match yours.
48 #define TODO \
49 xmlGenericError(xmlGenericErrorContext, \
50 "Unimplemented block at %s:%d\n", \
51 __FILE__, __LINE__);
54 * xmlSAX2ErrMemory:
55 * @ctxt: an XML validation parser context
56 * @msg: a string to accompany the error message
58 static void LIBXML_ATTR_FORMAT(2,0)
59 xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) {
60 xmlStructuredErrorFunc schannel = NULL;
61 const char *str1 = "out of memory\n";
63 if (ctxt != NULL) {
64 ctxt->errNo = XML_ERR_NO_MEMORY;
65 if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
66 schannel = ctxt->sax->serror;
67 __xmlRaiseError(schannel,
68 ctxt->vctxt.error, ctxt->vctxt.userData,
69 ctxt, NULL, XML_FROM_PARSER, XML_ERR_NO_MEMORY,
70 XML_ERR_ERROR, NULL, 0, (const char *) str1,
71 NULL, NULL, 0, 0,
72 msg, (const char *) str1, NULL);
73 ctxt->errNo = XML_ERR_NO_MEMORY;
74 ctxt->instate = XML_PARSER_EOF;
75 ctxt->disableSAX = 1;
76 } else {
77 __xmlRaiseError(schannel,
78 NULL, NULL,
79 ctxt, NULL, XML_FROM_PARSER, XML_ERR_NO_MEMORY,
80 XML_ERR_ERROR, NULL, 0, (const char *) str1,
81 NULL, NULL, 0, 0,
82 msg, (const char *) str1, NULL);
86 /**
87 * xmlValidError:
88 * @ctxt: an XML validation parser context
89 * @error: the error number
90 * @msg: the error message
91 * @str1: extra data
92 * @str2: extra data
94 * Handle a validation error
96 static void LIBXML_ATTR_FORMAT(3,0)
97 xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error,
98 const char *msg, const char *str1, const char *str2)
100 xmlStructuredErrorFunc schannel = NULL;
102 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
103 (ctxt->instate == XML_PARSER_EOF))
104 return;
105 if (ctxt != NULL) {
106 ctxt->errNo = error;
107 if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
108 schannel = ctxt->sax->serror;
109 __xmlRaiseError(schannel,
110 ctxt->vctxt.error, ctxt->vctxt.userData,
111 ctxt, NULL, XML_FROM_DTD, error,
112 XML_ERR_ERROR, NULL, 0, (const char *) str1,
113 (const char *) str2, NULL, 0, 0,
114 msg, (const char *) str1, (const char *) str2);
115 ctxt->valid = 0;
116 } else {
117 __xmlRaiseError(schannel,
118 NULL, NULL,
119 ctxt, NULL, XML_FROM_DTD, error,
120 XML_ERR_ERROR, NULL, 0, (const char *) str1,
121 (const char *) str2, NULL, 0, 0,
122 msg, (const char *) str1, (const char *) str2);
127 * xmlFatalErrMsg:
128 * @ctxt: an XML parser context
129 * @error: the error number
130 * @msg: the error message
131 * @str1: an error string
132 * @str2: an error string
134 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
136 static void LIBXML_ATTR_FORMAT(3,0)
137 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
138 const char *msg, const xmlChar *str1, const xmlChar *str2)
140 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
141 (ctxt->instate == XML_PARSER_EOF))
142 return;
143 if (ctxt != NULL)
144 ctxt->errNo = error;
145 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
146 XML_ERR_FATAL, NULL, 0,
147 (const char *) str1, (const char *) str2,
148 NULL, 0, 0, msg, str1, str2);
149 if (ctxt != NULL) {
150 ctxt->wellFormed = 0;
151 ctxt->valid = 0;
152 if (ctxt->recovery == 0)
153 ctxt->disableSAX = 1;
158 * xmlWarnMsg:
159 * @ctxt: an XML parser context
160 * @error: the error number
161 * @msg: the error message
162 * @str1: an error string
163 * @str2: an error string
165 * Handle a parser warning
167 static void LIBXML_ATTR_FORMAT(3,0)
168 xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
169 const char *msg, const xmlChar *str1)
171 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
172 (ctxt->instate == XML_PARSER_EOF))
173 return;
174 if (ctxt != NULL)
175 ctxt->errNo = error;
176 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
177 XML_ERR_WARNING, NULL, 0,
178 (const char *) str1, NULL,
179 NULL, 0, 0, msg, str1);
183 * xmlNsWarnMsg:
184 * @ctxt: an XML parser context
185 * @error: the error number
186 * @msg: the error message
187 * @str1: an error string
189 * Handle a namespace warning
191 static void LIBXML_ATTR_FORMAT(3,0)
192 xmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
193 const char *msg, const xmlChar *str1, const xmlChar *str2)
195 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
196 (ctxt->instate == XML_PARSER_EOF))
197 return;
198 if (ctxt != NULL)
199 ctxt->errNo = error;
200 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
201 XML_ERR_WARNING, NULL, 0,
202 (const char *) str1, (const char *) str2,
203 NULL, 0, 0, msg, str1, str2);
207 * xmlSAX2GetPublicId:
208 * @ctx: the user data (XML parser context)
210 * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
212 * Returns a xmlChar *
214 const xmlChar *
215 xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED)
217 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
218 return(NULL);
222 * xmlSAX2GetSystemId:
223 * @ctx: the user data (XML parser context)
225 * Provides the system ID, basically URL or filename e.g.
226 * http://www.sgmlsource.com/dtds/memo.dtd
228 * Returns a xmlChar *
230 const xmlChar *
231 xmlSAX2GetSystemId(void *ctx)
233 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
234 if ((ctx == NULL) || (ctxt->input == NULL)) return(NULL);
235 return((const xmlChar *) ctxt->input->filename);
239 * xmlSAX2GetLineNumber:
240 * @ctx: the user data (XML parser context)
242 * Provide the line number of the current parsing point.
244 * Returns an int
247 xmlSAX2GetLineNumber(void *ctx)
249 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
250 if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
251 return(ctxt->input->line);
255 * xmlSAX2GetColumnNumber:
256 * @ctx: the user data (XML parser context)
258 * Provide the column number of the current parsing point.
260 * Returns an int
263 xmlSAX2GetColumnNumber(void *ctx)
265 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
266 if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
267 return(ctxt->input->col);
271 * xmlSAX2IsStandalone:
272 * @ctx: the user data (XML parser context)
274 * Is this document tagged standalone ?
276 * Returns 1 if true
279 xmlSAX2IsStandalone(void *ctx)
281 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
282 if ((ctx == NULL) || (ctxt->myDoc == NULL)) return(0);
283 return(ctxt->myDoc->standalone == 1);
287 * xmlSAX2HasInternalSubset:
288 * @ctx: the user data (XML parser context)
290 * Does this document has an internal subset
292 * Returns 1 if true
295 xmlSAX2HasInternalSubset(void *ctx)
297 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
298 if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0);
299 return(ctxt->myDoc->intSubset != NULL);
303 * xmlSAX2HasExternalSubset:
304 * @ctx: the user data (XML parser context)
306 * Does this document has an external subset
308 * Returns 1 if true
311 xmlSAX2HasExternalSubset(void *ctx)
313 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
314 if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0);
315 return(ctxt->myDoc->extSubset != NULL);
319 * xmlSAX2InternalSubset:
320 * @ctx: the user data (XML parser context)
321 * @name: the root element name
322 * @ExternalID: the external ID
323 * @SystemID: the SYSTEM ID (e.g. filename or URL)
325 * Callback on internal subset declaration.
327 void
328 xmlSAX2InternalSubset(void *ctx, const xmlChar *name,
329 const xmlChar *ExternalID, const xmlChar *SystemID)
331 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
332 xmlDtdPtr dtd;
333 if (ctx == NULL) return;
334 #ifdef DEBUG_SAX
335 xmlGenericError(xmlGenericErrorContext,
336 "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n",
337 name, ExternalID, SystemID);
338 #endif
340 if (ctxt->myDoc == NULL)
341 return;
342 dtd = xmlGetIntSubset(ctxt->myDoc);
343 if (dtd != NULL) {
344 if (ctxt->html)
345 return;
346 xmlUnlinkNode((xmlNodePtr) dtd);
347 xmlFreeDtd(dtd);
348 ctxt->myDoc->intSubset = NULL;
350 ctxt->myDoc->intSubset =
351 xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
352 if (ctxt->myDoc->intSubset == NULL)
353 xmlSAX2ErrMemory(ctxt, "xmlSAX2InternalSubset");
357 * xmlSAX2ExternalSubset:
358 * @ctx: the user data (XML parser context)
359 * @name: the root element name
360 * @ExternalID: the external ID
361 * @SystemID: the SYSTEM ID (e.g. filename or URL)
363 * Callback on external subset declaration.
365 void
366 xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
367 const xmlChar *ExternalID, const xmlChar *SystemID)
369 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
370 if (ctx == NULL) return;
371 #ifdef DEBUG_SAX
372 xmlGenericError(xmlGenericErrorContext,
373 "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n",
374 name, ExternalID, SystemID);
375 #endif
376 if (((ExternalID != NULL) || (SystemID != NULL)) &&
377 (((ctxt->validate) || (ctxt->loadsubset != 0)) &&
378 (ctxt->wellFormed && ctxt->myDoc))) {
380 * Try to fetch and parse the external subset.
382 xmlParserInputPtr oldinput;
383 int oldinputNr;
384 int oldinputMax;
385 xmlParserInputPtr *oldinputTab;
386 xmlParserInputPtr input = NULL;
387 xmlCharEncoding enc;
388 int oldcharset;
389 const xmlChar *oldencoding;
390 int oldprogressive;
391 unsigned long consumed;
392 size_t buffered;
395 * Ask the Entity resolver to load the damn thing
397 if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
398 input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
399 SystemID);
400 if (input == NULL) {
401 return;
404 xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
407 * make sure we won't destroy the main document context
409 oldinput = ctxt->input;
410 oldinputNr = ctxt->inputNr;
411 oldinputMax = ctxt->inputMax;
412 oldinputTab = ctxt->inputTab;
413 oldcharset = ctxt->charset;
414 oldencoding = ctxt->encoding;
415 oldprogressive = ctxt->progressive;
416 ctxt->encoding = NULL;
417 ctxt->progressive = 0;
419 ctxt->inputTab = (xmlParserInputPtr *)
420 xmlMalloc(5 * sizeof(xmlParserInputPtr));
421 if (ctxt->inputTab == NULL) {
422 xmlSAX2ErrMemory(ctxt, "xmlSAX2ExternalSubset");
423 xmlFreeInputStream(input);
424 ctxt->input = oldinput;
425 ctxt->inputNr = oldinputNr;
426 ctxt->inputMax = oldinputMax;
427 ctxt->inputTab = oldinputTab;
428 ctxt->charset = oldcharset;
429 ctxt->encoding = oldencoding;
430 ctxt->progressive = oldprogressive;
431 return;
433 ctxt->inputNr = 0;
434 ctxt->inputMax = 5;
435 ctxt->input = NULL;
436 xmlPushInput(ctxt, input);
439 * On the fly encoding conversion if needed
441 if (ctxt->input->length >= 4) {
442 enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
443 xmlSwitchEncoding(ctxt, enc);
446 if (input->filename == NULL)
447 input->filename = (char *) xmlCanonicPath(SystemID);
448 input->line = 1;
449 input->col = 1;
450 input->base = ctxt->input->cur;
451 input->cur = ctxt->input->cur;
452 input->free = NULL;
455 * let's parse that entity knowing it's an external subset.
457 xmlParseExternalSubset(ctxt, ExternalID, SystemID);
460 * Free up the external entities
463 while (ctxt->inputNr > 1)
464 xmlPopInput(ctxt);
466 consumed = ctxt->input->consumed;
467 buffered = ctxt->input->cur - ctxt->input->base;
468 if (buffered > ULONG_MAX - consumed)
469 consumed = ULONG_MAX;
470 else
471 consumed += buffered;
472 if (consumed > ULONG_MAX - ctxt->sizeentities)
473 ctxt->sizeentities = ULONG_MAX;
474 else
475 ctxt->sizeentities += consumed;
477 xmlFreeInputStream(ctxt->input);
478 xmlFree(ctxt->inputTab);
481 * Restore the parsing context of the main entity
483 ctxt->input = oldinput;
484 ctxt->inputNr = oldinputNr;
485 ctxt->inputMax = oldinputMax;
486 ctxt->inputTab = oldinputTab;
487 ctxt->charset = oldcharset;
488 if ((ctxt->encoding != NULL) &&
489 ((ctxt->dict == NULL) ||
490 (!xmlDictOwns(ctxt->dict, ctxt->encoding))))
491 xmlFree((xmlChar *) ctxt->encoding);
492 ctxt->encoding = oldencoding;
493 ctxt->progressive = oldprogressive;
494 /* ctxt->wellFormed = oldwellFormed; */
499 * xmlSAX2ResolveEntity:
500 * @ctx: the user data (XML parser context)
501 * @publicId: The public ID of the entity
502 * @systemId: The system ID of the entity
504 * The entity loader, to control the loading of external entities,
505 * the application can either:
506 * - override this xmlSAX2ResolveEntity() callback in the SAX block
507 * - or better use the xmlSetExternalEntityLoader() function to
508 * set up it's own entity resolution routine
510 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
512 xmlParserInputPtr
513 xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
515 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
516 xmlParserInputPtr ret;
517 xmlChar *URI;
518 const char *base = NULL;
520 if (ctx == NULL) return(NULL);
521 if (ctxt->input != NULL)
522 base = ctxt->input->filename;
523 if (base == NULL)
524 base = ctxt->directory;
526 URI = xmlBuildURI(systemId, (const xmlChar *) base);
528 #ifdef DEBUG_SAX
529 xmlGenericError(xmlGenericErrorContext,
530 "SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId, systemId);
531 #endif
533 ret = xmlLoadExternalEntity((const char *) URI,
534 (const char *) publicId, ctxt);
535 if (URI != NULL)
536 xmlFree(URI);
537 return(ret);
541 * xmlSAX2GetEntity:
542 * @ctx: the user data (XML parser context)
543 * @name: The entity name
545 * Get an entity by name
547 * Returns the xmlEntityPtr if found.
549 xmlEntityPtr
550 xmlSAX2GetEntity(void *ctx, const xmlChar *name)
552 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
553 xmlEntityPtr ret = NULL;
555 if (ctx == NULL) return(NULL);
556 #ifdef DEBUG_SAX
557 xmlGenericError(xmlGenericErrorContext,
558 "SAX.xmlSAX2GetEntity(%s)\n", name);
559 #endif
561 if (ctxt->inSubset == 0) {
562 ret = xmlGetPredefinedEntity(name);
563 if (ret != NULL)
564 return(ret);
566 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1)) {
567 if (ctxt->inSubset == 2) {
568 ctxt->myDoc->standalone = 0;
569 ret = xmlGetDocEntity(ctxt->myDoc, name);
570 ctxt->myDoc->standalone = 1;
571 } else {
572 ret = xmlGetDocEntity(ctxt->myDoc, name);
573 if (ret == NULL) {
574 ctxt->myDoc->standalone = 0;
575 ret = xmlGetDocEntity(ctxt->myDoc, name);
576 if (ret != NULL) {
577 xmlFatalErrMsg(ctxt, XML_ERR_NOT_STANDALONE,
578 "Entity(%s) document marked standalone but requires external subset\n",
579 name, NULL);
581 ctxt->myDoc->standalone = 1;
584 } else {
585 ret = xmlGetDocEntity(ctxt->myDoc, name);
587 return(ret);
591 * xmlSAX2GetParameterEntity:
592 * @ctx: the user data (XML parser context)
593 * @name: The entity name
595 * Get a parameter entity by name
597 * Returns the xmlEntityPtr if found.
599 xmlEntityPtr
600 xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name)
602 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
603 xmlEntityPtr ret;
605 if (ctx == NULL) return(NULL);
606 #ifdef DEBUG_SAX
607 xmlGenericError(xmlGenericErrorContext,
608 "SAX.xmlSAX2GetParameterEntity(%s)\n", name);
609 #endif
611 ret = xmlGetParameterEntity(ctxt->myDoc, name);
612 return(ret);
617 * xmlSAX2EntityDecl:
618 * @ctx: the user data (XML parser context)
619 * @name: the entity name
620 * @type: the entity type
621 * @publicId: The public ID of the entity
622 * @systemId: The system ID of the entity
623 * @content: the entity value (without processing).
625 * An entity definition has been parsed
627 void
628 xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type,
629 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
631 xmlEntityPtr ent;
632 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
634 if (ctx == NULL) return;
635 #ifdef DEBUG_SAX
636 xmlGenericError(xmlGenericErrorContext,
637 "SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n",
638 name, type, publicId, systemId, content);
639 #endif
640 if (ctxt->inSubset == 1) {
641 ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
642 systemId, content);
643 if ((ent == NULL) && (ctxt->pedantic))
644 xmlWarnMsg(ctxt, XML_WAR_ENTITY_REDEFINED,
645 "Entity(%s) already defined in the internal subset\n",
646 name);
647 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
648 xmlChar *URI;
649 const char *base = NULL;
651 if (ctxt->input != NULL)
652 base = ctxt->input->filename;
653 if (base == NULL)
654 base = ctxt->directory;
656 URI = xmlBuildURI(systemId, (const xmlChar *) base);
657 ent->URI = URI;
659 } else if (ctxt->inSubset == 2) {
660 ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
661 systemId, content);
662 if ((ent == NULL) && (ctxt->pedantic) &&
663 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
664 ctxt->sax->warning(ctxt->userData,
665 "Entity(%s) already defined in the external subset\n", name);
666 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
667 xmlChar *URI;
668 const char *base = NULL;
670 if (ctxt->input != NULL)
671 base = ctxt->input->filename;
672 if (base == NULL)
673 base = ctxt->directory;
675 URI = xmlBuildURI(systemId, (const xmlChar *) base);
676 ent->URI = URI;
678 } else {
679 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
680 "SAX.xmlSAX2EntityDecl(%s) called while not in subset\n",
681 name, NULL);
686 * xmlSAX2AttributeDecl:
687 * @ctx: the user data (XML parser context)
688 * @elem: the name of the element
689 * @fullname: the attribute name
690 * @type: the attribute type
691 * @def: the type of default value
692 * @defaultValue: the attribute default value
693 * @tree: the tree of enumerated value set
695 * An attribute definition has been parsed
697 void
698 xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
699 int type, int def, const xmlChar *defaultValue,
700 xmlEnumerationPtr tree)
702 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
703 xmlAttributePtr attr;
704 xmlChar *name = NULL, *prefix = NULL;
706 /* Avoid unused variable warning if features are disabled. */
707 (void) attr;
709 if ((ctxt == NULL) || (ctxt->myDoc == NULL))
710 return;
712 #ifdef DEBUG_SAX
713 xmlGenericError(xmlGenericErrorContext,
714 "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n",
715 elem, fullname, type, def, defaultValue);
716 #endif
717 if ((xmlStrEqual(fullname, BAD_CAST "xml:id")) &&
718 (type != XML_ATTRIBUTE_ID)) {
720 * Raise the error but keep the validity flag
722 int tmp = ctxt->valid;
723 xmlErrValid(ctxt, XML_DTD_XMLID_TYPE,
724 "xml:id : attribute type should be ID\n", NULL, NULL);
725 ctxt->valid = tmp;
727 /* TODO: optimize name/prefix allocation */
728 name = xmlSplitQName(ctxt, fullname, &prefix);
729 ctxt->vctxt.valid = 1;
730 if (ctxt->inSubset == 1)
731 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
732 name, prefix, (xmlAttributeType) type,
733 (xmlAttributeDefault) def, defaultValue, tree);
734 else if (ctxt->inSubset == 2)
735 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
736 name, prefix, (xmlAttributeType) type,
737 (xmlAttributeDefault) def, defaultValue, tree);
738 else {
739 xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
740 "SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n",
741 name, NULL);
742 xmlFree(name);
743 xmlFreeEnumeration(tree);
744 return;
746 #ifdef LIBXML_VALID_ENABLED
747 if (ctxt->vctxt.valid == 0)
748 ctxt->valid = 0;
749 if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) &&
750 (ctxt->myDoc->intSubset != NULL))
751 ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
752 attr);
753 #endif /* LIBXML_VALID_ENABLED */
754 if (prefix != NULL)
755 xmlFree(prefix);
756 if (name != NULL)
757 xmlFree(name);
761 * xmlSAX2ElementDecl:
762 * @ctx: the user data (XML parser context)
763 * @name: the element name
764 * @type: the element type
765 * @content: the element value tree
767 * An element definition has been parsed
769 void
770 xmlSAX2ElementDecl(void *ctx, const xmlChar * name, int type,
771 xmlElementContentPtr content)
773 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
774 xmlElementPtr elem = NULL;
776 /* Avoid unused variable warning if features are disabled. */
777 (void) elem;
779 if ((ctxt == NULL) || (ctxt->myDoc == NULL))
780 return;
782 #ifdef DEBUG_SAX
783 xmlGenericError(xmlGenericErrorContext,
784 "SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name, type);
785 #endif
787 if (ctxt->inSubset == 1)
788 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
789 name, (xmlElementTypeVal) type, content);
790 else if (ctxt->inSubset == 2)
791 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
792 name, (xmlElementTypeVal) type, content);
793 else {
794 xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
795 "SAX.xmlSAX2ElementDecl(%s) called while not in subset\n",
796 name, NULL);
797 return;
799 #ifdef LIBXML_VALID_ENABLED
800 if (elem == NULL)
801 ctxt->valid = 0;
802 if (ctxt->validate && ctxt->wellFormed &&
803 ctxt->myDoc && ctxt->myDoc->intSubset)
804 ctxt->valid &=
805 xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
806 #endif /* LIBXML_VALID_ENABLED */
810 * xmlSAX2NotationDecl:
811 * @ctx: the user data (XML parser context)
812 * @name: The name of the notation
813 * @publicId: The public ID of the entity
814 * @systemId: The system ID of the entity
816 * What to do when a notation declaration has been parsed.
818 void
819 xmlSAX2NotationDecl(void *ctx, const xmlChar *name,
820 const xmlChar *publicId, const xmlChar *systemId)
822 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
823 xmlNotationPtr nota = NULL;
825 /* Avoid unused variable warning if features are disabled. */
826 (void) nota;
828 if ((ctxt == NULL) || (ctxt->myDoc == NULL))
829 return;
831 #ifdef DEBUG_SAX
832 xmlGenericError(xmlGenericErrorContext,
833 "SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name, publicId, systemId);
834 #endif
836 if ((publicId == NULL) && (systemId == NULL)) {
837 xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
838 "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n",
839 name, NULL);
840 return;
841 } else if (ctxt->inSubset == 1)
842 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
843 publicId, systemId);
844 else if (ctxt->inSubset == 2)
845 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name,
846 publicId, systemId);
847 else {
848 xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
849 "SAX.xmlSAX2NotationDecl(%s) called while not in subset\n",
850 name, NULL);
851 return;
853 #ifdef LIBXML_VALID_ENABLED
854 if (nota == NULL) ctxt->valid = 0;
855 if ((ctxt->validate) && (ctxt->wellFormed) &&
856 (ctxt->myDoc->intSubset != NULL))
857 ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
858 nota);
859 #endif /* LIBXML_VALID_ENABLED */
863 * xmlSAX2UnparsedEntityDecl:
864 * @ctx: the user data (XML parser context)
865 * @name: The name of the entity
866 * @publicId: The public ID of the entity
867 * @systemId: The system ID of the entity
868 * @notationName: the name of the notation
870 * What to do when an unparsed entity declaration is parsed
872 void
873 xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
874 const xmlChar *publicId, const xmlChar *systemId,
875 const xmlChar *notationName)
877 xmlEntityPtr ent;
878 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
879 if (ctx == NULL) return;
880 #ifdef DEBUG_SAX
881 xmlGenericError(xmlGenericErrorContext,
882 "SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n",
883 name, publicId, systemId, notationName);
884 #endif
885 if (ctxt->inSubset == 1) {
886 ent = xmlAddDocEntity(ctxt->myDoc, name,
887 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
888 publicId, systemId, notationName);
889 if ((ent == NULL) && (ctxt->pedantic) &&
890 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
891 ctxt->sax->warning(ctxt->userData,
892 "Entity(%s) already defined in the internal subset\n", name);
893 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
894 xmlChar *URI;
895 const char *base = NULL;
897 if (ctxt->input != NULL)
898 base = ctxt->input->filename;
899 if (base == NULL)
900 base = ctxt->directory;
902 URI = xmlBuildURI(systemId, (const xmlChar *) base);
903 ent->URI = URI;
905 } else if (ctxt->inSubset == 2) {
906 ent = xmlAddDtdEntity(ctxt->myDoc, name,
907 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
908 publicId, systemId, notationName);
909 if ((ent == NULL) && (ctxt->pedantic) &&
910 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
911 ctxt->sax->warning(ctxt->userData,
912 "Entity(%s) already defined in the external subset\n", name);
913 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
914 xmlChar *URI;
915 const char *base = NULL;
917 if (ctxt->input != NULL)
918 base = ctxt->input->filename;
919 if (base == NULL)
920 base = ctxt->directory;
922 URI = xmlBuildURI(systemId, (const xmlChar *) base);
923 ent->URI = URI;
925 } else {
926 xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
927 "SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n",
928 name, NULL);
933 * xmlSAX2SetDocumentLocator:
934 * @ctx: the user data (XML parser context)
935 * @loc: A SAX Locator
937 * Receive the document locator at startup, actually xmlDefaultSAXLocator
938 * Everything is available on the context, so this is useless in our case.
940 void
941 xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
943 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
944 #ifdef DEBUG_SAX
945 xmlGenericError(xmlGenericErrorContext,
946 "SAX.xmlSAX2SetDocumentLocator()\n");
947 #endif
951 * xmlSAX2StartDocument:
952 * @ctx: the user data (XML parser context)
954 * called when the document start being processed.
956 void
957 xmlSAX2StartDocument(void *ctx)
959 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
960 xmlDocPtr doc;
962 if (ctx == NULL) return;
964 #ifdef DEBUG_SAX
965 xmlGenericError(xmlGenericErrorContext,
966 "SAX.xmlSAX2StartDocument()\n");
967 #endif
968 if (ctxt->html) {
969 #ifdef LIBXML_HTML_ENABLED
970 if (ctxt->myDoc == NULL)
971 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
972 if (ctxt->myDoc == NULL) {
973 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
974 return;
976 ctxt->myDoc->properties = XML_DOC_HTML;
977 ctxt->myDoc->parseFlags = ctxt->options;
978 #else
979 xmlGenericError(xmlGenericErrorContext,
980 "libxml2 built without HTML support\n");
981 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
982 ctxt->instate = XML_PARSER_EOF;
983 ctxt->disableSAX = 1;
984 return;
985 #endif
986 } else {
987 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
988 if (doc != NULL) {
989 doc->properties = 0;
990 if (ctxt->options & XML_PARSE_OLD10)
991 doc->properties |= XML_DOC_OLD10;
992 doc->parseFlags = ctxt->options;
993 if (ctxt->encoding != NULL)
994 doc->encoding = xmlStrdup(ctxt->encoding);
995 else
996 doc->encoding = NULL;
997 doc->standalone = ctxt->standalone;
998 } else {
999 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
1000 return;
1002 if ((ctxt->dictNames) && (doc != NULL)) {
1003 doc->dict = ctxt->dict;
1004 xmlDictReference(doc->dict);
1007 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
1008 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
1009 ctxt->myDoc->URL = xmlPathToURI((const xmlChar *)ctxt->input->filename);
1010 if (ctxt->myDoc->URL == NULL)
1011 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
1016 * xmlSAX2EndDocument:
1017 * @ctx: the user data (XML parser context)
1019 * called when the document end has been detected.
1021 void
1022 xmlSAX2EndDocument(void *ctx)
1024 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1025 #ifdef DEBUG_SAX
1026 xmlGenericError(xmlGenericErrorContext,
1027 "SAX.xmlSAX2EndDocument()\n");
1028 #endif
1029 if (ctx == NULL) return;
1030 #ifdef LIBXML_VALID_ENABLED
1031 if (ctxt->validate && ctxt->wellFormed &&
1032 ctxt->myDoc && ctxt->myDoc->intSubset)
1033 ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
1034 #endif /* LIBXML_VALID_ENABLED */
1037 * Grab the encoding if it was added on-the-fly
1039 if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
1040 (ctxt->myDoc->encoding == NULL)) {
1041 ctxt->myDoc->encoding = ctxt->encoding;
1042 ctxt->encoding = NULL;
1044 if ((ctxt->inputTab != NULL) &&
1045 (ctxt->inputNr > 0) && (ctxt->inputTab[0] != NULL) &&
1046 (ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
1047 (ctxt->myDoc->encoding == NULL)) {
1048 ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
1050 if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
1051 (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
1052 ctxt->myDoc->charset = ctxt->charset;
1056 #if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
1058 * xmlNsErrMsg:
1059 * @ctxt: an XML parser context
1060 * @error: the error number
1061 * @msg: the error message
1062 * @str1: an error string
1063 * @str2: an error string
1065 * Handle a namespace error
1067 static void LIBXML_ATTR_FORMAT(3,0)
1068 xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
1069 const char *msg, const xmlChar *str1, const xmlChar *str2)
1071 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
1072 (ctxt->instate == XML_PARSER_EOF))
1073 return;
1074 if (ctxt != NULL)
1075 ctxt->errNo = error;
1076 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
1077 XML_ERR_ERROR, NULL, 0,
1078 (const char *) str1, (const char *) str2,
1079 NULL, 0, 0, msg, str1, str2);
1083 * xmlSAX2AttributeInternal:
1084 * @ctx: the user data (XML parser context)
1085 * @fullname: The attribute name, including namespace prefix
1086 * @value: The attribute value
1087 * @prefix: the prefix on the element node
1089 * Handle an attribute that has been read by the parser.
1090 * The default handling is to convert the attribute into an
1091 * DOM subtree and past it in a new xmlAttr element added to
1092 * the element.
1094 static void
1095 xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
1096 const xmlChar *value, const xmlChar *prefix ATTRIBUTE_UNUSED)
1098 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1099 xmlAttrPtr ret;
1100 xmlChar *name;
1101 xmlChar *ns;
1102 xmlChar *nval;
1103 xmlNsPtr namespace;
1105 if (ctxt->html) {
1106 name = xmlStrdup(fullname);
1107 ns = NULL;
1108 namespace = NULL;
1109 } else {
1111 * Split the full name into a namespace prefix and the tag name
1113 name = xmlSplitQName(ctxt, fullname, &ns);
1114 if ((name != NULL) && (name[0] == 0)) {
1115 if (xmlStrEqual(ns, BAD_CAST "xmlns")) {
1116 xmlNsErrMsg(ctxt, XML_ERR_NS_DECL_ERROR,
1117 "invalid namespace declaration '%s'\n",
1118 fullname, NULL);
1119 } else {
1120 xmlNsWarnMsg(ctxt, XML_WAR_NS_COLUMN,
1121 "Avoid attribute ending with ':' like '%s'\n",
1122 fullname, NULL);
1124 if (ns != NULL)
1125 xmlFree(ns);
1126 ns = NULL;
1127 xmlFree(name);
1128 name = xmlStrdup(fullname);
1131 if (name == NULL) {
1132 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1133 if (ns != NULL)
1134 xmlFree(ns);
1135 return;
1138 #ifdef LIBXML_HTML_ENABLED
1139 if ((ctxt->html) &&
1140 (value == NULL) && (htmlIsBooleanAttr(fullname))) {
1141 nval = xmlStrdup(fullname);
1142 value = (const xmlChar *) nval;
1143 } else
1144 #endif
1146 #ifdef LIBXML_VALID_ENABLED
1148 * Do the last stage of the attribute normalization
1149 * Needed for HTML too:
1150 * http://www.w3.org/TR/html4/types.html#h-6.2
1152 ctxt->vctxt.valid = 1;
1153 nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt,
1154 ctxt->myDoc, ctxt->node,
1155 fullname, value);
1156 if (ctxt->vctxt.valid != 1) {
1157 ctxt->valid = 0;
1159 if (nval != NULL)
1160 value = nval;
1161 #else
1162 nval = NULL;
1163 #endif /* LIBXML_VALID_ENABLED */
1167 * Check whether it's a namespace definition
1169 if ((!ctxt->html) && (ns == NULL) &&
1170 (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
1171 (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
1172 xmlNsPtr nsret;
1173 xmlChar *val;
1175 /* Avoid unused variable warning if features are disabled. */
1176 (void) nsret;
1178 if (!ctxt->replaceEntities) {
1179 ctxt->depth++;
1180 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
1181 0,0,0);
1182 ctxt->depth--;
1183 if (val == NULL) {
1184 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1185 if (name != NULL)
1186 xmlFree(name);
1187 if (nval != NULL)
1188 xmlFree(nval);
1189 return;
1191 } else {
1192 val = (xmlChar *) value;
1195 if (val[0] != 0) {
1196 xmlURIPtr uri;
1198 uri = xmlParseURI((const char *)val);
1199 if (uri == NULL) {
1200 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
1201 ctxt->sax->warning(ctxt->userData,
1202 "xmlns: %s not a valid URI\n", val);
1203 } else {
1204 if (uri->scheme == NULL) {
1205 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
1206 ctxt->sax->warning(ctxt->userData,
1207 "xmlns: URI %s is not absolute\n", val);
1209 xmlFreeURI(uri);
1213 /* a default namespace definition */
1214 nsret = xmlNewNs(ctxt->node, val, NULL);
1216 #ifdef LIBXML_VALID_ENABLED
1218 * Validate also for namespace decls, they are attributes from
1219 * an XML-1.0 perspective
1221 if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
1222 ctxt->myDoc && ctxt->myDoc->intSubset)
1223 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
1224 ctxt->node, prefix, nsret, val);
1225 #endif /* LIBXML_VALID_ENABLED */
1226 if (name != NULL)
1227 xmlFree(name);
1228 if (nval != NULL)
1229 xmlFree(nval);
1230 if (val != value)
1231 xmlFree(val);
1232 return;
1234 if ((!ctxt->html) &&
1235 (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
1236 (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
1237 xmlNsPtr nsret;
1238 xmlChar *val;
1240 /* Avoid unused variable warning if features are disabled. */
1241 (void) nsret;
1243 if (!ctxt->replaceEntities) {
1244 ctxt->depth++;
1245 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
1246 0,0,0);
1247 ctxt->depth--;
1248 if (val == NULL) {
1249 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1250 xmlFree(ns);
1251 if (name != NULL)
1252 xmlFree(name);
1253 if (nval != NULL)
1254 xmlFree(nval);
1255 return;
1257 } else {
1258 val = (xmlChar *) value;
1261 if (val[0] == 0) {
1262 xmlNsErrMsg(ctxt, XML_NS_ERR_EMPTY,
1263 "Empty namespace name for prefix %s\n", name, NULL);
1265 if ((ctxt->pedantic != 0) && (val[0] != 0)) {
1266 xmlURIPtr uri;
1268 uri = xmlParseURI((const char *)val);
1269 if (uri == NULL) {
1270 xmlNsWarnMsg(ctxt, XML_WAR_NS_URI,
1271 "xmlns:%s: %s not a valid URI\n", name, value);
1272 } else {
1273 if (uri->scheme == NULL) {
1274 xmlNsWarnMsg(ctxt, XML_WAR_NS_URI_RELATIVE,
1275 "xmlns:%s: URI %s is not absolute\n", name, value);
1277 xmlFreeURI(uri);
1281 /* a standard namespace definition */
1282 nsret = xmlNewNs(ctxt->node, val, name);
1283 xmlFree(ns);
1284 #ifdef LIBXML_VALID_ENABLED
1286 * Validate also for namespace decls, they are attributes from
1287 * an XML-1.0 perspective
1289 if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
1290 ctxt->myDoc && ctxt->myDoc->intSubset)
1291 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
1292 ctxt->node, prefix, nsret, value);
1293 #endif /* LIBXML_VALID_ENABLED */
1294 if (name != NULL)
1295 xmlFree(name);
1296 if (nval != NULL)
1297 xmlFree(nval);
1298 if (val != value)
1299 xmlFree(val);
1300 return;
1303 if (ns != NULL) {
1304 namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
1306 if (namespace == NULL) {
1307 xmlNsErrMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
1308 "Namespace prefix %s of attribute %s is not defined\n",
1309 ns, name);
1310 } else {
1311 xmlAttrPtr prop;
1313 prop = ctxt->node->properties;
1314 while (prop != NULL) {
1315 if (prop->ns != NULL) {
1316 if ((xmlStrEqual(name, prop->name)) &&
1317 ((namespace == prop->ns) ||
1318 (xmlStrEqual(namespace->href, prop->ns->href)))) {
1319 xmlNsErrMsg(ctxt, XML_ERR_ATTRIBUTE_REDEFINED,
1320 "Attribute %s in %s redefined\n",
1321 name, namespace->href);
1322 ctxt->wellFormed = 0;
1323 if (ctxt->recovery == 0) ctxt->disableSAX = 1;
1324 if (name != NULL)
1325 xmlFree(name);
1326 goto error;
1329 prop = prop->next;
1332 } else {
1333 namespace = NULL;
1336 /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
1337 ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL);
1338 if (ret == NULL)
1339 goto error;
1341 if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
1342 xmlNodePtr tmp;
1344 ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
1345 tmp = ret->children;
1346 while (tmp != NULL) {
1347 tmp->parent = (xmlNodePtr) ret;
1348 if (tmp->next == NULL)
1349 ret->last = tmp;
1350 tmp = tmp->next;
1352 } else if (value != NULL) {
1353 ret->children = xmlNewDocText(ctxt->myDoc, value);
1354 ret->last = ret->children;
1355 if (ret->children != NULL)
1356 ret->children->parent = (xmlNodePtr) ret;
1359 #ifdef LIBXML_VALID_ENABLED
1360 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
1361 ctxt->myDoc && ctxt->myDoc->intSubset) {
1364 * If we don't substitute entities, the validation should be
1365 * done on a value with replaced entities anyway.
1367 if (!ctxt->replaceEntities) {
1368 xmlChar *val;
1370 ctxt->depth++;
1371 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
1372 0,0,0);
1373 ctxt->depth--;
1375 if (val == NULL)
1376 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
1377 ctxt->myDoc, ctxt->node, ret, value);
1378 else {
1379 xmlChar *nvalnorm;
1382 * Do the last stage of the attribute normalization
1383 * It need to be done twice ... it's an extra burden related
1384 * to the ability to keep xmlSAX2References in attributes
1386 nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc,
1387 ctxt->node, fullname, val);
1388 if (nvalnorm != NULL) {
1389 xmlFree(val);
1390 val = nvalnorm;
1393 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
1394 ctxt->myDoc, ctxt->node, ret, val);
1395 xmlFree(val);
1397 } else {
1398 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
1399 ctxt->node, ret, value);
1401 } else
1402 #endif /* LIBXML_VALID_ENABLED */
1403 if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
1404 (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
1405 ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0))) &&
1406 /* Don't create IDs containing entity references */
1407 (ret->children != NULL) &&
1408 (ret->children->type == XML_TEXT_NODE) &&
1409 (ret->children->next == NULL)) {
1410 xmlChar *content = ret->children->content;
1412 * when validating, the ID registration is done at the attribute
1413 * validation level. Otherwise we have to do specific handling here.
1415 if (xmlStrEqual(fullname, BAD_CAST "xml:id")) {
1417 * Add the xml:id value
1419 * Open issue: normalization of the value.
1421 if (xmlValidateNCName(content, 1) != 0) {
1422 xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
1423 "xml:id : attribute value %s is not an NCName\n",
1424 (const char *) content, NULL);
1426 xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
1427 } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
1428 xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
1429 else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
1430 xmlAddRef(&ctxt->vctxt, ctxt->myDoc, content, ret);
1433 error:
1434 if (nval != NULL)
1435 xmlFree(nval);
1436 if (ns != NULL)
1437 xmlFree(ns);
1441 * xmlCheckDefaultedAttributes:
1443 * Check defaulted attributes from the DTD
1445 static void
1446 xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name,
1447 const xmlChar *prefix, const xmlChar **atts) {
1448 xmlElementPtr elemDecl;
1449 const xmlChar *att;
1450 int internal = 1;
1451 int i;
1453 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix);
1454 if (elemDecl == NULL) {
1455 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix);
1456 internal = 0;
1459 process_external_subset:
1461 if (elemDecl != NULL) {
1462 xmlAttributePtr attr = elemDecl->attributes;
1464 * Check against defaulted attributes from the external subset
1465 * if the document is stamped as standalone
1467 if ((ctxt->myDoc->standalone == 1) &&
1468 (ctxt->myDoc->extSubset != NULL) &&
1469 (ctxt->validate)) {
1470 while (attr != NULL) {
1471 if ((attr->defaultValue != NULL) &&
1472 (xmlGetDtdQAttrDesc(ctxt->myDoc->extSubset,
1473 attr->elem, attr->name,
1474 attr->prefix) == attr) &&
1475 (xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
1476 attr->elem, attr->name,
1477 attr->prefix) == NULL)) {
1478 xmlChar *fulln;
1480 if (attr->prefix != NULL) {
1481 fulln = xmlStrdup(attr->prefix);
1482 fulln = xmlStrcat(fulln, BAD_CAST ":");
1483 fulln = xmlStrcat(fulln, attr->name);
1484 } else {
1485 fulln = xmlStrdup(attr->name);
1487 if (fulln == NULL) {
1488 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1489 break;
1493 * Check that the attribute is not declared in the
1494 * serialization
1496 att = NULL;
1497 if (atts != NULL) {
1498 i = 0;
1499 att = atts[i];
1500 while (att != NULL) {
1501 if (xmlStrEqual(att, fulln))
1502 break;
1503 i += 2;
1504 att = atts[i];
1507 if (att == NULL) {
1508 xmlErrValid(ctxt, XML_DTD_STANDALONE_DEFAULTED,
1509 "standalone: attribute %s on %s defaulted from external subset\n",
1510 (const char *)fulln,
1511 (const char *)attr->elem);
1513 xmlFree(fulln);
1515 attr = attr->nexth;
1520 * Actually insert defaulted values when needed
1522 attr = elemDecl->attributes;
1523 while (attr != NULL) {
1525 * Make sure that attributes redefinition occurring in the
1526 * internal subset are not overridden by definitions in the
1527 * external subset.
1529 if (attr->defaultValue != NULL) {
1531 * the element should be instantiated in the tree if:
1532 * - this is a namespace prefix
1533 * - the user required for completion in the tree
1534 * like XSLT
1535 * - there isn't already an attribute definition
1536 * in the internal subset overriding it.
1538 if (((attr->prefix != NULL) &&
1539 (xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) ||
1540 ((attr->prefix == NULL) &&
1541 (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) ||
1542 (ctxt->loadsubset & XML_COMPLETE_ATTRS)) {
1543 xmlAttributePtr tst;
1545 tst = xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
1546 attr->elem, attr->name,
1547 attr->prefix);
1548 if ((tst == attr) || (tst == NULL)) {
1549 xmlChar fn[50];
1550 xmlChar *fulln;
1552 fulln = xmlBuildQName(attr->name, attr->prefix, fn, 50);
1553 if (fulln == NULL) {
1554 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1555 return;
1559 * Check that the attribute is not declared in the
1560 * serialization
1562 att = NULL;
1563 if (atts != NULL) {
1564 i = 0;
1565 att = atts[i];
1566 while (att != NULL) {
1567 if (xmlStrEqual(att, fulln))
1568 break;
1569 i += 2;
1570 att = atts[i];
1573 if (att == NULL) {
1574 xmlSAX2AttributeInternal(ctxt, fulln,
1575 attr->defaultValue, prefix);
1577 if ((fulln != fn) && (fulln != attr->name))
1578 xmlFree(fulln);
1582 attr = attr->nexth;
1584 if (internal == 1) {
1585 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset,
1586 name, prefix);
1587 internal = 0;
1588 goto process_external_subset;
1594 * xmlSAX2StartElement:
1595 * @ctx: the user data (XML parser context)
1596 * @fullname: The element name, including namespace prefix
1597 * @atts: An array of name/value attributes pairs, NULL terminated
1599 * called when an opening tag has been processed.
1601 void
1602 xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
1604 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1605 xmlNodePtr ret;
1606 xmlNodePtr parent;
1607 xmlNsPtr ns;
1608 xmlChar *name;
1609 xmlChar *prefix;
1610 const xmlChar *att;
1611 const xmlChar *value;
1612 int i;
1614 if ((ctx == NULL) || (fullname == NULL) || (ctxt->myDoc == NULL)) return;
1615 parent = ctxt->node;
1616 #ifdef DEBUG_SAX
1617 xmlGenericError(xmlGenericErrorContext,
1618 "SAX.xmlSAX2StartElement(%s)\n", fullname);
1619 #endif
1622 * First check on validity:
1624 if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
1625 ((ctxt->myDoc->intSubset == NULL) ||
1626 ((ctxt->myDoc->intSubset->notations == NULL) &&
1627 (ctxt->myDoc->intSubset->elements == NULL) &&
1628 (ctxt->myDoc->intSubset->attributes == NULL) &&
1629 (ctxt->myDoc->intSubset->entities == NULL)))) {
1630 xmlErrValid(ctxt, XML_ERR_NO_DTD,
1631 "Validation failed: no DTD found !", NULL, NULL);
1632 ctxt->validate = 0;
1635 if (ctxt->html) {
1636 prefix = NULL;
1637 name = xmlStrdup(fullname);
1638 } else {
1640 * Split the full name into a namespace prefix and the tag name
1642 name = xmlSplitQName(ctxt, fullname, &prefix);
1646 * Note : the namespace resolution is deferred until the end of the
1647 * attributes parsing, since local namespace can be defined as
1648 * an attribute at this level.
1650 ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL);
1651 if (ret == NULL) {
1652 if (prefix != NULL)
1653 xmlFree(prefix);
1654 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1655 return;
1657 if (ctxt->myDoc->children == NULL) {
1658 #ifdef DEBUG_SAX_TREE
1659 xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name);
1660 #endif
1661 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1662 } else if (parent == NULL) {
1663 parent = ctxt->myDoc->children;
1665 ctxt->nodemem = -1;
1666 if (ctxt->linenumbers) {
1667 if (ctxt->input != NULL) {
1668 if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
1669 ret->line = ctxt->input->line;
1670 else
1671 ret->line = USHRT_MAX;
1676 * We are parsing a new node.
1678 #ifdef DEBUG_SAX_TREE
1679 xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name);
1680 #endif
1681 if (nodePush(ctxt, ret) < 0) {
1682 xmlUnlinkNode(ret);
1683 xmlFreeNode(ret);
1684 if (prefix != NULL)
1685 xmlFree(prefix);
1686 return;
1690 * Link the child element
1692 if (parent != NULL) {
1693 if (parent->type == XML_ELEMENT_NODE) {
1694 #ifdef DEBUG_SAX_TREE
1695 xmlGenericError(xmlGenericErrorContext,
1696 "adding child %s to %s\n", name, parent->name);
1697 #endif
1698 xmlAddChild(parent, ret);
1699 } else {
1700 #ifdef DEBUG_SAX_TREE
1701 xmlGenericError(xmlGenericErrorContext,
1702 "adding sibling %s to ", name);
1703 xmlDebugDumpOneNode(stderr, parent, 0);
1704 #endif
1705 xmlAddSibling(parent, ret);
1709 if (!ctxt->html) {
1711 * Insert all the defaulted attributes from the DTD especially
1712 * namespaces
1714 if ((ctxt->myDoc->intSubset != NULL) ||
1715 (ctxt->myDoc->extSubset != NULL)) {
1716 xmlCheckDefaultedAttributes(ctxt, name, prefix, atts);
1720 * process all the attributes whose name start with "xmlns"
1722 if (atts != NULL) {
1723 i = 0;
1724 att = atts[i++];
1725 value = atts[i++];
1726 while ((att != NULL) && (value != NULL)) {
1727 if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') &&
1728 (att[3] == 'n') && (att[4] == 's'))
1729 xmlSAX2AttributeInternal(ctxt, att, value, prefix);
1731 att = atts[i++];
1732 value = atts[i++];
1737 * Search the namespace, note that since the attributes have been
1738 * processed, the local namespaces are available.
1740 ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
1741 if ((ns == NULL) && (parent != NULL))
1742 ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
1743 if ((prefix != NULL) && (ns == NULL)) {
1744 ns = xmlNewNs(ret, NULL, prefix);
1745 xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
1746 "Namespace prefix %s is not defined\n",
1747 prefix, NULL);
1751 * set the namespace node, making sure that if the default namespace
1752 * is unbound on a parent we simply keep it NULL
1754 if ((ns != NULL) && (ns->href != NULL) &&
1755 ((ns->href[0] != 0) || (ns->prefix != NULL)))
1756 xmlSetNs(ret, ns);
1760 * process all the other attributes
1762 if (atts != NULL) {
1763 i = 0;
1764 att = atts[i++];
1765 value = atts[i++];
1766 if (ctxt->html) {
1767 while (att != NULL) {
1768 xmlSAX2AttributeInternal(ctxt, att, value, NULL);
1769 att = atts[i++];
1770 value = atts[i++];
1772 } else {
1773 while ((att != NULL) && (value != NULL)) {
1774 if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l') ||
1775 (att[3] != 'n') || (att[4] != 's'))
1776 xmlSAX2AttributeInternal(ctxt, att, value, NULL);
1779 * Next ones
1781 att = atts[i++];
1782 value = atts[i++];
1787 #ifdef LIBXML_VALID_ENABLED
1789 * If it's the Document root, finish the DTD validation and
1790 * check the document root element for validity
1792 if ((ctxt->validate) &&
1793 ((ctxt->vctxt.flags & XML_VCTXT_DTD_VALIDATED) == 0)) {
1794 int chk;
1796 chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
1797 if (chk <= 0)
1798 ctxt->valid = 0;
1799 if (chk < 0)
1800 ctxt->wellFormed = 0;
1801 ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
1802 ctxt->vctxt.flags |= XML_VCTXT_DTD_VALIDATED;
1804 #endif /* LIBXML_VALID_ENABLED */
1806 if (prefix != NULL)
1807 xmlFree(prefix);
1812 * xmlSAX2EndElement:
1813 * @ctx: the user data (XML parser context)
1814 * @name: The element name
1816 * called when the end of an element has been detected.
1818 void
1819 xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
1821 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1822 xmlNodePtr cur;
1824 if (ctx == NULL) return;
1825 cur = ctxt->node;
1826 #ifdef DEBUG_SAX
1827 if (name == NULL)
1828 xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(NULL)\n");
1829 else
1830 xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(%s)\n", name);
1831 #endif
1833 ctxt->nodemem = -1;
1835 #ifdef LIBXML_VALID_ENABLED
1836 if (ctxt->validate && ctxt->wellFormed &&
1837 ctxt->myDoc && ctxt->myDoc->intSubset)
1838 ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
1839 cur);
1840 #endif /* LIBXML_VALID_ENABLED */
1844 * end of parsing of this node.
1846 #ifdef DEBUG_SAX_TREE
1847 xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name);
1848 #endif
1849 nodePop(ctxt);
1851 #endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLED || LIBXML_LEGACY_ENABLED */
1854 * xmlSAX2TextNode:
1855 * @ctxt: the parser context
1856 * @str: the input string
1857 * @len: the string length
1859 * Callback for a text node
1861 * Returns the newly allocated string or NULL if not needed or error
1863 static xmlNodePtr
1864 xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
1865 xmlNodePtr ret;
1866 const xmlChar *intern = NULL;
1869 * Allocate
1871 if (ctxt->freeElems != NULL) {
1872 ret = ctxt->freeElems;
1873 ctxt->freeElems = ret->next;
1874 ctxt->freeElemsNr--;
1875 } else {
1876 ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
1878 if (ret == NULL) {
1879 xmlErrMemory(ctxt, "xmlSAX2Characters");
1880 return(NULL);
1882 memset(ret, 0, sizeof(xmlNode));
1884 * intern the formatting blanks found between tags, or the
1885 * very short strings
1887 if (ctxt->dictNames) {
1888 xmlChar cur = str[len];
1890 if ((len < (int) (2 * sizeof(void *))) &&
1891 (ctxt->options & XML_PARSE_COMPACT)) {
1892 /* store the string in the node overriding properties and nsDef */
1893 xmlChar *tmp = (xmlChar *) &(ret->properties);
1894 memcpy(tmp, str, len);
1895 tmp[len] = 0;
1896 intern = tmp;
1897 } else if ((len <= 3) && ((cur == '"') || (cur == '\'') ||
1898 ((cur == '<') && (str[len + 1] != '!')))) {
1899 intern = xmlDictLookup(ctxt->dict, str, len);
1900 } else if (IS_BLANK_CH(*str) && (len < 60) && (cur == '<') &&
1901 (str[len + 1] != '!')) {
1902 int i;
1904 for (i = 1;i < len;i++) {
1905 if (!IS_BLANK_CH(str[i])) goto skip;
1907 intern = xmlDictLookup(ctxt->dict, str, len);
1910 skip:
1911 ret->type = XML_TEXT_NODE;
1913 ret->name = xmlStringText;
1914 if (intern == NULL) {
1915 ret->content = xmlStrndup(str, len);
1916 if (ret->content == NULL) {
1917 xmlSAX2ErrMemory(ctxt, "xmlSAX2TextNode");
1918 xmlFree(ret);
1919 return(NULL);
1921 } else
1922 ret->content = (xmlChar *) intern;
1924 if (ctxt->linenumbers) {
1925 if (ctxt->input != NULL) {
1926 if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
1927 ret->line = ctxt->input->line;
1928 else {
1929 ret->line = USHRT_MAX;
1930 if (ctxt->options & XML_PARSE_BIG_LINES)
1931 ret->psvi = (void *) (ptrdiff_t) ctxt->input->line;
1936 if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
1937 xmlRegisterNodeDefaultValue(ret);
1938 return(ret);
1941 #ifdef LIBXML_VALID_ENABLED
1943 * xmlSAX2DecodeAttrEntities:
1944 * @ctxt: the parser context
1945 * @str: the input string
1946 * @len: the string length
1948 * Remove the entities from an attribute value
1950 * Returns the newly allocated string or NULL if not needed or error
1952 static xmlChar *
1953 xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt, const xmlChar *str,
1954 const xmlChar *end) {
1955 const xmlChar *in;
1956 xmlChar *ret;
1958 in = str;
1959 while (in < end)
1960 if (*in++ == '&')
1961 goto decode;
1962 return(NULL);
1963 decode:
1964 ctxt->depth++;
1965 ret = xmlStringLenDecodeEntities(ctxt, str, end - str,
1966 XML_SUBSTITUTE_REF, 0,0,0);
1967 ctxt->depth--;
1968 return(ret);
1970 #endif /* LIBXML_VALID_ENABLED */
1973 * xmlSAX2AttributeNs:
1974 * @ctx: the user data (XML parser context)
1975 * @localname: the local name of the attribute
1976 * @prefix: the attribute namespace prefix if available
1977 * @URI: the attribute namespace name if available
1978 * @value: Start of the attribute value
1979 * @valueend: end of the attribute value
1981 * Handle an attribute that has been read by the parser.
1982 * The default handling is to convert the attribute into an
1983 * DOM subtree and past it in a new xmlAttr element added to
1984 * the element.
1986 static void
1987 xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
1988 const xmlChar * localname,
1989 const xmlChar * prefix,
1990 const xmlChar * value,
1991 const xmlChar * valueend)
1993 xmlAttrPtr ret;
1994 xmlNsPtr namespace = NULL;
1995 xmlChar *dup = NULL;
1998 * Note: if prefix == NULL, the attribute is not in the default namespace
2000 if (prefix != NULL)
2001 namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, prefix);
2004 * allocate the node
2006 if (ctxt->freeAttrs != NULL) {
2007 ret = ctxt->freeAttrs;
2008 ctxt->freeAttrs = ret->next;
2009 ctxt->freeAttrsNr--;
2010 memset(ret, 0, sizeof(xmlAttr));
2011 ret->type = XML_ATTRIBUTE_NODE;
2013 ret->parent = ctxt->node;
2014 ret->doc = ctxt->myDoc;
2015 ret->ns = namespace;
2017 if (ctxt->dictNames)
2018 ret->name = localname;
2019 else
2020 ret->name = xmlStrdup(localname);
2022 /* link at the end to preserve order, TODO speed up with a last */
2023 if (ctxt->node->properties == NULL) {
2024 ctxt->node->properties = ret;
2025 } else {
2026 xmlAttrPtr prev = ctxt->node->properties;
2028 while (prev->next != NULL) prev = prev->next;
2029 prev->next = ret;
2030 ret->prev = prev;
2033 if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
2034 xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
2035 } else {
2036 if (ctxt->dictNames)
2037 ret = xmlNewNsPropEatName(ctxt->node, namespace,
2038 (xmlChar *) localname, NULL);
2039 else
2040 ret = xmlNewNsProp(ctxt->node, namespace, localname, NULL);
2041 if (ret == NULL) {
2042 xmlErrMemory(ctxt, "xmlSAX2AttributeNs");
2043 return;
2047 if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
2048 xmlNodePtr tmp;
2051 * We know that if there is an entity reference, then
2052 * the string has been dup'ed and terminates with 0
2053 * otherwise with ' or "
2055 if (*valueend != 0) {
2056 tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
2057 ret->children = tmp;
2058 ret->last = tmp;
2059 if (tmp != NULL) {
2060 tmp->doc = ret->doc;
2061 tmp->parent = (xmlNodePtr) ret;
2063 } else {
2064 ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value,
2065 valueend - value);
2066 tmp = ret->children;
2067 while (tmp != NULL) {
2068 tmp->doc = ret->doc;
2069 tmp->parent = (xmlNodePtr) ret;
2070 if (tmp->next == NULL)
2071 ret->last = tmp;
2072 tmp = tmp->next;
2075 } else if (value != NULL) {
2076 xmlNodePtr tmp;
2078 tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
2079 ret->children = tmp;
2080 ret->last = tmp;
2081 if (tmp != NULL) {
2082 tmp->doc = ret->doc;
2083 tmp->parent = (xmlNodePtr) ret;
2087 #ifdef LIBXML_VALID_ENABLED
2088 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
2089 ctxt->myDoc && ctxt->myDoc->intSubset) {
2091 * If we don't substitute entities, the validation should be
2092 * done on a value with replaced entities anyway.
2094 if (!ctxt->replaceEntities) {
2095 dup = xmlSAX2DecodeAttrEntities(ctxt, value, valueend);
2096 if (dup == NULL) {
2097 if (*valueend == 0) {
2098 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2099 ctxt->myDoc, ctxt->node, ret, value);
2100 } else {
2102 * That should already be normalized.
2103 * cheaper to finally allocate here than duplicate
2104 * entry points in the full validation code
2106 dup = xmlStrndup(value, valueend - value);
2108 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2109 ctxt->myDoc, ctxt->node, ret, dup);
2111 } else {
2113 * dup now contains a string of the flattened attribute
2114 * content with entities substituted. Check if we need to
2115 * apply an extra layer of normalization.
2116 * It need to be done twice ... it's an extra burden related
2117 * to the ability to keep references in attributes
2119 if (ctxt->attsSpecial != NULL) {
2120 xmlChar *nvalnorm;
2121 xmlChar fn[50];
2122 xmlChar *fullname;
2124 fullname = xmlBuildQName(localname, prefix, fn, 50);
2125 if (fullname != NULL) {
2126 ctxt->vctxt.valid = 1;
2127 nvalnorm = xmlValidCtxtNormalizeAttributeValue(
2128 &ctxt->vctxt, ctxt->myDoc,
2129 ctxt->node, fullname, dup);
2130 if (ctxt->vctxt.valid != 1)
2131 ctxt->valid = 0;
2133 if ((fullname != fn) && (fullname != localname))
2134 xmlFree(fullname);
2135 if (nvalnorm != NULL) {
2136 xmlFree(dup);
2137 dup = nvalnorm;
2142 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2143 ctxt->myDoc, ctxt->node, ret, dup);
2145 } else {
2147 * if entities already have been substituted, then
2148 * the attribute as passed is already normalized
2150 dup = xmlStrndup(value, valueend - value);
2152 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2153 ctxt->myDoc, ctxt->node, ret, dup);
2155 } else
2156 #endif /* LIBXML_VALID_ENABLED */
2157 if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
2158 (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
2159 ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0))) &&
2160 /* Don't create IDs containing entity references */
2161 (ret->children != NULL) &&
2162 (ret->children->type == XML_TEXT_NODE) &&
2163 (ret->children->next == NULL)) {
2164 xmlChar *content = ret->children->content;
2166 * when validating, the ID registration is done at the attribute
2167 * validation level. Otherwise we have to do specific handling here.
2169 if ((prefix == ctxt->str_xml) &&
2170 (localname[0] == 'i') && (localname[1] == 'd') &&
2171 (localname[2] == 0)) {
2173 * Add the xml:id value
2175 * Open issue: normalization of the value.
2177 #if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
2178 #ifdef LIBXML_VALID_ENABLED
2179 if (xmlValidateNCName(content, 1) != 0) {
2180 xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
2181 "xml:id : attribute value %s is not an NCName\n",
2182 (const char *) content, NULL);
2184 #endif
2185 #endif
2186 xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
2187 } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
2188 xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
2189 } else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) {
2190 xmlAddRef(&ctxt->vctxt, ctxt->myDoc, content, ret);
2193 if (dup != NULL)
2194 xmlFree(dup);
2198 * xmlSAX2StartElementNs:
2199 * @ctx: the user data (XML parser context)
2200 * @localname: the local name of the element
2201 * @prefix: the element namespace prefix if available
2202 * @URI: the element namespace name if available
2203 * @nb_namespaces: number of namespace definitions on that node
2204 * @namespaces: pointer to the array of prefix/URI pairs namespace definitions
2205 * @nb_attributes: the number of attributes on that node
2206 * @nb_defaulted: the number of defaulted attributes.
2207 * @attributes: pointer to the array of (localname/prefix/URI/value/end)
2208 * attribute values.
2210 * SAX2 callback when an element start has been detected by the parser.
2211 * It provides the namespace information for the element, as well as
2212 * the new namespace declarations on the element.
2214 void
2215 xmlSAX2StartElementNs(void *ctx,
2216 const xmlChar *localname,
2217 const xmlChar *prefix,
2218 const xmlChar *URI,
2219 int nb_namespaces,
2220 const xmlChar **namespaces,
2221 int nb_attributes,
2222 int nb_defaulted,
2223 const xmlChar **attributes)
2225 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2226 xmlNodePtr ret;
2227 xmlNodePtr parent;
2228 xmlNsPtr last = NULL, ns;
2229 const xmlChar *uri, *pref;
2230 xmlChar *lname = NULL;
2231 int i, j;
2233 if (ctx == NULL) return;
2234 parent = ctxt->node;
2236 * First check on validity:
2238 if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
2239 ((ctxt->myDoc->intSubset == NULL) ||
2240 ((ctxt->myDoc->intSubset->notations == NULL) &&
2241 (ctxt->myDoc->intSubset->elements == NULL) &&
2242 (ctxt->myDoc->intSubset->attributes == NULL) &&
2243 (ctxt->myDoc->intSubset->entities == NULL)))) {
2244 xmlErrValid(ctxt, XML_DTD_NO_DTD,
2245 "Validation failed: no DTD found !", NULL, NULL);
2246 ctxt->validate = 0;
2250 * Take care of the rare case of an undefined namespace prefix
2252 if ((prefix != NULL) && (URI == NULL)) {
2253 if (ctxt->dictNames) {
2254 const xmlChar *fullname;
2256 fullname = xmlDictQLookup(ctxt->dict, prefix, localname);
2257 if (fullname != NULL)
2258 localname = fullname;
2259 } else {
2260 lname = xmlBuildQName(localname, prefix, NULL, 0);
2264 * allocate the node
2266 if (ctxt->freeElems != NULL) {
2267 ret = ctxt->freeElems;
2268 ctxt->freeElems = ret->next;
2269 ctxt->freeElemsNr--;
2270 memset(ret, 0, sizeof(xmlNode));
2271 ret->doc = ctxt->myDoc;
2272 ret->type = XML_ELEMENT_NODE;
2274 if (ctxt->dictNames)
2275 ret->name = localname;
2276 else {
2277 if (lname == NULL)
2278 ret->name = xmlStrdup(localname);
2279 else
2280 ret->name = lname;
2281 if (ret->name == NULL) {
2282 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
2283 xmlFree(ret);
2284 return;
2287 if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
2288 xmlRegisterNodeDefaultValue(ret);
2289 } else {
2290 if (ctxt->dictNames)
2291 ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
2292 (xmlChar *) localname, NULL);
2293 else if (lname == NULL)
2294 ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
2295 else
2296 ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
2297 (xmlChar *) lname, NULL);
2298 if (ret == NULL) {
2299 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
2300 return;
2303 if (ctxt->linenumbers) {
2304 if (ctxt->input != NULL) {
2305 if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
2306 ret->line = ctxt->input->line;
2307 else
2308 ret->line = USHRT_MAX;
2312 if (parent == NULL) {
2313 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
2316 * Build the namespace list
2318 for (i = 0,j = 0;j < nb_namespaces;j++) {
2319 pref = namespaces[i++];
2320 uri = namespaces[i++];
2321 ns = xmlNewNs(NULL, uri, pref);
2322 if (ns != NULL) {
2323 if (last == NULL) {
2324 ret->nsDef = last = ns;
2325 } else {
2326 last->next = ns;
2327 last = ns;
2329 if ((URI != NULL) && (prefix == pref))
2330 ret->ns = ns;
2331 } else {
2333 * any out of memory error would already have been raised
2334 * but we can't be guaranteed it's the actual error due to the
2335 * API, best is to skip in this case
2337 continue;
2339 #ifdef LIBXML_VALID_ENABLED
2340 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
2341 ctxt->myDoc && ctxt->myDoc->intSubset) {
2342 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
2343 ret, prefix, ns, uri);
2345 #endif /* LIBXML_VALID_ENABLED */
2347 ctxt->nodemem = -1;
2350 * We are parsing a new node.
2352 if (nodePush(ctxt, ret) < 0) {
2353 xmlUnlinkNode(ret);
2354 xmlFreeNode(ret);
2355 return;
2359 * Link the child element
2361 if (parent != NULL) {
2362 if (parent->type == XML_ELEMENT_NODE) {
2363 xmlAddChild(parent, ret);
2364 } else {
2365 xmlAddSibling(parent, ret);
2370 * Insert the defaulted attributes from the DTD only if requested:
2372 if ((nb_defaulted != 0) &&
2373 ((ctxt->loadsubset & XML_COMPLETE_ATTRS) == 0))
2374 nb_attributes -= nb_defaulted;
2377 * Search the namespace if it wasn't already found
2378 * Note that, if prefix is NULL, this searches for the default Ns
2380 if ((URI != NULL) && (ret->ns == NULL)) {
2381 ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
2382 if ((ret->ns == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
2383 ret->ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
2385 if (ret->ns == NULL) {
2386 ns = xmlNewNs(ret, NULL, prefix);
2387 if (ns == NULL) {
2389 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
2390 return;
2392 if (prefix != NULL)
2393 xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
2394 "Namespace prefix %s was not found\n",
2395 prefix, NULL);
2396 else
2397 xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
2398 "Namespace default prefix was not found\n",
2399 NULL, NULL);
2404 * process all the other attributes
2406 if (nb_attributes > 0) {
2407 for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
2409 * Handle the rare case of an undefined attribute prefix
2411 if ((attributes[j+1] != NULL) && (attributes[j+2] == NULL)) {
2412 if (ctxt->dictNames) {
2413 const xmlChar *fullname;
2415 fullname = xmlDictQLookup(ctxt->dict, attributes[j+1],
2416 attributes[j]);
2417 if (fullname != NULL) {
2418 xmlSAX2AttributeNs(ctxt, fullname, NULL,
2419 attributes[j+3], attributes[j+4]);
2420 continue;
2422 } else {
2423 lname = xmlBuildQName(attributes[j], attributes[j+1],
2424 NULL, 0);
2425 if (lname != NULL) {
2426 xmlSAX2AttributeNs(ctxt, lname, NULL,
2427 attributes[j+3], attributes[j+4]);
2428 xmlFree(lname);
2429 continue;
2433 xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
2434 attributes[j+3], attributes[j+4]);
2438 #ifdef LIBXML_VALID_ENABLED
2440 * If it's the Document root, finish the DTD validation and
2441 * check the document root element for validity
2443 if ((ctxt->validate) &&
2444 ((ctxt->vctxt.flags & XML_VCTXT_DTD_VALIDATED) == 0)) {
2445 int chk;
2447 chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
2448 if (chk <= 0)
2449 ctxt->valid = 0;
2450 if (chk < 0)
2451 ctxt->wellFormed = 0;
2452 ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
2453 ctxt->vctxt.flags |= XML_VCTXT_DTD_VALIDATED;
2455 #endif /* LIBXML_VALID_ENABLED */
2459 * xmlSAX2EndElementNs:
2460 * @ctx: the user data (XML parser context)
2461 * @localname: the local name of the element
2462 * @prefix: the element namespace prefix if available
2463 * @URI: the element namespace name if available
2465 * SAX2 callback when an element end has been detected by the parser.
2466 * It provides the namespace information for the element.
2468 void
2469 xmlSAX2EndElementNs(void *ctx,
2470 const xmlChar * localname ATTRIBUTE_UNUSED,
2471 const xmlChar * prefix ATTRIBUTE_UNUSED,
2472 const xmlChar * URI ATTRIBUTE_UNUSED)
2474 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2476 if (ctx == NULL) return;
2477 ctxt->nodemem = -1;
2479 #ifdef LIBXML_VALID_ENABLED
2480 if (ctxt->validate && ctxt->wellFormed &&
2481 ctxt->myDoc && ctxt->myDoc->intSubset)
2482 ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
2483 ctxt->node);
2484 #endif /* LIBXML_VALID_ENABLED */
2487 * end of parsing of this node.
2489 nodePop(ctxt);
2493 * xmlSAX2Reference:
2494 * @ctx: the user data (XML parser context)
2495 * @name: The entity name
2497 * called when an entity xmlSAX2Reference is detected.
2499 void
2500 xmlSAX2Reference(void *ctx, const xmlChar *name)
2502 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2503 xmlNodePtr ret;
2505 if (ctx == NULL) return;
2506 #ifdef DEBUG_SAX
2507 xmlGenericError(xmlGenericErrorContext,
2508 "SAX.xmlSAX2Reference(%s)\n", name);
2509 #endif
2510 if (name[0] == '#')
2511 ret = xmlNewCharRef(ctxt->myDoc, name);
2512 else
2513 ret = xmlNewReference(ctxt->myDoc, name);
2514 #ifdef DEBUG_SAX_TREE
2515 xmlGenericError(xmlGenericErrorContext,
2516 "add xmlSAX2Reference %s to %s \n", name, ctxt->node->name);
2517 #endif
2518 if (xmlAddChild(ctxt->node, ret) == NULL) {
2519 xmlFreeNode(ret);
2524 * xmlSAX2Text:
2525 * @ctx: the user data (XML parser context)
2526 * @ch: a xmlChar string
2527 * @len: the number of xmlChar
2528 * @type: text or cdata
2530 * Append characters.
2532 static void
2533 xmlSAX2Text(xmlParserCtxtPtr ctxt, const xmlChar *ch, int len,
2534 xmlElementType type)
2536 xmlNodePtr lastChild;
2538 if (ctxt == NULL) return;
2539 #ifdef DEBUG_SAX
2540 xmlGenericError(xmlGenericErrorContext,
2541 "SAX.xmlSAX2Characters(%.30s, %d)\n", ch, len);
2542 #endif
2544 * Handle the data if any. If there is no child
2545 * add it as content, otherwise if the last child is text,
2546 * concatenate it, else create a new node of type text.
2549 if (ctxt->node == NULL) {
2550 #ifdef DEBUG_SAX_TREE
2551 xmlGenericError(xmlGenericErrorContext,
2552 "add chars: ctxt->node == NULL !\n");
2553 #endif
2554 return;
2556 lastChild = ctxt->node->last;
2557 #ifdef DEBUG_SAX_TREE
2558 xmlGenericError(xmlGenericErrorContext,
2559 "add chars to %s \n", ctxt->node->name);
2560 #endif
2563 * Here we needed an accelerator mechanism in case of very large
2564 * elements. Use an attribute in the structure !!!
2566 if (lastChild == NULL) {
2567 if (type == XML_TEXT_NODE)
2568 lastChild = xmlSAX2TextNode(ctxt, ch, len);
2569 else
2570 lastChild = xmlNewCDataBlock(ctxt->myDoc, ch, len);
2571 if (lastChild != NULL) {
2572 ctxt->node->children = lastChild;
2573 ctxt->node->last = lastChild;
2574 lastChild->parent = ctxt->node;
2575 lastChild->doc = ctxt->node->doc;
2576 ctxt->nodelen = len;
2577 ctxt->nodemem = len + 1;
2578 } else {
2579 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
2580 return;
2582 } else {
2583 int coalesceText = (lastChild != NULL) &&
2584 (lastChild->type == type) &&
2585 ((type != XML_TEXT_NODE) ||
2586 (lastChild->name == xmlStringText));
2587 if ((coalesceText) && (ctxt->nodemem != 0)) {
2589 * The whole point of maintaining nodelen and nodemem,
2590 * xmlTextConcat is too costly, i.e. compute length,
2591 * reallocate a new buffer, move data, append ch. Here
2592 * We try to minimize realloc() uses and avoid copying
2593 * and recomputing length over and over.
2595 if (lastChild->content == (xmlChar *)&(lastChild->properties)) {
2596 lastChild->content = xmlStrdup(lastChild->content);
2597 lastChild->properties = NULL;
2598 } else if ((ctxt->nodemem == ctxt->nodelen + 1) &&
2599 (xmlDictOwns(ctxt->dict, lastChild->content))) {
2600 lastChild->content = xmlStrdup(lastChild->content);
2602 if (lastChild->content == NULL) {
2603 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: xmlStrdup returned NULL");
2604 return;
2606 if (ctxt->nodelen > INT_MAX - len) {
2607 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters overflow prevented");
2608 return;
2610 if ((ctxt->nodelen + len > XML_MAX_TEXT_LENGTH) &&
2611 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
2612 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: huge text node");
2613 return;
2615 if (ctxt->nodelen + len >= ctxt->nodemem) {
2616 xmlChar *newbuf;
2617 int size;
2619 size = ctxt->nodemem > INT_MAX - len ?
2620 INT_MAX :
2621 ctxt->nodemem + len;
2622 size = size > INT_MAX / 2 ? INT_MAX : size * 2;
2623 newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
2624 if (newbuf == NULL) {
2625 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
2626 return;
2628 ctxt->nodemem = size;
2629 lastChild->content = newbuf;
2631 memcpy(&lastChild->content[ctxt->nodelen], ch, len);
2632 ctxt->nodelen += len;
2633 lastChild->content[ctxt->nodelen] = 0;
2634 } else if (coalesceText) {
2635 if (xmlTextConcat(lastChild, ch, len)) {
2636 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
2638 if (ctxt->node->children != NULL) {
2639 ctxt->nodelen = xmlStrlen(lastChild->content);
2640 ctxt->nodemem = ctxt->nodelen + 1;
2642 } else {
2643 /* Mixed content, first time */
2644 if (type == XML_TEXT_NODE) {
2645 lastChild = xmlSAX2TextNode(ctxt, ch, len);
2646 if (lastChild != NULL)
2647 lastChild->doc = ctxt->myDoc;
2648 } else
2649 lastChild = xmlNewCDataBlock(ctxt->myDoc, ch, len);
2650 if (lastChild != NULL) {
2651 xmlAddChild(ctxt->node, lastChild);
2652 if (ctxt->node->children != NULL) {
2653 ctxt->nodelen = len;
2654 ctxt->nodemem = len + 1;
2662 * xmlSAX2Characters:
2663 * @ctx: the user data (XML parser context)
2664 * @ch: a xmlChar string
2665 * @len: the number of xmlChar
2667 * receiving some chars from the parser.
2669 void
2670 xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
2672 xmlSAX2Text((xmlParserCtxtPtr) ctx, ch, len, XML_TEXT_NODE);
2676 * xmlSAX2IgnorableWhitespace:
2677 * @ctx: the user data (XML parser context)
2678 * @ch: a xmlChar string
2679 * @len: the number of xmlChar
2681 * receiving some ignorable whitespaces from the parser.
2682 * UNUSED: by default the DOM building will use xmlSAX2Characters
2684 void
2685 xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED)
2687 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
2688 #ifdef DEBUG_SAX
2689 xmlGenericError(xmlGenericErrorContext,
2690 "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch, len);
2691 #endif
2695 * xmlSAX2ProcessingInstruction:
2696 * @ctx: the user data (XML parser context)
2697 * @target: the target name
2698 * @data: the PI data's
2700 * A processing instruction has been parsed.
2702 void
2703 xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target,
2704 const xmlChar *data)
2706 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2707 xmlNodePtr ret;
2708 xmlNodePtr parent;
2710 if (ctx == NULL) return;
2711 parent = ctxt->node;
2712 #ifdef DEBUG_SAX
2713 xmlGenericError(xmlGenericErrorContext,
2714 "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target, data);
2715 #endif
2717 ret = xmlNewDocPI(ctxt->myDoc, target, data);
2718 if (ret == NULL) return;
2720 if (ctxt->linenumbers) {
2721 if (ctxt->input != NULL) {
2722 if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
2723 ret->line = ctxt->input->line;
2724 else
2725 ret->line = USHRT_MAX;
2728 if (ctxt->inSubset == 1) {
2729 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
2730 return;
2731 } else if (ctxt->inSubset == 2) {
2732 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
2733 return;
2735 if (parent == NULL) {
2736 #ifdef DEBUG_SAX_TREE
2737 xmlGenericError(xmlGenericErrorContext,
2738 "Setting PI %s as root\n", target);
2739 #endif
2740 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
2741 return;
2743 if (parent->type == XML_ELEMENT_NODE) {
2744 #ifdef DEBUG_SAX_TREE
2745 xmlGenericError(xmlGenericErrorContext,
2746 "adding PI %s child to %s\n", target, parent->name);
2747 #endif
2748 xmlAddChild(parent, ret);
2749 } else {
2750 #ifdef DEBUG_SAX_TREE
2751 xmlGenericError(xmlGenericErrorContext,
2752 "adding PI %s sibling to ", target);
2753 xmlDebugDumpOneNode(stderr, parent, 0);
2754 #endif
2755 xmlAddSibling(parent, ret);
2760 * xmlSAX2Comment:
2761 * @ctx: the user data (XML parser context)
2762 * @value: the xmlSAX2Comment content
2764 * A xmlSAX2Comment has been parsed.
2766 void
2767 xmlSAX2Comment(void *ctx, const xmlChar *value)
2769 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2770 xmlNodePtr ret;
2771 xmlNodePtr parent;
2773 if (ctx == NULL) return;
2774 parent = ctxt->node;
2775 #ifdef DEBUG_SAX
2776 xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Comment(%s)\n", value);
2777 #endif
2778 ret = xmlNewDocComment(ctxt->myDoc, value);
2779 if (ret == NULL) return;
2780 if (ctxt->linenumbers) {
2781 if (ctxt->input != NULL) {
2782 if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
2783 ret->line = ctxt->input->line;
2784 else
2785 ret->line = USHRT_MAX;
2789 if (ctxt->inSubset == 1) {
2790 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
2791 return;
2792 } else if (ctxt->inSubset == 2) {
2793 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
2794 return;
2796 if (parent == NULL) {
2797 #ifdef DEBUG_SAX_TREE
2798 xmlGenericError(xmlGenericErrorContext,
2799 "Setting xmlSAX2Comment as root\n");
2800 #endif
2801 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
2802 return;
2804 if (parent->type == XML_ELEMENT_NODE) {
2805 #ifdef DEBUG_SAX_TREE
2806 xmlGenericError(xmlGenericErrorContext,
2807 "adding xmlSAX2Comment child to %s\n", parent->name);
2808 #endif
2809 xmlAddChild(parent, ret);
2810 } else {
2811 #ifdef DEBUG_SAX_TREE
2812 xmlGenericError(xmlGenericErrorContext,
2813 "adding xmlSAX2Comment sibling to ");
2814 xmlDebugDumpOneNode(stderr, parent, 0);
2815 #endif
2816 xmlAddSibling(parent, ret);
2821 * xmlSAX2CDataBlock:
2822 * @ctx: the user data (XML parser context)
2823 * @value: The pcdata content
2824 * @len: the block length
2826 * called when a pcdata block has been parsed
2828 void
2829 xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len)
2831 xmlSAX2Text((xmlParserCtxtPtr) ctx, value, len, XML_CDATA_SECTION_NODE);
2834 static int xmlSAX2DefaultVersionValue = 2;
2836 #ifdef LIBXML_SAX1_ENABLED
2838 * xmlSAXDefaultVersion:
2839 * @version: the version, 1 or 2
2841 * DEPRECATED: Use parser option XML_PARSE_SAX1.
2843 * Set the default version of SAX used globally by the library.
2844 * By default, during initialization the default is set to 2.
2845 * Note that it is generally a better coding style to use
2846 * xmlSAXVersion() to set up the version explicitly for a given
2847 * parsing context.
2849 * Returns the previous value in case of success and -1 in case of error.
2852 xmlSAXDefaultVersion(int version)
2854 int ret = xmlSAX2DefaultVersionValue;
2856 if ((version != 1) && (version != 2))
2857 return(-1);
2858 xmlSAX2DefaultVersionValue = version;
2859 return(ret);
2861 #endif /* LIBXML_SAX1_ENABLED */
2864 * xmlSAXVersion:
2865 * @hdlr: the SAX handler
2866 * @version: the version, 1 or 2
2868 * Initialize the default XML SAX handler according to the version
2870 * Returns 0 in case of success and -1 in case of error.
2873 xmlSAXVersion(xmlSAXHandler *hdlr, int version)
2875 if (hdlr == NULL) return(-1);
2876 if (version == 2) {
2877 hdlr->startElement = NULL;
2878 hdlr->endElement = NULL;
2879 hdlr->startElementNs = xmlSAX2StartElementNs;
2880 hdlr->endElementNs = xmlSAX2EndElementNs;
2881 hdlr->serror = NULL;
2882 hdlr->initialized = XML_SAX2_MAGIC;
2883 #ifdef LIBXML_SAX1_ENABLED
2884 } else if (version == 1) {
2885 hdlr->startElement = xmlSAX2StartElement;
2886 hdlr->endElement = xmlSAX2EndElement;
2887 hdlr->initialized = 1;
2888 #endif /* LIBXML_SAX1_ENABLED */
2889 } else
2890 return(-1);
2891 hdlr->internalSubset = xmlSAX2InternalSubset;
2892 hdlr->externalSubset = xmlSAX2ExternalSubset;
2893 hdlr->isStandalone = xmlSAX2IsStandalone;
2894 hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
2895 hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
2896 hdlr->resolveEntity = xmlSAX2ResolveEntity;
2897 hdlr->getEntity = xmlSAX2GetEntity;
2898 hdlr->getParameterEntity = xmlSAX2GetParameterEntity;
2899 hdlr->entityDecl = xmlSAX2EntityDecl;
2900 hdlr->attributeDecl = xmlSAX2AttributeDecl;
2901 hdlr->elementDecl = xmlSAX2ElementDecl;
2902 hdlr->notationDecl = xmlSAX2NotationDecl;
2903 hdlr->unparsedEntityDecl = xmlSAX2UnparsedEntityDecl;
2904 hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
2905 hdlr->startDocument = xmlSAX2StartDocument;
2906 hdlr->endDocument = xmlSAX2EndDocument;
2907 hdlr->reference = xmlSAX2Reference;
2908 hdlr->characters = xmlSAX2Characters;
2909 hdlr->cdataBlock = xmlSAX2CDataBlock;
2910 hdlr->ignorableWhitespace = xmlSAX2Characters;
2911 hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
2912 hdlr->comment = xmlSAX2Comment;
2913 hdlr->warning = xmlParserWarning;
2914 hdlr->error = xmlParserError;
2915 hdlr->fatalError = xmlParserError;
2917 return(0);
2921 * xmlSAX2InitDefaultSAXHandler:
2922 * @hdlr: the SAX handler
2923 * @warning: flag if non-zero sets the handler warning procedure
2925 * Initialize the default XML SAX2 handler
2927 void
2928 xmlSAX2InitDefaultSAXHandler(xmlSAXHandler *hdlr, int warning)
2930 if ((hdlr == NULL) || (hdlr->initialized != 0))
2931 return;
2933 xmlSAXVersion(hdlr, xmlSAX2DefaultVersionValue);
2934 if (warning == 0)
2935 hdlr->warning = NULL;
2936 else
2937 hdlr->warning = xmlParserWarning;
2941 * xmlDefaultSAXHandlerInit:
2943 * DEPRECATED: This function is a no-op. Call xmlInitParser to
2944 * initialize the library.
2946 * Initialize the default SAX2 handler
2948 void
2949 xmlDefaultSAXHandlerInit(void)
2953 #ifdef LIBXML_HTML_ENABLED
2956 * xmlSAX2InitHtmlDefaultSAXHandler:
2957 * @hdlr: the SAX handler
2959 * Initialize the default HTML SAX2 handler
2961 void
2962 xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr)
2964 if ((hdlr == NULL) || (hdlr->initialized != 0))
2965 return;
2967 hdlr->internalSubset = xmlSAX2InternalSubset;
2968 hdlr->externalSubset = NULL;
2969 hdlr->isStandalone = NULL;
2970 hdlr->hasInternalSubset = NULL;
2971 hdlr->hasExternalSubset = NULL;
2972 hdlr->resolveEntity = NULL;
2973 hdlr->getEntity = xmlSAX2GetEntity;
2974 hdlr->getParameterEntity = NULL;
2975 hdlr->entityDecl = NULL;
2976 hdlr->attributeDecl = NULL;
2977 hdlr->elementDecl = NULL;
2978 hdlr->notationDecl = NULL;
2979 hdlr->unparsedEntityDecl = NULL;
2980 hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
2981 hdlr->startDocument = xmlSAX2StartDocument;
2982 hdlr->endDocument = xmlSAX2EndDocument;
2983 hdlr->startElement = xmlSAX2StartElement;
2984 hdlr->endElement = xmlSAX2EndElement;
2985 hdlr->reference = NULL;
2986 hdlr->characters = xmlSAX2Characters;
2987 hdlr->cdataBlock = xmlSAX2CDataBlock;
2988 hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
2989 hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
2990 hdlr->comment = xmlSAX2Comment;
2991 hdlr->warning = xmlParserWarning;
2992 hdlr->error = xmlParserError;
2993 hdlr->fatalError = xmlParserError;
2995 hdlr->initialized = 1;
2999 * htmlDefaultSAXHandlerInit:
3001 * DEPRECATED: This function is a no-op. Call xmlInitParser to
3002 * initialize the library.
3004 void
3005 htmlDefaultSAXHandlerInit(void)
3009 #endif /* LIBXML_HTML_ENABLED */