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>
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 */
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
49 xmlGenericError(xmlGenericErrorContext, \
50 "Unimplemented block at %s:%d\n", \
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";
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
,
72 msg
, (const char *) str1
, NULL
);
73 ctxt
->errNo
= XML_ERR_NO_MEMORY
;
74 ctxt
->instate
= XML_PARSER_EOF
;
77 __xmlRaiseError(schannel
,
79 ctxt
, NULL
, XML_FROM_PARSER
, XML_ERR_NO_MEMORY
,
80 XML_ERR_ERROR
, NULL
, 0, (const char *) str1
,
82 msg
, (const char *) str1
, NULL
);
88 * @ctxt: an XML validation parser context
89 * @error: the error number
90 * @msg: the error message
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
))
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
);
117 __xmlRaiseError(schannel
,
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
);
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
))
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
);
150 ctxt
->wellFormed
= 0;
152 if (ctxt
->recovery
== 0)
153 ctxt
->disableSAX
= 1;
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
))
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
);
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
))
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 *
215 xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED
)
217 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
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 *
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.
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.
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 ?
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
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
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.
328 xmlSAX2InternalSubset(void *ctx
, const xmlChar
*name
,
329 const xmlChar
*ExternalID
, const xmlChar
*SystemID
)
331 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
333 if (ctx
== NULL
) return;
335 xmlGenericError(xmlGenericErrorContext
,
336 "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n",
337 name
, ExternalID
, SystemID
);
340 if (ctxt
->myDoc
== NULL
)
342 dtd
= xmlGetIntSubset(ctxt
->myDoc
);
346 xmlUnlinkNode((xmlNodePtr
) 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.
366 xmlSAX2ExternalSubset(void *ctx
, const xmlChar
*name
,
367 const xmlChar
*ExternalID
, const xmlChar
*SystemID
)
369 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
370 if (ctx
== NULL
) return;
372 xmlGenericError(xmlGenericErrorContext
,
373 "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n",
374 name
, ExternalID
, SystemID
);
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
;
385 xmlParserInputPtr
*oldinputTab
;
386 xmlParserInputPtr input
= NULL
;
389 const xmlChar
*oldencoding
;
391 unsigned long consumed
;
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
,
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
;
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
);
450 input
->base
= ctxt
->input
->cur
;
451 input
->cur
= ctxt
->input
->cur
;
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)
466 consumed
= ctxt
->input
->consumed
;
467 buffered
= ctxt
->input
->cur
- ctxt
->input
->base
;
468 if (buffered
> ULONG_MAX
- consumed
)
469 consumed
= ULONG_MAX
;
471 consumed
+= buffered
;
472 if (consumed
> ULONG_MAX
- ctxt
->sizeentities
)
473 ctxt
->sizeentities
= ULONG_MAX
;
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.
513 xmlSAX2ResolveEntity(void *ctx
, const xmlChar
*publicId
, const xmlChar
*systemId
)
515 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
516 xmlParserInputPtr ret
;
518 const char *base
= NULL
;
520 if (ctx
== NULL
) return(NULL
);
521 if (ctxt
->input
!= NULL
)
522 base
= ctxt
->input
->filename
;
524 base
= ctxt
->directory
;
526 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
529 xmlGenericError(xmlGenericErrorContext
,
530 "SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId
, systemId
);
533 ret
= xmlLoadExternalEntity((const char *) URI
,
534 (const char *) publicId
, ctxt
);
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.
550 xmlSAX2GetEntity(void *ctx
, const xmlChar
*name
)
552 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
553 xmlEntityPtr ret
= NULL
;
555 if (ctx
== NULL
) return(NULL
);
557 xmlGenericError(xmlGenericErrorContext
,
558 "SAX.xmlSAX2GetEntity(%s)\n", name
);
561 if (ctxt
->inSubset
== 0) {
562 ret
= xmlGetPredefinedEntity(name
);
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;
572 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
574 ctxt
->myDoc
->standalone
= 0;
575 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
577 xmlFatalErrMsg(ctxt
, XML_ERR_NOT_STANDALONE
,
578 "Entity(%s) document marked standalone but requires external subset\n",
581 ctxt
->myDoc
->standalone
= 1;
585 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
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.
600 xmlSAX2GetParameterEntity(void *ctx
, const xmlChar
*name
)
602 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
605 if (ctx
== NULL
) return(NULL
);
607 xmlGenericError(xmlGenericErrorContext
,
608 "SAX.xmlSAX2GetParameterEntity(%s)\n", name
);
611 ret
= xmlGetParameterEntity(ctxt
->myDoc
, name
);
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
628 xmlSAX2EntityDecl(void *ctx
, const xmlChar
*name
, int type
,
629 const xmlChar
*publicId
, const xmlChar
*systemId
, xmlChar
*content
)
632 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
634 if (ctx
== NULL
) return;
636 xmlGenericError(xmlGenericErrorContext
,
637 "SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n",
638 name
, type
, publicId
, systemId
, content
);
640 if (ctxt
->inSubset
== 1) {
641 ent
= xmlAddDocEntity(ctxt
->myDoc
, name
, type
, publicId
,
643 if ((ent
== NULL
) && (ctxt
->pedantic
))
644 xmlWarnMsg(ctxt
, XML_WAR_ENTITY_REDEFINED
,
645 "Entity(%s) already defined in the internal subset\n",
647 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
649 const char *base
= NULL
;
651 if (ctxt
->input
!= NULL
)
652 base
= ctxt
->input
->filename
;
654 base
= ctxt
->directory
;
656 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
659 } else if (ctxt
->inSubset
== 2) {
660 ent
= xmlAddDtdEntity(ctxt
->myDoc
, name
, type
, publicId
,
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
)) {
668 const char *base
= NULL
;
670 if (ctxt
->input
!= NULL
)
671 base
= ctxt
->input
->filename
;
673 base
= ctxt
->directory
;
675 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
679 xmlFatalErrMsg(ctxt
, XML_ERR_ENTITY_PROCESSING
,
680 "SAX.xmlSAX2EntityDecl(%s) called while not in subset\n",
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
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. */
709 if ((ctxt
== NULL
) || (ctxt
->myDoc
== NULL
))
713 xmlGenericError(xmlGenericErrorContext
,
714 "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n",
715 elem
, fullname
, type
, def
, defaultValue
);
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
);
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
);
739 xmlFatalErrMsg(ctxt
, XML_ERR_INTERNAL_ERROR
,
740 "SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n",
743 xmlFreeEnumeration(tree
);
746 #ifdef LIBXML_VALID_ENABLED
747 if (ctxt
->vctxt
.valid
== 0)
749 if ((attr
!= NULL
) && (ctxt
->validate
) && (ctxt
->wellFormed
) &&
750 (ctxt
->myDoc
->intSubset
!= NULL
))
751 ctxt
->valid
&= xmlValidateAttributeDecl(&ctxt
->vctxt
, ctxt
->myDoc
,
753 #endif /* LIBXML_VALID_ENABLED */
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
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. */
779 if ((ctxt
== NULL
) || (ctxt
->myDoc
== NULL
))
783 xmlGenericError(xmlGenericErrorContext
,
784 "SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name
, type
);
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
);
794 xmlFatalErrMsg(ctxt
, XML_ERR_INTERNAL_ERROR
,
795 "SAX.xmlSAX2ElementDecl(%s) called while not in subset\n",
799 #ifdef LIBXML_VALID_ENABLED
802 if (ctxt
->validate
&& ctxt
->wellFormed
&&
803 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
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.
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. */
828 if ((ctxt
== NULL
) || (ctxt
->myDoc
== NULL
))
832 xmlGenericError(xmlGenericErrorContext
,
833 "SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name
, publicId
, systemId
);
836 if ((publicId
== NULL
) && (systemId
== NULL
)) {
837 xmlFatalErrMsg(ctxt
, XML_ERR_NOTATION_PROCESSING
,
838 "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n",
841 } else if (ctxt
->inSubset
== 1)
842 nota
= xmlAddNotationDecl(&ctxt
->vctxt
, ctxt
->myDoc
->intSubset
, name
,
844 else if (ctxt
->inSubset
== 2)
845 nota
= xmlAddNotationDecl(&ctxt
->vctxt
, ctxt
->myDoc
->extSubset
, name
,
848 xmlFatalErrMsg(ctxt
, XML_ERR_NOTATION_PROCESSING
,
849 "SAX.xmlSAX2NotationDecl(%s) called while not in subset\n",
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
,
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
873 xmlSAX2UnparsedEntityDecl(void *ctx
, const xmlChar
*name
,
874 const xmlChar
*publicId
, const xmlChar
*systemId
,
875 const xmlChar
*notationName
)
878 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
879 if (ctx
== NULL
) return;
881 xmlGenericError(xmlGenericErrorContext
,
882 "SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n",
883 name
, publicId
, systemId
, notationName
);
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
)) {
895 const char *base
= NULL
;
897 if (ctxt
->input
!= NULL
)
898 base
= ctxt
->input
->filename
;
900 base
= ctxt
->directory
;
902 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
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
)) {
915 const char *base
= NULL
;
917 if (ctxt
->input
!= NULL
)
918 base
= ctxt
->input
->filename
;
920 base
= ctxt
->directory
;
922 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
926 xmlFatalErrMsg(ctxt
, XML_ERR_INTERNAL_ERROR
,
927 "SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n",
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.
941 xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED
, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED
)
943 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
945 xmlGenericError(xmlGenericErrorContext
,
946 "SAX.xmlSAX2SetDocumentLocator()\n");
951 * xmlSAX2StartDocument:
952 * @ctx: the user data (XML parser context)
954 * called when the document start being processed.
957 xmlSAX2StartDocument(void *ctx
)
959 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
962 if (ctx
== NULL
) return;
965 xmlGenericError(xmlGenericErrorContext
,
966 "SAX.xmlSAX2StartDocument()\n");
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");
976 ctxt
->myDoc
->properties
= XML_DOC_HTML
;
977 ctxt
->myDoc
->parseFlags
= ctxt
->options
;
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;
987 doc
= ctxt
->myDoc
= xmlNewDoc(ctxt
->version
);
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
);
996 doc
->encoding
= NULL
;
997 doc
->standalone
= ctxt
->standalone
;
999 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartDocument");
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.
1022 xmlSAX2EndDocument(void *ctx
)
1024 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1026 xmlGenericError(xmlGenericErrorContext
,
1027 "SAX.xmlSAX2EndDocument()\n");
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)
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
))
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
1095 xmlSAX2AttributeInternal(void *ctx
, const xmlChar
*fullname
,
1096 const xmlChar
*value
, const xmlChar
*prefix ATTRIBUTE_UNUSED
)
1098 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1106 name
= xmlStrdup(fullname
);
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",
1120 xmlNsWarnMsg(ctxt
, XML_WAR_NS_COLUMN
,
1121 "Avoid attribute ending with ':' like '%s'\n",
1128 name
= xmlStrdup(fullname
);
1132 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1138 #ifdef LIBXML_HTML_ENABLED
1140 (value
== NULL
) && (htmlIsBooleanAttr(fullname
))) {
1141 nval
= xmlStrdup(fullname
);
1142 value
= (const xmlChar
*) nval
;
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
,
1156 if (ctxt
->vctxt
.valid
!= 1) {
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)) {
1175 /* Avoid unused variable warning if features are disabled. */
1178 if (!ctxt
->replaceEntities
) {
1180 val
= xmlStringDecodeEntities(ctxt
, value
, XML_SUBSTITUTE_REF
,
1184 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1192 val
= (xmlChar
*) value
;
1198 uri
= xmlParseURI((const char *)val
);
1200 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
1201 ctxt
->sax
->warning(ctxt
->userData
,
1202 "xmlns: %s not a valid URI\n", val
);
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
);
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 */
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)) {
1240 /* Avoid unused variable warning if features are disabled. */
1243 if (!ctxt
->replaceEntities
) {
1245 val
= xmlStringDecodeEntities(ctxt
, value
, XML_SUBSTITUTE_REF
,
1249 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1258 val
= (xmlChar
*) value
;
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)) {
1268 uri
= xmlParseURI((const char *)val
);
1270 xmlNsWarnMsg(ctxt
, XML_WAR_NS_URI
,
1271 "xmlns:%s: %s not a valid URI\n", name
, value
);
1273 if (uri
->scheme
== NULL
) {
1274 xmlNsWarnMsg(ctxt
, XML_WAR_NS_URI_RELATIVE
,
1275 "xmlns:%s: URI %s is not absolute\n", name
, value
);
1281 /* a standard namespace definition */
1282 nsret
= xmlNewNs(ctxt
->node
, val
, name
);
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 */
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",
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;
1336 /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
1337 ret
= xmlNewNsPropEatName(ctxt
->node
, namespace, name
, NULL
);
1341 if ((ctxt
->replaceEntities
== 0) && (!ctxt
->html
)) {
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
)
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
) {
1371 val
= xmlStringDecodeEntities(ctxt
, value
, XML_SUBSTITUTE_REF
,
1376 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
1377 ctxt
->myDoc
, ctxt
->node
, ret
, value
);
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
) {
1393 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
1394 ctxt
->myDoc
, ctxt
->node
, ret
, val
);
1398 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
, ctxt
->myDoc
,
1399 ctxt
->node
, ret
, value
);
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
);
1441 * xmlCheckDefaultedAttributes:
1443 * Check defaulted attributes from the DTD
1446 xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt
, const xmlChar
*name
,
1447 const xmlChar
*prefix
, const xmlChar
**atts
) {
1448 xmlElementPtr elemDecl
;
1453 elemDecl
= xmlGetDtdQElementDesc(ctxt
->myDoc
->intSubset
, name
, prefix
);
1454 if (elemDecl
== NULL
) {
1455 elemDecl
= xmlGetDtdQElementDesc(ctxt
->myDoc
->extSubset
, name
, prefix
);
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
) &&
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
)) {
1480 if (attr
->prefix
!= NULL
) {
1481 fulln
= xmlStrdup(attr
->prefix
);
1482 fulln
= xmlStrcat(fulln
, BAD_CAST
":");
1483 fulln
= xmlStrcat(fulln
, attr
->name
);
1485 fulln
= xmlStrdup(attr
->name
);
1487 if (fulln
== NULL
) {
1488 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1493 * Check that the attribute is not declared in the
1500 while (att
!= NULL
) {
1501 if (xmlStrEqual(att
, fulln
))
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
);
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
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
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
,
1548 if ((tst
== attr
) || (tst
== NULL
)) {
1552 fulln
= xmlBuildQName(attr
->name
, attr
->prefix
, fn
, 50);
1553 if (fulln
== NULL
) {
1554 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1559 * Check that the attribute is not declared in the
1566 while (att
!= NULL
) {
1567 if (xmlStrEqual(att
, fulln
))
1574 xmlSAX2AttributeInternal(ctxt
, fulln
,
1575 attr
->defaultValue
, prefix
);
1577 if ((fulln
!= fn
) && (fulln
!= attr
->name
))
1584 if (internal
== 1) {
1585 elemDecl
= xmlGetDtdQElementDesc(ctxt
->myDoc
->extSubset
,
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.
1602 xmlSAX2StartElement(void *ctx
, const xmlChar
*fullname
, const xmlChar
**atts
)
1604 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1611 const xmlChar
*value
;
1614 if ((ctx
== NULL
) || (fullname
== NULL
) || (ctxt
->myDoc
== NULL
)) return;
1615 parent
= ctxt
->node
;
1617 xmlGenericError(xmlGenericErrorContext
,
1618 "SAX.xmlSAX2StartElement(%s)\n", fullname
);
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
);
1637 name
= xmlStrdup(fullname
);
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
);
1654 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1657 if (ctxt
->myDoc
->children
== NULL
) {
1658 #ifdef DEBUG_SAX_TREE
1659 xmlGenericError(xmlGenericErrorContext
, "Setting %s as root\n", name
);
1661 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
1662 } else if (parent
== NULL
) {
1663 parent
= ctxt
->myDoc
->children
;
1666 if (ctxt
->linenumbers
) {
1667 if (ctxt
->input
!= NULL
) {
1668 if ((unsigned) ctxt
->input
->line
< (unsigned) USHRT_MAX
)
1669 ret
->line
= ctxt
->input
->line
;
1671 ret
->line
= USHRT_MAX
;
1676 * We are parsing a new node.
1678 #ifdef DEBUG_SAX_TREE
1679 xmlGenericError(xmlGenericErrorContext
, "pushing(%s)\n", name
);
1681 if (nodePush(ctxt
, ret
) < 0) {
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
);
1698 xmlAddChild(parent
, ret
);
1700 #ifdef DEBUG_SAX_TREE
1701 xmlGenericError(xmlGenericErrorContext
,
1702 "adding sibling %s to ", name
);
1703 xmlDebugDumpOneNode(stderr
, parent
, 0);
1705 xmlAddSibling(parent
, ret
);
1711 * Insert all the defaulted attributes from the DTD especially
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"
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
);
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",
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
)))
1760 * process all the other attributes
1767 while (att
!= NULL
) {
1768 xmlSAX2AttributeInternal(ctxt
, att
, value
, NULL
);
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
);
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)) {
1796 chk
= xmlValidateDtdFinal(&ctxt
->vctxt
, ctxt
->myDoc
);
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 */
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.
1819 xmlSAX2EndElement(void *ctx
, const xmlChar
*name ATTRIBUTE_UNUSED
)
1821 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1824 if (ctx
== NULL
) return;
1828 xmlGenericError(xmlGenericErrorContext
, "SAX.xmlSAX2EndElement(NULL)\n");
1830 xmlGenericError(xmlGenericErrorContext
, "SAX.xmlSAX2EndElement(%s)\n", name
);
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
,
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
);
1851 #endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLED || LIBXML_LEGACY_ENABLED */
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
1864 xmlSAX2TextNode(xmlParserCtxtPtr ctxt
, const xmlChar
*str
, int len
) {
1866 const xmlChar
*intern
= NULL
;
1871 if (ctxt
->freeElems
!= NULL
) {
1872 ret
= ctxt
->freeElems
;
1873 ctxt
->freeElems
= ret
->next
;
1874 ctxt
->freeElemsNr
--;
1876 ret
= (xmlNodePtr
) xmlMalloc(sizeof(xmlNode
));
1879 xmlErrMemory(ctxt
, "xmlSAX2Characters");
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
);
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] != '!')) {
1904 for (i
= 1;i
< len
;i
++) {
1905 if (!IS_BLANK_CH(str
[i
])) goto skip
;
1907 intern
= xmlDictLookup(ctxt
->dict
, str
, len
);
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");
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
;
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
);
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
1953 xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt
, const xmlChar
*str
,
1954 const xmlChar
*end
) {
1965 ret
= xmlStringLenDecodeEntities(ctxt
, str
, end
- str
,
1966 XML_SUBSTITUTE_REF
, 0,0,0);
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
1987 xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt
,
1988 const xmlChar
* localname
,
1989 const xmlChar
* prefix
,
1990 const xmlChar
* value
,
1991 const xmlChar
* valueend
)
1994 xmlNsPtr
namespace = NULL
;
1995 xmlChar
*dup
= NULL
;
1998 * Note: if prefix == NULL, the attribute is not in the default namespace
2001 namespace = xmlSearchNs(ctxt
->myDoc
, ctxt
->node
, prefix
);
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
;
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
;
2026 xmlAttrPtr prev
= ctxt
->node
->properties
;
2028 while (prev
->next
!= NULL
) prev
= prev
->next
;
2033 if ((__xmlRegisterCallbacks
) && (xmlRegisterNodeDefaultValue
))
2034 xmlRegisterNodeDefaultValue((xmlNodePtr
)ret
);
2036 if (ctxt
->dictNames
)
2037 ret
= xmlNewNsPropEatName(ctxt
->node
, namespace,
2038 (xmlChar
*) localname
, NULL
);
2040 ret
= xmlNewNsProp(ctxt
->node
, namespace, localname
, NULL
);
2042 xmlErrMemory(ctxt
, "xmlSAX2AttributeNs");
2047 if ((ctxt
->replaceEntities
== 0) && (!ctxt
->html
)) {
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
;
2060 tmp
->doc
= ret
->doc
;
2061 tmp
->parent
= (xmlNodePtr
) ret
;
2064 ret
->children
= xmlStringLenGetNodeList(ctxt
->myDoc
, value
,
2066 tmp
= ret
->children
;
2067 while (tmp
!= NULL
) {
2068 tmp
->doc
= ret
->doc
;
2069 tmp
->parent
= (xmlNodePtr
) ret
;
2070 if (tmp
->next
== NULL
)
2075 } else if (value
!= NULL
) {
2078 tmp
= xmlSAX2TextNode(ctxt
, value
, valueend
- value
);
2079 ret
->children
= tmp
;
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
);
2097 if (*valueend
== 0) {
2098 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2099 ctxt
->myDoc
, ctxt
->node
, ret
, value
);
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
);
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
) {
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)
2133 if ((fullname
!= fn
) && (fullname
!= localname
))
2135 if (nvalnorm
!= NULL
) {
2142 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2143 ctxt
->myDoc
, ctxt
->node
, ret
, dup
);
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
);
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
);
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
);
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)
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.
2215 xmlSAX2StartElementNs(void *ctx
,
2216 const xmlChar
*localname
,
2217 const xmlChar
*prefix
,
2220 const xmlChar
**namespaces
,
2223 const xmlChar
**attributes
)
2225 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2228 xmlNsPtr last
= NULL
, ns
;
2229 const xmlChar
*uri
, *pref
;
2230 xmlChar
*lname
= NULL
;
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
);
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
;
2260 lname
= xmlBuildQName(localname
, prefix
, NULL
, 0);
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
;
2278 ret
->name
= xmlStrdup(localname
);
2281 if (ret
->name
== NULL
) {
2282 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2287 if ((__xmlRegisterCallbacks
) && (xmlRegisterNodeDefaultValue
))
2288 xmlRegisterNodeDefaultValue(ret
);
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
);
2296 ret
= xmlNewDocNodeEatName(ctxt
->myDoc
, NULL
,
2297 (xmlChar
*) lname
, NULL
);
2299 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2303 if (ctxt
->linenumbers
) {
2304 if (ctxt
->input
!= NULL
) {
2305 if ((unsigned) ctxt
->input
->line
< (unsigned) USHRT_MAX
)
2306 ret
->line
= ctxt
->input
->line
;
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
);
2324 ret
->nsDef
= last
= ns
;
2329 if ((URI
!= NULL
) && (prefix
== pref
))
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
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 */
2350 * We are parsing a new node.
2352 if (nodePush(ctxt
, ret
) < 0) {
2359 * Link the child element
2361 if (parent
!= NULL
) {
2362 if (parent
->type
== XML_ELEMENT_NODE
) {
2363 xmlAddChild(parent
, ret
);
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
);
2389 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2393 xmlNsWarnMsg(ctxt
, XML_NS_ERR_UNDEFINED_NAMESPACE
,
2394 "Namespace prefix %s was not found\n",
2397 xmlNsWarnMsg(ctxt
, XML_NS_ERR_UNDEFINED_NAMESPACE
,
2398 "Namespace default prefix was not found\n",
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],
2417 if (fullname
!= NULL
) {
2418 xmlSAX2AttributeNs(ctxt
, fullname
, NULL
,
2419 attributes
[j
+3], attributes
[j
+4]);
2423 lname
= xmlBuildQName(attributes
[j
], attributes
[j
+1],
2425 if (lname
!= NULL
) {
2426 xmlSAX2AttributeNs(ctxt
, lname
, NULL
,
2427 attributes
[j
+3], attributes
[j
+4]);
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)) {
2447 chk
= xmlValidateDtdFinal(&ctxt
->vctxt
, ctxt
->myDoc
);
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.
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;
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
,
2484 #endif /* LIBXML_VALID_ENABLED */
2487 * end of parsing of this node.
2494 * @ctx: the user data (XML parser context)
2495 * @name: The entity name
2497 * called when an entity xmlSAX2Reference is detected.
2500 xmlSAX2Reference(void *ctx
, const xmlChar
*name
)
2502 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2505 if (ctx
== NULL
) return;
2507 xmlGenericError(xmlGenericErrorContext
,
2508 "SAX.xmlSAX2Reference(%s)\n", name
);
2511 ret
= xmlNewCharRef(ctxt
->myDoc
, name
);
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
);
2518 if (xmlAddChild(ctxt
->node
, ret
) == NULL
) {
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.
2533 xmlSAX2Text(xmlParserCtxtPtr ctxt
, const xmlChar
*ch
, int len
,
2534 xmlElementType type
)
2536 xmlNodePtr lastChild
;
2538 if (ctxt
== NULL
) return;
2540 xmlGenericError(xmlGenericErrorContext
,
2541 "SAX.xmlSAX2Characters(%.30s, %d)\n", ch
, len
);
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");
2556 lastChild
= ctxt
->node
->last
;
2557 #ifdef DEBUG_SAX_TREE
2558 xmlGenericError(xmlGenericErrorContext
,
2559 "add chars to %s \n", ctxt
->node
->name
);
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
);
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;
2579 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters");
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");
2606 if (ctxt
->nodelen
> INT_MAX
- len
) {
2607 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters overflow prevented");
2610 if ((ctxt
->nodelen
+ len
> XML_MAX_TEXT_LENGTH
) &&
2611 ((ctxt
->options
& XML_PARSE_HUGE
) == 0)) {
2612 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters: huge text node");
2615 if (ctxt
->nodelen
+ len
>= ctxt
->nodemem
) {
2619 size
= ctxt
->nodemem
> INT_MAX
- len
?
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");
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;
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
;
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.
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
2685 xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED
, const xmlChar
*ch ATTRIBUTE_UNUSED
, int len ATTRIBUTE_UNUSED
)
2687 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
2689 xmlGenericError(xmlGenericErrorContext
,
2690 "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch
, len
);
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.
2703 xmlSAX2ProcessingInstruction(void *ctx
, const xmlChar
*target
,
2704 const xmlChar
*data
)
2706 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2710 if (ctx
== NULL
) return;
2711 parent
= ctxt
->node
;
2713 xmlGenericError(xmlGenericErrorContext
,
2714 "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target
, data
);
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
;
2725 ret
->line
= USHRT_MAX
;
2728 if (ctxt
->inSubset
== 1) {
2729 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->intSubset
, ret
);
2731 } else if (ctxt
->inSubset
== 2) {
2732 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->extSubset
, ret
);
2735 if (parent
== NULL
) {
2736 #ifdef DEBUG_SAX_TREE
2737 xmlGenericError(xmlGenericErrorContext
,
2738 "Setting PI %s as root\n", target
);
2740 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
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
);
2748 xmlAddChild(parent
, ret
);
2750 #ifdef DEBUG_SAX_TREE
2751 xmlGenericError(xmlGenericErrorContext
,
2752 "adding PI %s sibling to ", target
);
2753 xmlDebugDumpOneNode(stderr
, parent
, 0);
2755 xmlAddSibling(parent
, ret
);
2761 * @ctx: the user data (XML parser context)
2762 * @value: the xmlSAX2Comment content
2764 * A xmlSAX2Comment has been parsed.
2767 xmlSAX2Comment(void *ctx
, const xmlChar
*value
)
2769 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2773 if (ctx
== NULL
) return;
2774 parent
= ctxt
->node
;
2776 xmlGenericError(xmlGenericErrorContext
, "SAX.xmlSAX2Comment(%s)\n", value
);
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
;
2785 ret
->line
= USHRT_MAX
;
2789 if (ctxt
->inSubset
== 1) {
2790 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->intSubset
, ret
);
2792 } else if (ctxt
->inSubset
== 2) {
2793 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->extSubset
, ret
);
2796 if (parent
== NULL
) {
2797 #ifdef DEBUG_SAX_TREE
2798 xmlGenericError(xmlGenericErrorContext
,
2799 "Setting xmlSAX2Comment as root\n");
2801 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
2804 if (parent
->type
== XML_ELEMENT_NODE
) {
2805 #ifdef DEBUG_SAX_TREE
2806 xmlGenericError(xmlGenericErrorContext
,
2807 "adding xmlSAX2Comment child to %s\n", parent
->name
);
2809 xmlAddChild(parent
, ret
);
2811 #ifdef DEBUG_SAX_TREE
2812 xmlGenericError(xmlGenericErrorContext
,
2813 "adding xmlSAX2Comment sibling to ");
2814 xmlDebugDumpOneNode(stderr
, parent
, 0);
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
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
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))
2858 xmlSAX2DefaultVersionValue
= version
;
2861 #endif /* LIBXML_SAX1_ENABLED */
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);
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 */
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
;
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
2928 xmlSAX2InitDefaultSAXHandler(xmlSAXHandler
*hdlr
, int warning
)
2930 if ((hdlr
== NULL
) || (hdlr
->initialized
!= 0))
2933 xmlSAXVersion(hdlr
, xmlSAX2DefaultVersionValue
);
2935 hdlr
->warning
= NULL
;
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
2949 xmlDefaultSAXHandlerInit(void)
2953 #ifdef LIBXML_HTML_ENABLED
2956 * xmlSAX2InitHtmlDefaultSAXHandler:
2957 * @hdlr: the SAX handler
2959 * Initialize the default HTML SAX2 handler
2962 xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler
*hdlr
)
2964 if ((hdlr
== NULL
) || (hdlr
->initialized
!= 0))
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.
3005 htmlDefaultSAXHandlerInit(void)
3009 #endif /* LIBXML_HTML_ENABLED */