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>
15 #include <libxml/xmlmemory.h>
16 #include <libxml/tree.h>
17 #include <libxml/parser.h>
18 #include <libxml/parserInternals.h>
19 #include <libxml/valid.h>
20 #include <libxml/entities.h>
21 #include <libxml/xmlerror.h>
22 #include <libxml/debugXML.h>
23 #include <libxml/xmlIO.h>
24 #include <libxml/SAX.h>
25 #include <libxml/uri.h>
26 #include <libxml/valid.h>
27 #include <libxml/HTMLtree.h>
28 #include <libxml/globals.h>
30 /* Define SIZE_T_MAX unless defined through <limits.h>. */
32 # define SIZE_T_MAX ((size_t)-1)
33 #endif /* !SIZE_T_MAX */
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 prefered
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
59 xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt
, const char *msg
) {
61 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->error
!= NULL
))
62 ctxt
->sax
->error(ctxt
->userData
, "%s: out of memory\n", msg
);
63 ctxt
->errNo
= XML_ERR_NO_MEMORY
;
64 ctxt
->instate
= XML_PARSER_EOF
;
71 * @ctxt: an XML validation parser context
72 * @error: the error number
73 * @msg: the error message
77 * Handle a validation error
80 xmlErrValid(xmlParserCtxtPtr ctxt
, xmlParserErrors error
,
81 const char *msg
, const char *str1
, const char *str2
)
83 xmlStructuredErrorFunc schannel
= NULL
;
85 if ((ctxt
!= NULL
) && (ctxt
->disableSAX
!= 0) &&
86 (ctxt
->instate
== XML_PARSER_EOF
))
90 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->initialized
== XML_SAX2_MAGIC
))
91 schannel
= ctxt
->sax
->serror
;
92 __xmlRaiseError(schannel
,
93 ctxt
->vctxt
.error
, ctxt
->vctxt
.userData
,
94 ctxt
, NULL
, XML_FROM_DTD
, error
,
95 XML_ERR_ERROR
, NULL
, 0, (const char *) str1
,
96 (const char *) str2
, NULL
, 0, 0,
97 msg
, (const char *) str1
, (const char *) str2
);
100 __xmlRaiseError(schannel
,
102 ctxt
, NULL
, XML_FROM_DTD
, error
,
103 XML_ERR_ERROR
, NULL
, 0, (const char *) str1
,
104 (const char *) str2
, NULL
, 0, 0,
105 msg
, (const char *) str1
, (const char *) str2
);
111 * @ctxt: an XML parser context
112 * @error: the error number
113 * @msg: the error message
114 * @str1: an error string
115 * @str2: an error string
117 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
120 xmlFatalErrMsg(xmlParserCtxtPtr ctxt
, xmlParserErrors error
,
121 const char *msg
, const xmlChar
*str1
, const xmlChar
*str2
)
123 if ((ctxt
!= NULL
) && (ctxt
->disableSAX
!= 0) &&
124 (ctxt
->instate
== XML_PARSER_EOF
))
128 __xmlRaiseError(NULL
, NULL
, NULL
, ctxt
, NULL
, XML_FROM_PARSER
, error
,
129 XML_ERR_FATAL
, NULL
, 0,
130 (const char *) str1
, (const char *) str2
,
131 NULL
, 0, 0, msg
, str1
, str2
);
133 ctxt
->wellFormed
= 0;
135 if (ctxt
->recovery
== 0)
136 ctxt
->disableSAX
= 1;
142 * @ctxt: an XML parser context
143 * @error: the error number
144 * @msg: the error message
145 * @str1: an error string
146 * @str2: an error string
148 * Handle a parser warning
151 xmlWarnMsg(xmlParserCtxtPtr ctxt
, xmlParserErrors error
,
152 const char *msg
, const xmlChar
*str1
)
154 if ((ctxt
!= NULL
) && (ctxt
->disableSAX
!= 0) &&
155 (ctxt
->instate
== XML_PARSER_EOF
))
159 __xmlRaiseError(NULL
, NULL
, NULL
, ctxt
, NULL
, XML_FROM_PARSER
, error
,
160 XML_ERR_WARNING
, NULL
, 0,
161 (const char *) str1
, NULL
,
162 NULL
, 0, 0, msg
, str1
);
167 * @ctxt: an XML parser context
168 * @error: the error number
169 * @msg: the error message
170 * @str1: an error string
171 * @str2: an error string
173 * Handle a namespace error
176 xmlNsErrMsg(xmlParserCtxtPtr ctxt
, xmlParserErrors error
,
177 const char *msg
, const xmlChar
*str1
, const xmlChar
*str2
)
179 if ((ctxt
!= NULL
) && (ctxt
->disableSAX
!= 0) &&
180 (ctxt
->instate
== XML_PARSER_EOF
))
184 __xmlRaiseError(NULL
, NULL
, NULL
, ctxt
, NULL
, XML_FROM_NAMESPACE
, error
,
185 XML_ERR_ERROR
, NULL
, 0,
186 (const char *) str1
, (const char *) str2
,
187 NULL
, 0, 0, msg
, str1
, str2
);
192 * @ctxt: an XML parser context
193 * @error: the error number
194 * @msg: the error message
195 * @str1: an error string
197 * Handle a namespace warning
200 xmlNsWarnMsg(xmlParserCtxtPtr ctxt
, xmlParserErrors error
,
201 const char *msg
, const xmlChar
*str1
, const xmlChar
*str2
)
203 if ((ctxt
!= NULL
) && (ctxt
->disableSAX
!= 0) &&
204 (ctxt
->instate
== XML_PARSER_EOF
))
208 __xmlRaiseError(NULL
, NULL
, NULL
, ctxt
, NULL
, XML_FROM_NAMESPACE
, error
,
209 XML_ERR_WARNING
, NULL
, 0,
210 (const char *) str1
, (const char *) str2
,
211 NULL
, 0, 0, msg
, str1
, str2
);
215 * xmlSAX2GetPublicId:
216 * @ctx: the user data (XML parser context)
218 * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
220 * Returns a xmlChar *
223 xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED
)
225 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
230 * xmlSAX2GetSystemId:
231 * @ctx: the user data (XML parser context)
233 * Provides the system ID, basically URL or filename e.g.
234 * http://www.sgmlsource.com/dtds/memo.dtd
236 * Returns a xmlChar *
239 xmlSAX2GetSystemId(void *ctx
)
241 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
242 if ((ctx
== NULL
) || (ctxt
->input
== NULL
)) return(NULL
);
243 return((const xmlChar
*) ctxt
->input
->filename
);
247 * xmlSAX2GetLineNumber:
248 * @ctx: the user data (XML parser context)
250 * Provide the line number of the current parsing point.
255 xmlSAX2GetLineNumber(void *ctx
)
257 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
258 if ((ctx
== NULL
) || (ctxt
->input
== NULL
)) return(0);
259 return(ctxt
->input
->line
);
263 * xmlSAX2GetColumnNumber:
264 * @ctx: the user data (XML parser context)
266 * Provide the column number of the current parsing point.
271 xmlSAX2GetColumnNumber(void *ctx
)
273 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
274 if ((ctx
== NULL
) || (ctxt
->input
== NULL
)) return(0);
275 return(ctxt
->input
->col
);
279 * xmlSAX2IsStandalone:
280 * @ctx: the user data (XML parser context)
282 * Is this document tagged standalone ?
287 xmlSAX2IsStandalone(void *ctx
)
289 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
290 if ((ctx
== NULL
) || (ctxt
->myDoc
== NULL
)) return(0);
291 return(ctxt
->myDoc
->standalone
== 1);
295 * xmlSAX2HasInternalSubset:
296 * @ctx: the user data (XML parser context)
298 * Does this document has an internal subset
303 xmlSAX2HasInternalSubset(void *ctx
)
305 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
306 if ((ctxt
== NULL
) || (ctxt
->myDoc
== NULL
)) return(0);
307 return(ctxt
->myDoc
->intSubset
!= NULL
);
311 * xmlSAX2HasExternalSubset:
312 * @ctx: the user data (XML parser context)
314 * Does this document has an external subset
319 xmlSAX2HasExternalSubset(void *ctx
)
321 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
322 if ((ctxt
== NULL
) || (ctxt
->myDoc
== NULL
)) return(0);
323 return(ctxt
->myDoc
->extSubset
!= NULL
);
327 * xmlSAX2InternalSubset:
328 * @ctx: the user data (XML parser context)
329 * @name: the root element name
330 * @ExternalID: the external ID
331 * @SystemID: the SYSTEM ID (e.g. filename or URL)
333 * Callback on internal subset declaration.
336 xmlSAX2InternalSubset(void *ctx
, const xmlChar
*name
,
337 const xmlChar
*ExternalID
, const xmlChar
*SystemID
)
339 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
341 if (ctx
== NULL
) return;
343 xmlGenericError(xmlGenericErrorContext
,
344 "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n",
345 name
, ExternalID
, SystemID
);
348 if (ctxt
->myDoc
== NULL
)
350 dtd
= xmlGetIntSubset(ctxt
->myDoc
);
354 xmlUnlinkNode((xmlNodePtr
) dtd
);
356 ctxt
->myDoc
->intSubset
= NULL
;
358 ctxt
->myDoc
->intSubset
=
359 xmlCreateIntSubset(ctxt
->myDoc
, name
, ExternalID
, SystemID
);
360 if (ctxt
->myDoc
->intSubset
== NULL
)
361 xmlSAX2ErrMemory(ctxt
, "xmlSAX2InternalSubset");
365 * xmlSAX2ExternalSubset:
366 * @ctx: the user data (XML parser context)
367 * @name: the root element name
368 * @ExternalID: the external ID
369 * @SystemID: the SYSTEM ID (e.g. filename or URL)
371 * Callback on external subset declaration.
374 xmlSAX2ExternalSubset(void *ctx
, const xmlChar
*name
,
375 const xmlChar
*ExternalID
, const xmlChar
*SystemID
)
377 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
378 if (ctx
== NULL
) return;
380 xmlGenericError(xmlGenericErrorContext
,
381 "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n",
382 name
, ExternalID
, SystemID
);
384 if (((ExternalID
!= NULL
) || (SystemID
!= NULL
)) &&
385 (((ctxt
->validate
) || (ctxt
->loadsubset
!= 0)) &&
386 (ctxt
->wellFormed
&& ctxt
->myDoc
))) {
388 * Try to fetch and parse the external subset.
390 xmlParserInputPtr oldinput
;
393 xmlParserInputPtr
*oldinputTab
;
394 xmlParserInputPtr input
= NULL
;
399 * Ask the Entity resolver to load the damn thing
401 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->resolveEntity
!= NULL
))
402 input
= ctxt
->sax
->resolveEntity(ctxt
->userData
, ExternalID
,
408 xmlNewDtd(ctxt
->myDoc
, name
, ExternalID
, SystemID
);
411 * make sure we won't destroy the main document context
413 oldinput
= ctxt
->input
;
414 oldinputNr
= ctxt
->inputNr
;
415 oldinputMax
= ctxt
->inputMax
;
416 oldinputTab
= ctxt
->inputTab
;
417 oldcharset
= ctxt
->charset
;
419 ctxt
->inputTab
= (xmlParserInputPtr
*)
420 xmlMalloc(5 * sizeof(xmlParserInputPtr
));
421 if (ctxt
->inputTab
== NULL
) {
422 xmlSAX2ErrMemory(ctxt
, "xmlSAX2ExternalSubset");
423 ctxt
->input
= oldinput
;
424 ctxt
->inputNr
= oldinputNr
;
425 ctxt
->inputMax
= oldinputMax
;
426 ctxt
->inputTab
= oldinputTab
;
427 ctxt
->charset
= oldcharset
;
433 xmlPushInput(ctxt
, input
);
436 * On the fly encoding conversion if needed
438 if (ctxt
->input
->length
>= 4) {
439 enc
= xmlDetectCharEncoding(ctxt
->input
->cur
, 4);
440 xmlSwitchEncoding(ctxt
, enc
);
443 if (input
->filename
== NULL
)
444 input
->filename
= (char *) xmlCanonicPath(SystemID
);
447 input
->base
= ctxt
->input
->cur
;
448 input
->cur
= ctxt
->input
->cur
;
452 * let's parse that entity knowing it's an external subset.
454 xmlParseExternalSubset(ctxt
, ExternalID
, SystemID
);
457 * Free up the external entities
460 while (ctxt
->inputNr
> 1)
462 xmlFreeInputStream(ctxt
->input
);
463 xmlFree(ctxt
->inputTab
);
466 * Restore the parsing context of the main entity
468 ctxt
->input
= oldinput
;
469 ctxt
->inputNr
= oldinputNr
;
470 ctxt
->inputMax
= oldinputMax
;
471 ctxt
->inputTab
= oldinputTab
;
472 ctxt
->charset
= oldcharset
;
473 /* ctxt->wellFormed = oldwellFormed; */
478 * xmlSAX2ResolveEntity:
479 * @ctx: the user data (XML parser context)
480 * @publicId: The public ID of the entity
481 * @systemId: The system ID of the entity
483 * The entity loader, to control the loading of external entities,
484 * the application can either:
485 * - override this xmlSAX2ResolveEntity() callback in the SAX block
486 * - or better use the xmlSetExternalEntityLoader() function to
487 * set up it's own entity resolution routine
489 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
492 xmlSAX2ResolveEntity(void *ctx
, const xmlChar
*publicId
, const xmlChar
*systemId
)
494 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
495 xmlParserInputPtr ret
;
497 const char *base
= NULL
;
499 if (ctx
== NULL
) return(NULL
);
500 if (ctxt
->input
!= NULL
)
501 base
= ctxt
->input
->filename
;
503 base
= ctxt
->directory
;
505 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
508 xmlGenericError(xmlGenericErrorContext
,
509 "SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId
, systemId
);
512 ret
= xmlLoadExternalEntity((const char *) URI
,
513 (const char *) publicId
, ctxt
);
521 * @ctx: the user data (XML parser context)
522 * @name: The entity name
524 * Get an entity by name
526 * Returns the xmlEntityPtr if found.
529 xmlSAX2GetEntity(void *ctx
, const xmlChar
*name
)
531 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
532 xmlEntityPtr ret
= NULL
;
534 if (ctx
== NULL
) return(NULL
);
536 xmlGenericError(xmlGenericErrorContext
,
537 "SAX.xmlSAX2GetEntity(%s)\n", name
);
540 if (ctxt
->inSubset
== 0) {
541 ret
= xmlGetPredefinedEntity(name
);
545 if ((ctxt
->myDoc
!= NULL
) && (ctxt
->myDoc
->standalone
== 1)) {
546 if (ctxt
->inSubset
== 2) {
547 ctxt
->myDoc
->standalone
= 0;
548 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
549 ctxt
->myDoc
->standalone
= 1;
551 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
553 ctxt
->myDoc
->standalone
= 0;
554 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
556 xmlFatalErrMsg(ctxt
, XML_ERR_NOT_STANDALONE
,
557 "Entity(%s) document marked standalone but requires external subset\n",
560 ctxt
->myDoc
->standalone
= 1;
564 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
567 ((ctxt
->validate
) || (ctxt
->replaceEntities
)) &&
568 (ret
->children
== NULL
) &&
569 (ret
->etype
== XML_EXTERNAL_GENERAL_PARSED_ENTITY
)) {
573 * for validation purposes we really need to fetch and
574 * parse the external entity
578 val
= xmlParseCtxtExternalEntity(ctxt
, ret
->URI
,
579 ret
->ExternalID
, &children
);
581 xmlAddChildList((xmlNodePtr
) ret
, children
);
583 xmlFatalErrMsg(ctxt
, XML_ERR_ENTITY_PROCESSING
,
584 "Failure to process entity %s\n", name
, NULL
);
589 if (ret
->checked
== 0)
596 * xmlSAX2GetParameterEntity:
597 * @ctx: the user data (XML parser context)
598 * @name: The entity name
600 * Get a parameter entity by name
602 * Returns the xmlEntityPtr if found.
605 xmlSAX2GetParameterEntity(void *ctx
, const xmlChar
*name
)
607 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
610 if (ctx
== NULL
) return(NULL
);
612 xmlGenericError(xmlGenericErrorContext
,
613 "SAX.xmlSAX2GetParameterEntity(%s)\n", name
);
616 ret
= xmlGetParameterEntity(ctxt
->myDoc
, name
);
623 * @ctx: the user data (XML parser context)
624 * @name: the entity name
625 * @type: the entity type
626 * @publicId: The public ID of the entity
627 * @systemId: The system ID of the entity
628 * @content: the entity value (without processing).
630 * An entity definition has been parsed
633 xmlSAX2EntityDecl(void *ctx
, const xmlChar
*name
, int type
,
634 const xmlChar
*publicId
, const xmlChar
*systemId
, xmlChar
*content
)
637 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
639 if (ctx
== NULL
) return;
641 xmlGenericError(xmlGenericErrorContext
,
642 "SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n",
643 name
, type
, publicId
, systemId
, content
);
645 if (ctxt
->inSubset
== 1) {
646 ent
= xmlAddDocEntity(ctxt
->myDoc
, name
, type
, publicId
,
648 if ((ent
== NULL
) && (ctxt
->pedantic
))
649 xmlWarnMsg(ctxt
, XML_WAR_ENTITY_REDEFINED
,
650 "Entity(%s) already defined in the internal subset\n",
652 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
654 const char *base
= NULL
;
656 if (ctxt
->input
!= NULL
)
657 base
= ctxt
->input
->filename
;
659 base
= ctxt
->directory
;
661 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
664 } else if (ctxt
->inSubset
== 2) {
665 ent
= xmlAddDtdEntity(ctxt
->myDoc
, name
, type
, publicId
,
667 if ((ent
== NULL
) && (ctxt
->pedantic
) &&
668 (ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
669 ctxt
->sax
->warning(ctxt
->userData
,
670 "Entity(%s) already defined in the external subset\n", name
);
671 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
673 const char *base
= NULL
;
675 if (ctxt
->input
!= NULL
)
676 base
= ctxt
->input
->filename
;
678 base
= ctxt
->directory
;
680 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
684 xmlFatalErrMsg(ctxt
, XML_ERR_ENTITY_PROCESSING
,
685 "SAX.xmlSAX2EntityDecl(%s) called while not in subset\n",
691 * xmlSAX2AttributeDecl:
692 * @ctx: the user data (XML parser context)
693 * @elem: the name of the element
694 * @fullname: the attribute name
695 * @type: the attribute type
696 * @def: the type of default value
697 * @defaultValue: the attribute default value
698 * @tree: the tree of enumerated value set
700 * An attribute definition has been parsed
703 xmlSAX2AttributeDecl(void *ctx
, const xmlChar
*elem
, const xmlChar
*fullname
,
704 int type
, int def
, const xmlChar
*defaultValue
,
705 xmlEnumerationPtr tree
)
707 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
708 xmlAttributePtr attr
;
709 xmlChar
*name
= NULL
, *prefix
= NULL
;
711 if ((ctxt
== NULL
) || (ctxt
->myDoc
== NULL
))
715 xmlGenericError(xmlGenericErrorContext
,
716 "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n",
717 elem
, fullname
, type
, def
, defaultValue
);
719 if ((xmlStrEqual(fullname
, BAD_CAST
"xml:id")) &&
720 (type
!= XML_ATTRIBUTE_ID
)) {
722 * Raise the error but keep the validity flag
724 int tmp
= ctxt
->valid
;
725 xmlErrValid(ctxt
, XML_DTD_XMLID_TYPE
,
726 "xml:id : attribute type should be ID\n", NULL
, NULL
);
729 /* TODO: optimize name/prefix allocation */
730 name
= xmlSplitQName(ctxt
, fullname
, &prefix
);
731 ctxt
->vctxt
.valid
= 1;
732 if (ctxt
->inSubset
== 1)
733 attr
= xmlAddAttributeDecl(&ctxt
->vctxt
, ctxt
->myDoc
->intSubset
, elem
,
734 name
, prefix
, (xmlAttributeType
) type
,
735 (xmlAttributeDefault
) def
, defaultValue
, tree
);
736 else if (ctxt
->inSubset
== 2)
737 attr
= xmlAddAttributeDecl(&ctxt
->vctxt
, ctxt
->myDoc
->extSubset
, elem
,
738 name
, prefix
, (xmlAttributeType
) type
,
739 (xmlAttributeDefault
) def
, defaultValue
, tree
);
741 xmlFatalErrMsg(ctxt
, XML_ERR_INTERNAL_ERROR
,
742 "SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n",
744 xmlFreeEnumeration(tree
);
747 #ifdef LIBXML_VALID_ENABLED
748 if (ctxt
->vctxt
.valid
== 0)
750 if ((attr
!= NULL
) && (ctxt
->validate
) && (ctxt
->wellFormed
) &&
751 (ctxt
->myDoc
->intSubset
!= NULL
))
752 ctxt
->valid
&= xmlValidateAttributeDecl(&ctxt
->vctxt
, ctxt
->myDoc
,
754 #endif /* LIBXML_VALID_ENABLED */
762 * xmlSAX2ElementDecl:
763 * @ctx: the user data (XML parser context)
764 * @name: the element name
765 * @type: the element type
766 * @content: the element value tree
768 * An element definition has been parsed
771 xmlSAX2ElementDecl(void *ctx
, const xmlChar
* name
, int type
,
772 xmlElementContentPtr content
)
774 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
775 xmlElementPtr elem
= NULL
;
777 if ((ctxt
== NULL
) || (ctxt
->myDoc
== NULL
))
781 xmlGenericError(xmlGenericErrorContext
,
782 "SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name
, type
);
785 if (ctxt
->inSubset
== 1)
786 elem
= xmlAddElementDecl(&ctxt
->vctxt
, ctxt
->myDoc
->intSubset
,
787 name
, (xmlElementTypeVal
) type
, content
);
788 else if (ctxt
->inSubset
== 2)
789 elem
= xmlAddElementDecl(&ctxt
->vctxt
, ctxt
->myDoc
->extSubset
,
790 name
, (xmlElementTypeVal
) type
, content
);
792 xmlFatalErrMsg(ctxt
, XML_ERR_INTERNAL_ERROR
,
793 "SAX.xmlSAX2ElementDecl(%s) called while not in subset\n",
797 #ifdef LIBXML_VALID_ENABLED
800 if (ctxt
->validate
&& ctxt
->wellFormed
&&
801 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
803 xmlValidateElementDecl(&ctxt
->vctxt
, ctxt
->myDoc
, elem
);
804 #endif /* LIBXML_VALID_ENABLED */
808 * xmlSAX2NotationDecl:
809 * @ctx: the user data (XML parser context)
810 * @name: The name of the notation
811 * @publicId: The public ID of the entity
812 * @systemId: The system ID of the entity
814 * What to do when a notation declaration has been parsed.
817 xmlSAX2NotationDecl(void *ctx
, const xmlChar
*name
,
818 const xmlChar
*publicId
, const xmlChar
*systemId
)
820 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
821 xmlNotationPtr nota
= NULL
;
823 if ((ctxt
== NULL
) || (ctxt
->myDoc
== NULL
))
827 xmlGenericError(xmlGenericErrorContext
,
828 "SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name
, publicId
, systemId
);
831 if ((publicId
== NULL
) && (systemId
== NULL
)) {
832 xmlFatalErrMsg(ctxt
, XML_ERR_NOTATION_PROCESSING
,
833 "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n",
836 } else if (ctxt
->inSubset
== 1)
837 nota
= xmlAddNotationDecl(&ctxt
->vctxt
, ctxt
->myDoc
->intSubset
, name
,
839 else if (ctxt
->inSubset
== 2)
840 nota
= xmlAddNotationDecl(&ctxt
->vctxt
, ctxt
->myDoc
->extSubset
, name
,
843 xmlFatalErrMsg(ctxt
, XML_ERR_NOTATION_PROCESSING
,
844 "SAX.xmlSAX2NotationDecl(%s) called while not in subset\n",
848 #ifdef LIBXML_VALID_ENABLED
849 if (nota
== NULL
) ctxt
->valid
= 0;
850 if ((ctxt
->validate
) && (ctxt
->wellFormed
) &&
851 (ctxt
->myDoc
->intSubset
!= NULL
))
852 ctxt
->valid
&= xmlValidateNotationDecl(&ctxt
->vctxt
, ctxt
->myDoc
,
854 #endif /* LIBXML_VALID_ENABLED */
858 * xmlSAX2UnparsedEntityDecl:
859 * @ctx: the user data (XML parser context)
860 * @name: The name of the entity
861 * @publicId: The public ID of the entity
862 * @systemId: The system ID of the entity
863 * @notationName: the name of the notation
865 * What to do when an unparsed entity declaration is parsed
868 xmlSAX2UnparsedEntityDecl(void *ctx
, const xmlChar
*name
,
869 const xmlChar
*publicId
, const xmlChar
*systemId
,
870 const xmlChar
*notationName
)
873 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
874 if (ctx
== NULL
) return;
876 xmlGenericError(xmlGenericErrorContext
,
877 "SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n",
878 name
, publicId
, systemId
, notationName
);
880 if (ctxt
->inSubset
== 1) {
881 ent
= xmlAddDocEntity(ctxt
->myDoc
, name
,
882 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY
,
883 publicId
, systemId
, notationName
);
884 if ((ent
== NULL
) && (ctxt
->pedantic
) &&
885 (ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
886 ctxt
->sax
->warning(ctxt
->userData
,
887 "Entity(%s) already defined in the internal subset\n", name
);
888 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
890 const char *base
= NULL
;
892 if (ctxt
->input
!= NULL
)
893 base
= ctxt
->input
->filename
;
895 base
= ctxt
->directory
;
897 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
900 } else if (ctxt
->inSubset
== 2) {
901 ent
= xmlAddDtdEntity(ctxt
->myDoc
, name
,
902 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY
,
903 publicId
, systemId
, notationName
);
904 if ((ent
== NULL
) && (ctxt
->pedantic
) &&
905 (ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
906 ctxt
->sax
->warning(ctxt
->userData
,
907 "Entity(%s) already defined in the external subset\n", name
);
908 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
910 const char *base
= NULL
;
912 if (ctxt
->input
!= NULL
)
913 base
= ctxt
->input
->filename
;
915 base
= ctxt
->directory
;
917 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
921 xmlFatalErrMsg(ctxt
, XML_ERR_INTERNAL_ERROR
,
922 "SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n",
928 * xmlSAX2SetDocumentLocator:
929 * @ctx: the user data (XML parser context)
930 * @loc: A SAX Locator
932 * Receive the document locator at startup, actually xmlDefaultSAXLocator
933 * Everything is available on the context, so this is useless in our case.
936 xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED
, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED
)
938 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
940 xmlGenericError(xmlGenericErrorContext
,
941 "SAX.xmlSAX2SetDocumentLocator()\n");
946 * xmlSAX2StartDocument:
947 * @ctx: the user data (XML parser context)
949 * called when the document start being processed.
952 xmlSAX2StartDocument(void *ctx
)
954 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
957 if (ctx
== NULL
) return;
960 xmlGenericError(xmlGenericErrorContext
,
961 "SAX.xmlSAX2StartDocument()\n");
964 #ifdef LIBXML_HTML_ENABLED
965 if (ctxt
->myDoc
== NULL
)
966 ctxt
->myDoc
= htmlNewDocNoDtD(NULL
, NULL
);
967 ctxt
->myDoc
->properties
= XML_DOC_HTML
;
968 ctxt
->myDoc
->parseFlags
= ctxt
->options
;
969 if (ctxt
->myDoc
== NULL
) {
970 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartDocument");
974 xmlGenericError(xmlGenericErrorContext
,
975 "libxml2 built without HTML support\n");
976 ctxt
->errNo
= XML_ERR_INTERNAL_ERROR
;
977 ctxt
->instate
= XML_PARSER_EOF
;
978 ctxt
->disableSAX
= 1;
982 doc
= ctxt
->myDoc
= xmlNewDoc(ctxt
->version
);
985 if (ctxt
->options
& XML_PARSE_OLD10
)
986 doc
->properties
|= XML_DOC_OLD10
;
987 doc
->parseFlags
= ctxt
->options
;
988 if (ctxt
->encoding
!= NULL
)
989 doc
->encoding
= xmlStrdup(ctxt
->encoding
);
991 doc
->encoding
= NULL
;
992 doc
->standalone
= ctxt
->standalone
;
994 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartDocument");
997 if ((ctxt
->dictNames
) && (doc
!= NULL
)) {
998 doc
->dict
= ctxt
->dict
;
999 xmlDictReference(doc
->dict
);
1002 if ((ctxt
->myDoc
!= NULL
) && (ctxt
->myDoc
->URL
== NULL
) &&
1003 (ctxt
->input
!= NULL
) && (ctxt
->input
->filename
!= NULL
)) {
1004 ctxt
->myDoc
->URL
= xmlPathToURI((const xmlChar
*)ctxt
->input
->filename
);
1005 if (ctxt
->myDoc
->URL
== NULL
)
1006 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartDocument");
1011 * xmlSAX2EndDocument:
1012 * @ctx: the user data (XML parser context)
1014 * called when the document end has been detected.
1017 xmlSAX2EndDocument(void *ctx
)
1019 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1021 xmlGenericError(xmlGenericErrorContext
,
1022 "SAX.xmlSAX2EndDocument()\n");
1024 if (ctx
== NULL
) return;
1025 #ifdef LIBXML_VALID_ENABLED
1026 if (ctxt
->validate
&& ctxt
->wellFormed
&&
1027 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
1028 ctxt
->valid
&= xmlValidateDocumentFinal(&ctxt
->vctxt
, ctxt
->myDoc
);
1029 #endif /* LIBXML_VALID_ENABLED */
1032 * Grab the encoding if it was added on-the-fly
1034 if ((ctxt
->encoding
!= NULL
) && (ctxt
->myDoc
!= NULL
) &&
1035 (ctxt
->myDoc
->encoding
== NULL
)) {
1036 ctxt
->myDoc
->encoding
= ctxt
->encoding
;
1037 ctxt
->encoding
= NULL
;
1039 if ((ctxt
->inputTab
!= NULL
) &&
1040 (ctxt
->inputNr
> 0) && (ctxt
->inputTab
[0] != NULL
) &&
1041 (ctxt
->inputTab
[0]->encoding
!= NULL
) && (ctxt
->myDoc
!= NULL
) &&
1042 (ctxt
->myDoc
->encoding
== NULL
)) {
1043 ctxt
->myDoc
->encoding
= xmlStrdup(ctxt
->inputTab
[0]->encoding
);
1045 if ((ctxt
->charset
!= XML_CHAR_ENCODING_NONE
) && (ctxt
->myDoc
!= NULL
) &&
1046 (ctxt
->myDoc
->charset
== XML_CHAR_ENCODING_NONE
)) {
1047 ctxt
->myDoc
->charset
= ctxt
->charset
;
1051 #if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
1053 * xmlSAX2AttributeInternal:
1054 * @ctx: the user data (XML parser context)
1055 * @fullname: The attribute name, including namespace prefix
1056 * @value: The attribute value
1057 * @prefix: the prefix on the element node
1059 * Handle an attribute that has been read by the parser.
1060 * The default handling is to convert the attribute into an
1061 * DOM subtree and past it in a new xmlAttr element added to
1065 xmlSAX2AttributeInternal(void *ctx
, const xmlChar
*fullname
,
1066 const xmlChar
*value
, const xmlChar
*prefix ATTRIBUTE_UNUSED
)
1068 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1076 name
= xmlStrdup(fullname
);
1081 * Split the full name into a namespace prefix and the tag name
1083 name
= xmlSplitQName(ctxt
, fullname
, &ns
);
1084 if ((name
!= NULL
) && (name
[0] == 0)) {
1085 if (xmlStrEqual(ns
, BAD_CAST
"xmlns")) {
1086 xmlNsErrMsg(ctxt
, XML_ERR_NS_DECL_ERROR
,
1087 "invalid namespace declaration '%s'\n",
1090 xmlNsWarnMsg(ctxt
, XML_WAR_NS_COLUMN
,
1091 "Avoid attribute ending with ':' like '%s'\n",
1098 name
= xmlStrdup(fullname
);
1102 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1108 #ifdef LIBXML_HTML_ENABLED
1110 (value
== NULL
) && (htmlIsBooleanAttr(fullname
))) {
1111 nval
= xmlStrdup(fullname
);
1112 value
= (const xmlChar
*) nval
;
1116 #ifdef LIBXML_VALID_ENABLED
1118 * Do the last stage of the attribute normalization
1119 * Needed for HTML too:
1120 * http://www.w3.org/TR/html4/types.html#h-6.2
1122 ctxt
->vctxt
.valid
= 1;
1123 nval
= xmlValidCtxtNormalizeAttributeValue(&ctxt
->vctxt
,
1124 ctxt
->myDoc
, ctxt
->node
,
1126 if (ctxt
->vctxt
.valid
!= 1) {
1133 #endif /* LIBXML_VALID_ENABLED */
1137 * Check whether it's a namespace definition
1139 if ((!ctxt
->html
) && (ns
== NULL
) &&
1140 (name
[0] == 'x') && (name
[1] == 'm') && (name
[2] == 'l') &&
1141 (name
[3] == 'n') && (name
[4] == 's') && (name
[5] == 0)) {
1145 if (!ctxt
->replaceEntities
) {
1147 val
= xmlStringDecodeEntities(ctxt
, value
, XML_SUBSTITUTE_REF
,
1151 val
= (xmlChar
*) value
;
1157 uri
= xmlParseURI((const char *)val
);
1159 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
1160 ctxt
->sax
->warning(ctxt
->userData
,
1161 "xmlns: %s not a valid URI\n", val
);
1163 if (uri
->scheme
== NULL
) {
1164 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
1165 ctxt
->sax
->warning(ctxt
->userData
,
1166 "xmlns: URI %s is not absolute\n", val
);
1172 /* a default namespace definition */
1173 nsret
= xmlNewNs(ctxt
->node
, val
, NULL
);
1175 #ifdef LIBXML_VALID_ENABLED
1177 * Validate also for namespace decls, they are attributes from
1178 * an XML-1.0 perspective
1180 if (nsret
!= NULL
&& ctxt
->validate
&& ctxt
->wellFormed
&&
1181 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
1182 ctxt
->valid
&= xmlValidateOneNamespace(&ctxt
->vctxt
, ctxt
->myDoc
,
1183 ctxt
->node
, prefix
, nsret
, val
);
1184 #endif /* LIBXML_VALID_ENABLED */
1193 if ((!ctxt
->html
) &&
1194 (ns
!= NULL
) && (ns
[0] == 'x') && (ns
[1] == 'm') && (ns
[2] == 'l') &&
1195 (ns
[3] == 'n') && (ns
[4] == 's') && (ns
[5] == 0)) {
1199 if (!ctxt
->replaceEntities
) {
1201 val
= xmlStringDecodeEntities(ctxt
, value
, XML_SUBSTITUTE_REF
,
1205 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1212 val
= (xmlChar
*) value
;
1216 xmlNsErrMsg(ctxt
, XML_NS_ERR_EMPTY
,
1217 "Empty namespace name for prefix %s\n", name
, NULL
);
1219 if ((ctxt
->pedantic
!= 0) && (val
[0] != 0)) {
1222 uri
= xmlParseURI((const char *)val
);
1224 xmlNsWarnMsg(ctxt
, XML_WAR_NS_URI
,
1225 "xmlns:%s: %s not a valid URI\n", name
, value
);
1227 if (uri
->scheme
== NULL
) {
1228 xmlNsWarnMsg(ctxt
, XML_WAR_NS_URI_RELATIVE
,
1229 "xmlns:%s: URI %s is not absolute\n", name
, value
);
1235 /* a standard namespace definition */
1236 nsret
= xmlNewNs(ctxt
->node
, val
, name
);
1238 #ifdef LIBXML_VALID_ENABLED
1240 * Validate also for namespace decls, they are attributes from
1241 * an XML-1.0 perspective
1243 if (nsret
!= NULL
&& ctxt
->validate
&& ctxt
->wellFormed
&&
1244 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
1245 ctxt
->valid
&= xmlValidateOneNamespace(&ctxt
->vctxt
, ctxt
->myDoc
,
1246 ctxt
->node
, prefix
, nsret
, value
);
1247 #endif /* LIBXML_VALID_ENABLED */
1258 namespace = xmlSearchNs(ctxt
->myDoc
, ctxt
->node
, ns
);
1260 if (namespace == NULL
) {
1261 xmlNsErrMsg(ctxt
, XML_NS_ERR_UNDEFINED_NAMESPACE
,
1262 "Namespace prefix %s of attribute %s is not defined\n",
1267 prop
= ctxt
->node
->properties
;
1268 while (prop
!= NULL
) {
1269 if (prop
->ns
!= NULL
) {
1270 if ((xmlStrEqual(name
, prop
->name
)) &&
1271 ((namespace == prop
->ns
) ||
1272 (xmlStrEqual(namespace->href
, prop
->ns
->href
)))) {
1273 xmlNsErrMsg(ctxt
, XML_ERR_ATTRIBUTE_REDEFINED
,
1274 "Attribute %s in %s redefined\n",
1275 name
, namespace->href
);
1276 ctxt
->wellFormed
= 0;
1277 if (ctxt
->recovery
== 0) ctxt
->disableSAX
= 1;
1288 /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
1289 ret
= xmlNewNsPropEatName(ctxt
->node
, namespace, name
, NULL
);
1292 if ((ctxt
->replaceEntities
== 0) && (!ctxt
->html
)) {
1295 ret
->children
= xmlStringGetNodeList(ctxt
->myDoc
, value
);
1296 tmp
= ret
->children
;
1297 while (tmp
!= NULL
) {
1298 tmp
->parent
= (xmlNodePtr
) ret
;
1299 if (tmp
->next
== NULL
)
1303 } else if (value
!= NULL
) {
1304 ret
->children
= xmlNewDocText(ctxt
->myDoc
, value
);
1305 ret
->last
= ret
->children
;
1306 if (ret
->children
!= NULL
)
1307 ret
->children
->parent
= (xmlNodePtr
) ret
;
1311 #ifdef LIBXML_VALID_ENABLED
1312 if ((!ctxt
->html
) && ctxt
->validate
&& ctxt
->wellFormed
&&
1313 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
) {
1316 * If we don't substitute entities, the validation should be
1317 * done on a value with replaced entities anyway.
1319 if (!ctxt
->replaceEntities
) {
1323 val
= xmlStringDecodeEntities(ctxt
, value
, XML_SUBSTITUTE_REF
,
1328 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
1329 ctxt
->myDoc
, ctxt
->node
, ret
, value
);
1334 * Do the last stage of the attribute normalization
1335 * It need to be done twice ... it's an extra burden related
1336 * to the ability to keep xmlSAX2References in attributes
1338 nvalnorm
= xmlValidNormalizeAttributeValue(ctxt
->myDoc
,
1339 ctxt
->node
, fullname
, val
);
1340 if (nvalnorm
!= NULL
) {
1345 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
1346 ctxt
->myDoc
, ctxt
->node
, ret
, val
);
1350 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
, ctxt
->myDoc
,
1351 ctxt
->node
, ret
, value
);
1354 #endif /* LIBXML_VALID_ENABLED */
1355 if (((ctxt
->loadsubset
& XML_SKIP_IDS
) == 0) &&
1356 (((ctxt
->replaceEntities
== 0) && (ctxt
->external
!= 2)) ||
1357 ((ctxt
->replaceEntities
!= 0) && (ctxt
->inSubset
== 0)))) {
1359 * when validating, the ID registration is done at the attribute
1360 * validation level. Otherwise we have to do specific handling here.
1362 if (xmlStrEqual(fullname
, BAD_CAST
"xml:id")) {
1364 * Add the xml:id value
1366 * Open issue: normalization of the value.
1368 if (xmlValidateNCName(value
, 1) != 0) {
1369 xmlErrValid(ctxt
, XML_DTD_XMLID_VALUE
,
1370 "xml:id : attribute value %s is not an NCName\n",
1371 (const char *) value
, NULL
);
1373 xmlAddID(&ctxt
->vctxt
, ctxt
->myDoc
, value
, ret
);
1374 } else if (xmlIsID(ctxt
->myDoc
, ctxt
->node
, ret
))
1375 xmlAddID(&ctxt
->vctxt
, ctxt
->myDoc
, value
, ret
);
1376 else if (xmlIsRef(ctxt
->myDoc
, ctxt
->node
, ret
))
1377 xmlAddRef(&ctxt
->vctxt
, ctxt
->myDoc
, value
, ret
);
1388 * xmlCheckDefaultedAttributes:
1390 * Check defaulted attributes from the DTD
1393 xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt
, const xmlChar
*name
,
1394 const xmlChar
*prefix
, const xmlChar
**atts
) {
1395 xmlElementPtr elemDecl
;
1400 elemDecl
= xmlGetDtdQElementDesc(ctxt
->myDoc
->intSubset
, name
, prefix
);
1401 if (elemDecl
== NULL
) {
1402 elemDecl
= xmlGetDtdQElementDesc(ctxt
->myDoc
->extSubset
, name
, prefix
);
1406 process_external_subset
:
1408 if (elemDecl
!= NULL
) {
1409 xmlAttributePtr attr
= elemDecl
->attributes
;
1411 * Check against defaulted attributes from the external subset
1412 * if the document is stamped as standalone
1414 if ((ctxt
->myDoc
->standalone
== 1) &&
1415 (ctxt
->myDoc
->extSubset
!= NULL
) &&
1417 while (attr
!= NULL
) {
1418 if ((attr
->defaultValue
!= NULL
) &&
1419 (xmlGetDtdQAttrDesc(ctxt
->myDoc
->extSubset
,
1420 attr
->elem
, attr
->name
,
1421 attr
->prefix
) == attr
) &&
1422 (xmlGetDtdQAttrDesc(ctxt
->myDoc
->intSubset
,
1423 attr
->elem
, attr
->name
,
1424 attr
->prefix
) == NULL
)) {
1427 if (attr
->prefix
!= NULL
) {
1428 fulln
= xmlStrdup(attr
->prefix
);
1429 fulln
= xmlStrcat(fulln
, BAD_CAST
":");
1430 fulln
= xmlStrcat(fulln
, attr
->name
);
1432 fulln
= xmlStrdup(attr
->name
);
1434 if (fulln
== NULL
) {
1435 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1440 * Check that the attribute is not declared in the
1447 while (att
!= NULL
) {
1448 if (xmlStrEqual(att
, fulln
))
1455 xmlErrValid(ctxt
, XML_DTD_STANDALONE_DEFAULTED
,
1456 "standalone: attribute %s on %s defaulted from external subset\n",
1457 (const char *)fulln
,
1458 (const char *)attr
->elem
);
1467 * Actually insert defaulted values when needed
1469 attr
= elemDecl
->attributes
;
1470 while (attr
!= NULL
) {
1472 * Make sure that attributes redefinition occuring in the
1473 * internal subset are not overriden by definitions in the
1476 if (attr
->defaultValue
!= NULL
) {
1478 * the element should be instantiated in the tree if:
1479 * - this is a namespace prefix
1480 * - the user required for completion in the tree
1482 * - there isn't already an attribute definition
1483 * in the internal subset overriding it.
1485 if (((attr
->prefix
!= NULL
) &&
1486 (xmlStrEqual(attr
->prefix
, BAD_CAST
"xmlns"))) ||
1487 ((attr
->prefix
== NULL
) &&
1488 (xmlStrEqual(attr
->name
, BAD_CAST
"xmlns"))) ||
1489 (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)) {
1490 xmlAttributePtr tst
;
1492 tst
= xmlGetDtdQAttrDesc(ctxt
->myDoc
->intSubset
,
1493 attr
->elem
, attr
->name
,
1495 if ((tst
== attr
) || (tst
== NULL
)) {
1499 fulln
= xmlBuildQName(attr
->name
, attr
->prefix
, fn
, 50);
1500 if (fulln
== NULL
) {
1501 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1506 * Check that the attribute is not declared in the
1513 while (att
!= NULL
) {
1514 if (xmlStrEqual(att
, fulln
))
1521 xmlSAX2AttributeInternal(ctxt
, fulln
,
1522 attr
->defaultValue
, prefix
);
1524 if ((fulln
!= fn
) && (fulln
!= attr
->name
))
1531 if (internal
== 1) {
1532 elemDecl
= xmlGetDtdQElementDesc(ctxt
->myDoc
->extSubset
,
1535 goto process_external_subset
;
1541 * xmlSAX2StartElement:
1542 * @ctx: the user data (XML parser context)
1543 * @fullname: The element name, including namespace prefix
1544 * @atts: An array of name/value attributes pairs, NULL terminated
1546 * called when an opening tag has been processed.
1549 xmlSAX2StartElement(void *ctx
, const xmlChar
*fullname
, const xmlChar
**atts
)
1551 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1558 const xmlChar
*value
;
1561 if ((ctx
== NULL
) || (fullname
== NULL
) || (ctxt
->myDoc
== NULL
)) return;
1562 parent
= ctxt
->node
;
1564 xmlGenericError(xmlGenericErrorContext
,
1565 "SAX.xmlSAX2StartElement(%s)\n", fullname
);
1569 * First check on validity:
1571 if (ctxt
->validate
&& (ctxt
->myDoc
->extSubset
== NULL
) &&
1572 ((ctxt
->myDoc
->intSubset
== NULL
) ||
1573 ((ctxt
->myDoc
->intSubset
->notations
== NULL
) &&
1574 (ctxt
->myDoc
->intSubset
->elements
== NULL
) &&
1575 (ctxt
->myDoc
->intSubset
->attributes
== NULL
) &&
1576 (ctxt
->myDoc
->intSubset
->entities
== NULL
)))) {
1577 xmlErrValid(ctxt
, XML_ERR_NO_DTD
,
1578 "Validation failed: no DTD found !", NULL
, NULL
);
1584 * Split the full name into a namespace prefix and the tag name
1586 name
= xmlSplitQName(ctxt
, fullname
, &prefix
);
1590 * Note : the namespace resolution is deferred until the end of the
1591 * attributes parsing, since local namespace can be defined as
1592 * an attribute at this level.
1594 ret
= xmlNewDocNodeEatName(ctxt
->myDoc
, NULL
, name
, NULL
);
1598 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1601 if (ctxt
->myDoc
->children
== NULL
) {
1602 #ifdef DEBUG_SAX_TREE
1603 xmlGenericError(xmlGenericErrorContext
, "Setting %s as root\n", name
);
1605 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
1606 } else if (parent
== NULL
) {
1607 parent
= ctxt
->myDoc
->children
;
1610 if (ctxt
->linenumbers
) {
1611 if (ctxt
->input
!= NULL
) {
1612 if (ctxt
->input
->line
< 65535)
1613 ret
->line
= (short) ctxt
->input
->line
;
1620 * We are parsing a new node.
1622 #ifdef DEBUG_SAX_TREE
1623 xmlGenericError(xmlGenericErrorContext
, "pushing(%s)\n", name
);
1625 nodePush(ctxt
, ret
);
1628 * Link the child element
1630 if (parent
!= NULL
) {
1631 if (parent
->type
== XML_ELEMENT_NODE
) {
1632 #ifdef DEBUG_SAX_TREE
1633 xmlGenericError(xmlGenericErrorContext
,
1634 "adding child %s to %s\n", name
, parent
->name
);
1636 xmlAddChild(parent
, ret
);
1638 #ifdef DEBUG_SAX_TREE
1639 xmlGenericError(xmlGenericErrorContext
,
1640 "adding sibling %s to ", name
);
1641 xmlDebugDumpOneNode(stderr
, parent
, 0);
1643 xmlAddSibling(parent
, ret
);
1648 * Insert all the defaulted attributes from the DTD especially namespaces
1650 if ((!ctxt
->html
) &&
1651 ((ctxt
->myDoc
->intSubset
!= NULL
) ||
1652 (ctxt
->myDoc
->extSubset
!= NULL
))) {
1653 xmlCheckDefaultedAttributes(ctxt
, name
, prefix
, atts
);
1657 * process all the attributes whose name start with "xmlns"
1664 while ((att
!= NULL
) && (value
!= NULL
)) {
1665 if ((att
[0] == 'x') && (att
[1] == 'm') && (att
[2] == 'l') &&
1666 (att
[3] == 'n') && (att
[4] == 's'))
1667 xmlSAX2AttributeInternal(ctxt
, att
, value
, prefix
);
1676 * Search the namespace, note that since the attributes have been
1677 * processed, the local namespaces are available.
1679 ns
= xmlSearchNs(ctxt
->myDoc
, ret
, prefix
);
1680 if ((ns
== NULL
) && (parent
!= NULL
))
1681 ns
= xmlSearchNs(ctxt
->myDoc
, parent
, prefix
);
1682 if ((prefix
!= NULL
) && (ns
== NULL
)) {
1683 ns
= xmlNewNs(ret
, NULL
, prefix
);
1684 xmlNsWarnMsg(ctxt
, XML_NS_ERR_UNDEFINED_NAMESPACE
,
1685 "Namespace prefix %s is not defined\n",
1690 * set the namespace node, making sure that if the default namspace
1691 * is unbound on a parent we simply kee it NULL
1693 if ((ns
!= NULL
) && (ns
->href
!= NULL
) &&
1694 ((ns
->href
[0] != 0) || (ns
->prefix
!= NULL
)))
1698 * process all the other attributes
1705 while (att
!= NULL
) {
1706 xmlSAX2AttributeInternal(ctxt
, att
, value
, NULL
);
1711 while ((att
!= NULL
) && (value
!= NULL
)) {
1712 if ((att
[0] != 'x') || (att
[1] != 'm') || (att
[2] != 'l') ||
1713 (att
[3] != 'n') || (att
[4] != 's'))
1714 xmlSAX2AttributeInternal(ctxt
, att
, value
, NULL
);
1725 #ifdef LIBXML_VALID_ENABLED
1727 * If it's the Document root, finish the DTD validation and
1728 * check the document root element for validity
1730 if ((ctxt
->validate
) && (ctxt
->vctxt
.finishDtd
== XML_CTXT_FINISH_DTD_0
)) {
1733 chk
= xmlValidateDtdFinal(&ctxt
->vctxt
, ctxt
->myDoc
);
1737 ctxt
->wellFormed
= 0;
1738 ctxt
->valid
&= xmlValidateRoot(&ctxt
->vctxt
, ctxt
->myDoc
);
1739 ctxt
->vctxt
.finishDtd
= XML_CTXT_FINISH_DTD_1
;
1741 #endif /* LIBXML_VALID_ENABLED */
1749 * xmlSAX2EndElement:
1750 * @ctx: the user data (XML parser context)
1751 * @name: The element name
1753 * called when the end of an element has been detected.
1756 xmlSAX2EndElement(void *ctx
, const xmlChar
*name ATTRIBUTE_UNUSED
)
1758 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1759 xmlParserNodeInfo node_info
;
1762 if (ctx
== NULL
) return;
1766 xmlGenericError(xmlGenericErrorContext
, "SAX.xmlSAX2EndElement(NULL)\n");
1768 xmlGenericError(xmlGenericErrorContext
, "SAX.xmlSAX2EndElement(%s)\n", name
);
1771 /* Capture end position and add node */
1772 if (cur
!= NULL
&& ctxt
->record_info
) {
1773 node_info
.end_pos
= ctxt
->input
->cur
- ctxt
->input
->base
;
1774 node_info
.end_line
= ctxt
->input
->line
;
1775 node_info
.node
= cur
;
1776 xmlParserAddNodeInfo(ctxt
, &node_info
);
1780 #ifdef LIBXML_VALID_ENABLED
1781 if (ctxt
->validate
&& ctxt
->wellFormed
&&
1782 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
1783 ctxt
->valid
&= xmlValidateOneElement(&ctxt
->vctxt
, ctxt
->myDoc
,
1785 #endif /* LIBXML_VALID_ENABLED */
1789 * end of parsing of this node.
1791 #ifdef DEBUG_SAX_TREE
1792 xmlGenericError(xmlGenericErrorContext
, "popping(%s)\n", cur
->name
);
1796 #endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLE */
1800 * @ctxt: the parser context
1801 * @str: the input string
1802 * @len: the string length
1804 * Remove the entities from an attribute value
1806 * Returns the newly allocated string or NULL if not needed or error
1809 xmlSAX2TextNode(xmlParserCtxtPtr ctxt
, const xmlChar
*str
, int len
) {
1811 const xmlChar
*intern
= NULL
;
1816 if (ctxt
->freeElems
!= NULL
) {
1817 ret
= ctxt
->freeElems
;
1818 ctxt
->freeElems
= ret
->next
;
1819 ctxt
->freeElemsNr
--;
1821 ret
= (xmlNodePtr
) xmlMalloc(sizeof(xmlNode
));
1824 xmlErrMemory(ctxt
, "xmlSAX2Characters");
1827 memset(ret
, 0, sizeof(xmlNode
));
1829 * intern the formatting blanks found between tags, or the
1830 * very short strings
1832 if (ctxt
->dictNames
) {
1833 xmlChar cur
= str
[len
];
1835 if ((len
< (int) (2 * sizeof(void *))) &&
1836 (ctxt
->options
& XML_PARSE_COMPACT
)) {
1837 /* store the string in the node overrithing properties and nsDef */
1838 xmlChar
*tmp
= (xmlChar
*) &(ret
->properties
);
1839 memcpy(tmp
, str
, len
);
1842 } else if ((len
<= 3) && ((cur
== '"') || (cur
== '\'') ||
1843 ((cur
== '<') && (str
[len
+ 1] != '!')))) {
1844 intern
= xmlDictLookup(ctxt
->dict
, str
, len
);
1845 } else if (IS_BLANK_CH(*str
) && (len
< 60) && (cur
== '<') &&
1846 (str
[len
+ 1] != '!')) {
1849 for (i
= 1;i
< len
;i
++) {
1850 if (!IS_BLANK_CH(str
[i
])) goto skip
;
1852 intern
= xmlDictLookup(ctxt
->dict
, str
, len
);
1856 ret
->type
= XML_TEXT_NODE
;
1858 ret
->name
= xmlStringText
;
1859 if (intern
== NULL
) {
1860 ret
->content
= xmlStrndup(str
, len
);
1861 if (ret
->content
== NULL
) {
1862 xmlSAX2ErrMemory(ctxt
, "xmlSAX2TextNode");
1867 ret
->content
= (xmlChar
*) intern
;
1869 if (ctxt
->input
!= NULL
)
1870 ret
->line
= ctxt
->input
->line
;
1872 if ((__xmlRegisterCallbacks
) && (xmlRegisterNodeDefaultValue
))
1873 xmlRegisterNodeDefaultValue(ret
);
1877 #ifdef LIBXML_VALID_ENABLED
1879 * xmlSAX2DecodeAttrEntities:
1880 * @ctxt: the parser context
1881 * @str: the input string
1882 * @len: the string length
1884 * Remove the entities from an attribute value
1886 * Returns the newly allocated string or NULL if not needed or error
1889 xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt
, const xmlChar
*str
,
1890 const xmlChar
*end
) {
1901 ret
= xmlStringLenDecodeEntities(ctxt
, str
, end
- str
,
1902 XML_SUBSTITUTE_REF
, 0,0,0);
1906 #endif /* LIBXML_VALID_ENABLED */
1909 * xmlSAX2AttributeNs:
1910 * @ctx: the user data (XML parser context)
1911 * @localname: the local name of the attribute
1912 * @prefix: the attribute namespace prefix if available
1913 * @URI: the attribute namespace name if available
1914 * @value: Start of the attribute value
1915 * @valueend: end of the attribute value
1917 * Handle an attribute that has been read by the parser.
1918 * The default handling is to convert the attribute into an
1919 * DOM subtree and past it in a new xmlAttr element added to
1923 xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt
,
1924 const xmlChar
* localname
,
1925 const xmlChar
* prefix
,
1926 const xmlChar
* value
,
1927 const xmlChar
* valueend
)
1930 xmlNsPtr
namespace = NULL
;
1931 xmlChar
*dup
= NULL
;
1934 * Note: if prefix == NULL, the attribute is not in the default namespace
1937 namespace = xmlSearchNs(ctxt
->myDoc
, ctxt
->node
, prefix
);
1942 if (ctxt
->freeAttrs
!= NULL
) {
1943 ret
= ctxt
->freeAttrs
;
1944 ctxt
->freeAttrs
= ret
->next
;
1945 ctxt
->freeAttrsNr
--;
1946 memset(ret
, 0, sizeof(xmlAttr
));
1947 ret
->type
= XML_ATTRIBUTE_NODE
;
1949 ret
->parent
= ctxt
->node
;
1950 ret
->doc
= ctxt
->myDoc
;
1951 ret
->ns
= namespace;
1953 if (ctxt
->dictNames
)
1954 ret
->name
= localname
;
1956 ret
->name
= xmlStrdup(localname
);
1958 /* link at the end to preserv order, TODO speed up with a last */
1959 if (ctxt
->node
->properties
== NULL
) {
1960 ctxt
->node
->properties
= ret
;
1962 xmlAttrPtr prev
= ctxt
->node
->properties
;
1964 while (prev
->next
!= NULL
) prev
= prev
->next
;
1969 if ((__xmlRegisterCallbacks
) && (xmlRegisterNodeDefaultValue
))
1970 xmlRegisterNodeDefaultValue((xmlNodePtr
)ret
);
1972 if (ctxt
->dictNames
)
1973 ret
= xmlNewNsPropEatName(ctxt
->node
, namespace,
1974 (xmlChar
*) localname
, NULL
);
1976 ret
= xmlNewNsProp(ctxt
->node
, namespace, localname
, NULL
);
1978 xmlErrMemory(ctxt
, "xmlSAX2AttributeNs");
1983 if ((ctxt
->replaceEntities
== 0) && (!ctxt
->html
)) {
1987 * We know that if there is an entity reference, then
1988 * the string has been dup'ed and terminates with 0
1989 * otherwise with ' or "
1991 if (*valueend
!= 0) {
1992 tmp
= xmlSAX2TextNode(ctxt
, value
, valueend
- value
);
1993 ret
->children
= tmp
;
1996 tmp
->doc
= ret
->doc
;
1997 tmp
->parent
= (xmlNodePtr
) ret
;
2000 ret
->children
= xmlStringLenGetNodeList(ctxt
->myDoc
, value
,
2002 tmp
= ret
->children
;
2003 while (tmp
!= NULL
) {
2004 tmp
->doc
= ret
->doc
;
2005 tmp
->parent
= (xmlNodePtr
) ret
;
2006 if (tmp
->next
== NULL
)
2011 } else if (value
!= NULL
) {
2014 tmp
= xmlSAX2TextNode(ctxt
, value
, valueend
- value
);
2015 ret
->children
= tmp
;
2018 tmp
->doc
= ret
->doc
;
2019 tmp
->parent
= (xmlNodePtr
) ret
;
2023 #ifdef LIBXML_VALID_ENABLED
2024 if ((!ctxt
->html
) && ctxt
->validate
&& ctxt
->wellFormed
&&
2025 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
) {
2027 * If we don't substitute entities, the validation should be
2028 * done on a value with replaced entities anyway.
2030 if (!ctxt
->replaceEntities
) {
2031 dup
= xmlSAX2DecodeAttrEntities(ctxt
, value
, valueend
);
2033 if (*valueend
== 0) {
2034 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2035 ctxt
->myDoc
, ctxt
->node
, ret
, value
);
2038 * That should already be normalized.
2039 * cheaper to finally allocate here than duplicate
2040 * entry points in the full validation code
2042 dup
= xmlStrndup(value
, valueend
- value
);
2044 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2045 ctxt
->myDoc
, ctxt
->node
, ret
, dup
);
2049 * dup now contains a string of the flattened attribute
2050 * content with entities substitued. Check if we need to
2051 * apply an extra layer of normalization.
2052 * It need to be done twice ... it's an extra burden related
2053 * to the ability to keep references in attributes
2055 if (ctxt
->attsSpecial
!= NULL
) {
2060 fullname
= xmlBuildQName(localname
, prefix
, fn
, 50);
2061 if (fullname
!= NULL
) {
2062 ctxt
->vctxt
.valid
= 1;
2063 nvalnorm
= xmlValidCtxtNormalizeAttributeValue(
2064 &ctxt
->vctxt
, ctxt
->myDoc
,
2065 ctxt
->node
, fullname
, dup
);
2066 if (ctxt
->vctxt
.valid
!= 1)
2069 if ((fullname
!= fn
) && (fullname
!= localname
))
2071 if (nvalnorm
!= NULL
) {
2078 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2079 ctxt
->myDoc
, ctxt
->node
, ret
, dup
);
2083 * if entities already have been substitued, then
2084 * the attribute as passed is already normalized
2086 dup
= xmlStrndup(value
, valueend
- value
);
2088 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2089 ctxt
->myDoc
, ctxt
->node
, ret
, dup
);
2092 #endif /* LIBXML_VALID_ENABLED */
2093 if (((ctxt
->loadsubset
& XML_SKIP_IDS
) == 0) &&
2094 (((ctxt
->replaceEntities
== 0) && (ctxt
->external
!= 2)) ||
2095 ((ctxt
->replaceEntities
!= 0) && (ctxt
->inSubset
== 0)))) {
2097 * when validating, the ID registration is done at the attribute
2098 * validation level. Otherwise we have to do specific handling here.
2100 if ((prefix
== ctxt
->str_xml
) &&
2101 (localname
[0] == 'i') && (localname
[1] == 'd') &&
2102 (localname
[2] == 0)) {
2104 * Add the xml:id value
2106 * Open issue: normalization of the value.
2109 dup
= xmlStrndup(value
, valueend
- value
);
2110 #ifdef LIBXML_VALID_ENABLED
2111 if (xmlValidateNCName(dup
, 1) != 0) {
2112 xmlErrValid(ctxt
, XML_DTD_XMLID_VALUE
,
2113 "xml:id : attribute value %s is not an NCName\n",
2114 (const char *) dup
, NULL
);
2117 xmlAddID(&ctxt
->vctxt
, ctxt
->myDoc
, dup
, ret
);
2118 } else if (xmlIsID(ctxt
->myDoc
, ctxt
->node
, ret
)) {
2119 /* might be worth duplicate entry points and not copy */
2121 dup
= xmlStrndup(value
, valueend
- value
);
2122 xmlAddID(&ctxt
->vctxt
, ctxt
->myDoc
, dup
, ret
);
2123 } else if (xmlIsRef(ctxt
->myDoc
, ctxt
->node
, ret
)) {
2125 dup
= xmlStrndup(value
, valueend
- value
);
2126 xmlAddRef(&ctxt
->vctxt
, ctxt
->myDoc
, dup
, ret
);
2134 * xmlSAX2StartElementNs:
2135 * @ctx: the user data (XML parser context)
2136 * @localname: the local name of the element
2137 * @prefix: the element namespace prefix if available
2138 * @URI: the element namespace name if available
2139 * @nb_namespaces: number of namespace definitions on that node
2140 * @namespaces: pointer to the array of prefix/URI pairs namespace definitions
2141 * @nb_attributes: the number of attributes on that node
2142 * @nb_defaulted: the number of defaulted attributes.
2143 * @attributes: pointer to the array of (localname/prefix/URI/value/end)
2146 * SAX2 callback when an element start has been detected by the parser.
2147 * It provides the namespace informations for the element, as well as
2148 * the new namespace declarations on the element.
2151 xmlSAX2StartElementNs(void *ctx
,
2152 const xmlChar
*localname
,
2153 const xmlChar
*prefix
,
2156 const xmlChar
**namespaces
,
2159 const xmlChar
**attributes
)
2161 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2164 xmlNsPtr last
= NULL
, ns
;
2165 const xmlChar
*uri
, *pref
;
2168 if (ctx
== NULL
) return;
2169 parent
= ctxt
->node
;
2171 * First check on validity:
2173 if (ctxt
->validate
&& (ctxt
->myDoc
->extSubset
== NULL
) &&
2174 ((ctxt
->myDoc
->intSubset
== NULL
) ||
2175 ((ctxt
->myDoc
->intSubset
->notations
== NULL
) &&
2176 (ctxt
->myDoc
->intSubset
->elements
== NULL
) &&
2177 (ctxt
->myDoc
->intSubset
->attributes
== NULL
) &&
2178 (ctxt
->myDoc
->intSubset
->entities
== NULL
)))) {
2179 xmlErrValid(ctxt
, XML_ERR_NO_DTD
,
2180 "Validation failed: no DTD found !", NULL
, NULL
);
2187 if (ctxt
->freeElems
!= NULL
) {
2188 ret
= ctxt
->freeElems
;
2189 ctxt
->freeElems
= ret
->next
;
2190 ctxt
->freeElemsNr
--;
2191 memset(ret
, 0, sizeof(xmlNode
));
2192 ret
->type
= XML_ELEMENT_NODE
;
2194 if (ctxt
->dictNames
)
2195 ret
->name
= localname
;
2197 ret
->name
= xmlStrdup(localname
);
2198 if (ret
->name
== NULL
) {
2199 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2203 if ((__xmlRegisterCallbacks
) && (xmlRegisterNodeDefaultValue
))
2204 xmlRegisterNodeDefaultValue(ret
);
2206 if (ctxt
->dictNames
)
2207 ret
= xmlNewDocNodeEatName(ctxt
->myDoc
, NULL
,
2208 (xmlChar
*) localname
, NULL
);
2210 ret
= xmlNewDocNode(ctxt
->myDoc
, NULL
, localname
, NULL
);
2212 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2216 if (ctxt
->linenumbers
) {
2217 if (ctxt
->input
!= NULL
) {
2218 if (ctxt
->input
->line
< 65535)
2219 ret
->line
= (short) ctxt
->input
->line
;
2225 if ((ctxt
->myDoc
->children
== NULL
) || (parent
== NULL
)) {
2226 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
2229 * Build the namespace list
2231 for (i
= 0,j
= 0;j
< nb_namespaces
;j
++) {
2232 pref
= namespaces
[i
++];
2233 uri
= namespaces
[i
++];
2234 ns
= xmlNewNs(NULL
, uri
, pref
);
2237 ret
->nsDef
= last
= ns
;
2242 if ((URI
!= NULL
) && (prefix
== pref
))
2245 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2248 #ifdef LIBXML_VALID_ENABLED
2249 if ((!ctxt
->html
) && ctxt
->validate
&& ctxt
->wellFormed
&&
2250 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
) {
2251 ctxt
->valid
&= xmlValidateOneNamespace(&ctxt
->vctxt
, ctxt
->myDoc
,
2252 ret
, prefix
, ns
, uri
);
2254 #endif /* LIBXML_VALID_ENABLED */
2259 * We are parsing a new node.
2261 nodePush(ctxt
, ret
);
2264 * Link the child element
2266 if (parent
!= NULL
) {
2267 if (parent
->type
== XML_ELEMENT_NODE
) {
2268 xmlAddChild(parent
, ret
);
2270 xmlAddSibling(parent
, ret
);
2275 * Insert the defaulted attributes from the DTD only if requested:
2277 if ((nb_defaulted
!= 0) &&
2278 ((ctxt
->loadsubset
& XML_COMPLETE_ATTRS
) == 0))
2279 nb_attributes
-= nb_defaulted
;
2282 * Search the namespace if it wasn't already found
2283 * Note that, if prefix is NULL, this searches for the default Ns
2285 if ((URI
!= NULL
) && (ret
->ns
== NULL
)) {
2286 ret
->ns
= xmlSearchNs(ctxt
->myDoc
, parent
, prefix
);
2287 if ((ret
->ns
== NULL
) && (xmlStrEqual(prefix
, BAD_CAST
"xml"))) {
2288 ret
->ns
= xmlSearchNs(ctxt
->myDoc
, ret
, prefix
);
2290 if (ret
->ns
== NULL
) {
2291 ns
= xmlNewNs(ret
, NULL
, prefix
);
2294 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2298 xmlNsWarnMsg(ctxt
, XML_NS_ERR_UNDEFINED_NAMESPACE
,
2299 "Namespace prefix %s was not found\n",
2302 xmlNsWarnMsg(ctxt
, XML_NS_ERR_UNDEFINED_NAMESPACE
,
2303 "Namespace default prefix was not found\n",
2309 * process all the other attributes
2311 if (nb_attributes
> 0) {
2312 for (j
= 0,i
= 0;i
< nb_attributes
;i
++,j
+=5) {
2313 xmlSAX2AttributeNs(ctxt
, attributes
[j
], attributes
[j
+1],
2314 attributes
[j
+3], attributes
[j
+4]);
2318 #ifdef LIBXML_VALID_ENABLED
2320 * If it's the Document root, finish the DTD validation and
2321 * check the document root element for validity
2323 if ((ctxt
->validate
) && (ctxt
->vctxt
.finishDtd
== XML_CTXT_FINISH_DTD_0
)) {
2326 chk
= xmlValidateDtdFinal(&ctxt
->vctxt
, ctxt
->myDoc
);
2330 ctxt
->wellFormed
= 0;
2331 ctxt
->valid
&= xmlValidateRoot(&ctxt
->vctxt
, ctxt
->myDoc
);
2332 ctxt
->vctxt
.finishDtd
= XML_CTXT_FINISH_DTD_1
;
2334 #endif /* LIBXML_VALID_ENABLED */
2338 * xmlSAX2EndElementNs:
2339 * @ctx: the user data (XML parser context)
2340 * @localname: the local name of the element
2341 * @prefix: the element namespace prefix if available
2342 * @URI: the element namespace name if available
2344 * SAX2 callback when an element end has been detected by the parser.
2345 * It provides the namespace informations for the element.
2348 xmlSAX2EndElementNs(void *ctx
,
2349 const xmlChar
* localname ATTRIBUTE_UNUSED
,
2350 const xmlChar
* prefix ATTRIBUTE_UNUSED
,
2351 const xmlChar
* URI ATTRIBUTE_UNUSED
)
2353 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2354 xmlParserNodeInfo node_info
;
2357 if (ctx
== NULL
) return;
2359 /* Capture end position and add node */
2360 if ((ctxt
->record_info
) && (cur
!= NULL
)) {
2361 node_info
.end_pos
= ctxt
->input
->cur
- ctxt
->input
->base
;
2362 node_info
.end_line
= ctxt
->input
->line
;
2363 node_info
.node
= cur
;
2364 xmlParserAddNodeInfo(ctxt
, &node_info
);
2368 #ifdef LIBXML_VALID_ENABLED
2369 if (ctxt
->validate
&& ctxt
->wellFormed
&&
2370 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
2371 ctxt
->valid
&= xmlValidateOneElement(&ctxt
->vctxt
, ctxt
->myDoc
, cur
);
2372 #endif /* LIBXML_VALID_ENABLED */
2375 * end of parsing of this node.
2382 * @ctx: the user data (XML parser context)
2383 * @name: The entity name
2385 * called when an entity xmlSAX2Reference is detected.
2388 xmlSAX2Reference(void *ctx
, const xmlChar
*name
)
2390 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2393 if (ctx
== NULL
) return;
2395 xmlGenericError(xmlGenericErrorContext
,
2396 "SAX.xmlSAX2Reference(%s)\n", name
);
2399 ret
= xmlNewCharRef(ctxt
->myDoc
, name
);
2401 ret
= xmlNewReference(ctxt
->myDoc
, name
);
2402 #ifdef DEBUG_SAX_TREE
2403 xmlGenericError(xmlGenericErrorContext
,
2404 "add xmlSAX2Reference %s to %s \n", name
, ctxt
->node
->name
);
2406 if (xmlAddChild(ctxt
->node
, ret
) == NULL
) {
2412 * xmlSAX2Characters:
2413 * @ctx: the user data (XML parser context)
2414 * @ch: a xmlChar string
2415 * @len: the number of xmlChar
2417 * receiving some chars from the parser.
2420 xmlSAX2Characters(void *ctx
, const xmlChar
*ch
, int len
)
2422 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2423 xmlNodePtr lastChild
;
2425 if (ctx
== NULL
) return;
2427 xmlGenericError(xmlGenericErrorContext
,
2428 "SAX.xmlSAX2Characters(%.30s, %d)\n", ch
, len
);
2431 * Handle the data if any. If there is no child
2432 * add it as content, otherwise if the last child is text,
2433 * concatenate it, else create a new node of type text.
2436 if (ctxt
->node
== NULL
) {
2437 #ifdef DEBUG_SAX_TREE
2438 xmlGenericError(xmlGenericErrorContext
,
2439 "add chars: ctxt->node == NULL !\n");
2443 lastChild
= ctxt
->node
->last
;
2444 #ifdef DEBUG_SAX_TREE
2445 xmlGenericError(xmlGenericErrorContext
,
2446 "add chars to %s \n", ctxt
->node
->name
);
2450 * Here we needed an accelerator mechanism in case of very large
2451 * elements. Use an attribute in the structure !!!
2453 if (lastChild
== NULL
) {
2454 lastChild
= xmlSAX2TextNode(ctxt
, ch
, len
);
2455 if (lastChild
!= NULL
) {
2456 ctxt
->node
->children
= lastChild
;
2457 ctxt
->node
->last
= lastChild
;
2458 lastChild
->parent
= ctxt
->node
;
2459 lastChild
->doc
= ctxt
->node
->doc
;
2460 ctxt
->nodelen
= len
;
2461 ctxt
->nodemem
= len
+ 1;
2463 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters");
2467 int coalesceText
= (lastChild
!= NULL
) &&
2468 (lastChild
->type
== XML_TEXT_NODE
) &&
2469 (lastChild
->name
== xmlStringText
);
2470 if ((coalesceText
) && (ctxt
->nodemem
!= 0)) {
2472 * The whole point of maintaining nodelen and nodemem,
2473 * xmlTextConcat is too costly, i.e. compute length,
2474 * reallocate a new buffer, move data, append ch. Here
2475 * We try to minimaze realloc() uses and avoid copying
2476 * and recomputing length over and over.
2478 if (lastChild
->content
== (xmlChar
*)&(lastChild
->properties
)) {
2479 lastChild
->content
= xmlStrdup(lastChild
->content
);
2480 lastChild
->properties
= NULL
;
2481 } else if ((ctxt
->nodemem
== ctxt
->nodelen
+ 1) &&
2482 (xmlDictOwns(ctxt
->dict
, lastChild
->content
))) {
2483 lastChild
->content
= xmlStrdup(lastChild
->content
);
2485 if (((size_t)ctxt
->nodelen
+ (size_t)len
> XML_MAX_TEXT_LENGTH
) &&
2486 ((ctxt
->options
& XML_PARSE_HUGE
) == 0)) {
2487 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters: huge text node");
2490 if ((size_t)ctxt
->nodelen
> SIZE_T_MAX
- (size_t)len
||
2491 (size_t)ctxt
->nodemem
+ (size_t)len
> SIZE_T_MAX
/ 2) {
2492 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters overflow prevented");
2495 if (ctxt
->nodelen
+ len
>= ctxt
->nodemem
) {
2499 size
= ctxt
->nodemem
+ len
;
2501 newbuf
= (xmlChar
*) xmlRealloc(lastChild
->content
,size
);
2502 if (newbuf
== NULL
) {
2503 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters");
2506 ctxt
->nodemem
= size
;
2507 lastChild
->content
= newbuf
;
2509 memcpy(&lastChild
->content
[ctxt
->nodelen
], ch
, len
);
2510 ctxt
->nodelen
+= len
;
2511 lastChild
->content
[ctxt
->nodelen
] = 0;
2512 } else if (coalesceText
) {
2513 if (xmlTextConcat(lastChild
, ch
, len
)) {
2514 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters");
2516 if (ctxt
->node
->children
!= NULL
) {
2517 ctxt
->nodelen
= xmlStrlen(lastChild
->content
);
2518 ctxt
->nodemem
= ctxt
->nodelen
+ 1;
2521 /* Mixed content, first time */
2522 lastChild
= xmlSAX2TextNode(ctxt
, ch
, len
);
2523 if (lastChild
!= NULL
) {
2524 xmlAddChild(ctxt
->node
, lastChild
);
2525 if (ctxt
->node
->children
!= NULL
) {
2526 ctxt
->nodelen
= len
;
2527 ctxt
->nodemem
= len
+ 1;
2535 * xmlSAX2IgnorableWhitespace:
2536 * @ctx: the user data (XML parser context)
2537 * @ch: a xmlChar string
2538 * @len: the number of xmlChar
2540 * receiving some ignorable whitespaces from the parser.
2541 * UNUSED: by default the DOM building will use xmlSAX2Characters
2544 xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED
, const xmlChar
*ch ATTRIBUTE_UNUSED
, int len ATTRIBUTE_UNUSED
)
2546 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
2548 xmlGenericError(xmlGenericErrorContext
,
2549 "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch
, len
);
2554 * xmlSAX2ProcessingInstruction:
2555 * @ctx: the user data (XML parser context)
2556 * @target: the target name
2557 * @data: the PI data's
2559 * A processing instruction has been parsed.
2562 xmlSAX2ProcessingInstruction(void *ctx
, const xmlChar
*target
,
2563 const xmlChar
*data
)
2565 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2569 if (ctx
== NULL
) return;
2570 parent
= ctxt
->node
;
2572 xmlGenericError(xmlGenericErrorContext
,
2573 "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target
, data
);
2576 ret
= xmlNewDocPI(ctxt
->myDoc
, target
, data
);
2577 if (ret
== NULL
) return;
2579 if (ctxt
->linenumbers
) {
2580 if (ctxt
->input
!= NULL
) {
2581 if (ctxt
->input
->line
< 65535)
2582 ret
->line
= (short) ctxt
->input
->line
;
2587 if (ctxt
->inSubset
== 1) {
2588 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->intSubset
, ret
);
2590 } else if (ctxt
->inSubset
== 2) {
2591 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->extSubset
, ret
);
2594 if ((ctxt
->myDoc
->children
== NULL
) || (parent
== NULL
)) {
2595 #ifdef DEBUG_SAX_TREE
2596 xmlGenericError(xmlGenericErrorContext
,
2597 "Setting PI %s as root\n", target
);
2599 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
2602 if (parent
->type
== XML_ELEMENT_NODE
) {
2603 #ifdef DEBUG_SAX_TREE
2604 xmlGenericError(xmlGenericErrorContext
,
2605 "adding PI %s child to %s\n", target
, parent
->name
);
2607 xmlAddChild(parent
, ret
);
2609 #ifdef DEBUG_SAX_TREE
2610 xmlGenericError(xmlGenericErrorContext
,
2611 "adding PI %s sibling to ", target
);
2612 xmlDebugDumpOneNode(stderr
, parent
, 0);
2614 xmlAddSibling(parent
, ret
);
2620 * @ctx: the user data (XML parser context)
2621 * @value: the xmlSAX2Comment content
2623 * A xmlSAX2Comment has been parsed.
2626 xmlSAX2Comment(void *ctx
, const xmlChar
*value
)
2628 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2632 if (ctx
== NULL
) return;
2633 parent
= ctxt
->node
;
2635 xmlGenericError(xmlGenericErrorContext
, "SAX.xmlSAX2Comment(%s)\n", value
);
2637 ret
= xmlNewDocComment(ctxt
->myDoc
, value
);
2638 if (ret
== NULL
) return;
2639 if (ctxt
->linenumbers
) {
2640 if (ctxt
->input
!= NULL
) {
2641 if (ctxt
->input
->line
< 65535)
2642 ret
->line
= (short) ctxt
->input
->line
;
2648 if (ctxt
->inSubset
== 1) {
2649 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->intSubset
, ret
);
2651 } else if (ctxt
->inSubset
== 2) {
2652 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->extSubset
, ret
);
2655 if ((ctxt
->myDoc
->children
== NULL
) || (parent
== NULL
)) {
2656 #ifdef DEBUG_SAX_TREE
2657 xmlGenericError(xmlGenericErrorContext
,
2658 "Setting xmlSAX2Comment as root\n");
2660 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
2663 if (parent
->type
== XML_ELEMENT_NODE
) {
2664 #ifdef DEBUG_SAX_TREE
2665 xmlGenericError(xmlGenericErrorContext
,
2666 "adding xmlSAX2Comment child to %s\n", parent
->name
);
2668 xmlAddChild(parent
, ret
);
2670 #ifdef DEBUG_SAX_TREE
2671 xmlGenericError(xmlGenericErrorContext
,
2672 "adding xmlSAX2Comment sibling to ");
2673 xmlDebugDumpOneNode(stderr
, parent
, 0);
2675 xmlAddSibling(parent
, ret
);
2680 * xmlSAX2CDataBlock:
2681 * @ctx: the user data (XML parser context)
2682 * @value: The pcdata content
2683 * @len: the block length
2685 * called when a pcdata block has been parsed
2688 xmlSAX2CDataBlock(void *ctx
, const xmlChar
*value
, int len
)
2690 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2691 xmlNodePtr ret
, lastChild
;
2693 if (ctx
== NULL
) return;
2695 xmlGenericError(xmlGenericErrorContext
,
2696 "SAX.pcdata(%.10s, %d)\n", value
, len
);
2698 lastChild
= xmlGetLastChild(ctxt
->node
);
2699 #ifdef DEBUG_SAX_TREE
2700 xmlGenericError(xmlGenericErrorContext
,
2701 "add chars to %s \n", ctxt
->node
->name
);
2703 if ((lastChild
!= NULL
) &&
2704 (lastChild
->type
== XML_CDATA_SECTION_NODE
)) {
2705 xmlTextConcat(lastChild
, value
, len
);
2707 ret
= xmlNewCDataBlock(ctxt
->myDoc
, value
, len
);
2708 xmlAddChild(ctxt
->node
, ret
);
2712 static int xmlSAX2DefaultVersionValue
= 2;
2714 #ifdef LIBXML_SAX1_ENABLED
2716 * xmlSAXDefaultVersion:
2717 * @version: the version, 1 or 2
2719 * Set the default version of SAX used globally by the library.
2720 * By default, during initialization the default is set to 2.
2721 * Note that it is generally a better coding style to use
2722 * xmlSAXVersion() to set up the version explicitly for a given
2725 * Returns the previous value in case of success and -1 in case of error.
2728 xmlSAXDefaultVersion(int version
)
2730 int ret
= xmlSAX2DefaultVersionValue
;
2732 if ((version
!= 1) && (version
!= 2))
2734 xmlSAX2DefaultVersionValue
= version
;
2737 #endif /* LIBXML_SAX1_ENABLED */
2741 * @hdlr: the SAX handler
2742 * @version: the version, 1 or 2
2744 * Initialize the default XML SAX handler according to the version
2746 * Returns 0 in case of success and -1 in case of error.
2749 xmlSAXVersion(xmlSAXHandler
*hdlr
, int version
)
2751 if (hdlr
== NULL
) return(-1);
2753 hdlr
->startElement
= NULL
;
2754 hdlr
->endElement
= NULL
;
2755 hdlr
->startElementNs
= xmlSAX2StartElementNs
;
2756 hdlr
->endElementNs
= xmlSAX2EndElementNs
;
2757 hdlr
->serror
= NULL
;
2758 hdlr
->initialized
= XML_SAX2_MAGIC
;
2759 #ifdef LIBXML_SAX1_ENABLED
2760 } else if (version
== 1) {
2761 hdlr
->startElement
= xmlSAX2StartElement
;
2762 hdlr
->endElement
= xmlSAX2EndElement
;
2763 hdlr
->initialized
= 1;
2764 #endif /* LIBXML_SAX1_ENABLED */
2767 hdlr
->internalSubset
= xmlSAX2InternalSubset
;
2768 hdlr
->externalSubset
= xmlSAX2ExternalSubset
;
2769 hdlr
->isStandalone
= xmlSAX2IsStandalone
;
2770 hdlr
->hasInternalSubset
= xmlSAX2HasInternalSubset
;
2771 hdlr
->hasExternalSubset
= xmlSAX2HasExternalSubset
;
2772 hdlr
->resolveEntity
= xmlSAX2ResolveEntity
;
2773 hdlr
->getEntity
= xmlSAX2GetEntity
;
2774 hdlr
->getParameterEntity
= xmlSAX2GetParameterEntity
;
2775 hdlr
->entityDecl
= xmlSAX2EntityDecl
;
2776 hdlr
->attributeDecl
= xmlSAX2AttributeDecl
;
2777 hdlr
->elementDecl
= xmlSAX2ElementDecl
;
2778 hdlr
->notationDecl
= xmlSAX2NotationDecl
;
2779 hdlr
->unparsedEntityDecl
= xmlSAX2UnparsedEntityDecl
;
2780 hdlr
->setDocumentLocator
= xmlSAX2SetDocumentLocator
;
2781 hdlr
->startDocument
= xmlSAX2StartDocument
;
2782 hdlr
->endDocument
= xmlSAX2EndDocument
;
2783 hdlr
->reference
= xmlSAX2Reference
;
2784 hdlr
->characters
= xmlSAX2Characters
;
2785 hdlr
->cdataBlock
= xmlSAX2CDataBlock
;
2786 hdlr
->ignorableWhitespace
= xmlSAX2Characters
;
2787 hdlr
->processingInstruction
= xmlSAX2ProcessingInstruction
;
2788 hdlr
->comment
= xmlSAX2Comment
;
2789 hdlr
->warning
= xmlParserWarning
;
2790 hdlr
->error
= xmlParserError
;
2791 hdlr
->fatalError
= xmlParserError
;
2797 * xmlSAX2InitDefaultSAXHandler:
2798 * @hdlr: the SAX handler
2799 * @warning: flag if non-zero sets the handler warning procedure
2801 * Initialize the default XML SAX2 handler
2804 xmlSAX2InitDefaultSAXHandler(xmlSAXHandler
*hdlr
, int warning
)
2806 if ((hdlr
== NULL
) || (hdlr
->initialized
!= 0))
2809 xmlSAXVersion(hdlr
, xmlSAX2DefaultVersionValue
);
2811 hdlr
->warning
= NULL
;
2813 hdlr
->warning
= xmlParserWarning
;
2817 * xmlDefaultSAXHandlerInit:
2819 * Initialize the default SAX2 handler
2822 xmlDefaultSAXHandlerInit(void)
2824 #ifdef LIBXML_SAX1_ENABLED
2825 xmlSAXVersion((xmlSAXHandlerPtr
) &xmlDefaultSAXHandler
, 1);
2826 #endif /* LIBXML_SAX1_ENABLED */
2829 #ifdef LIBXML_HTML_ENABLED
2832 * xmlSAX2InitHtmlDefaultSAXHandler:
2833 * @hdlr: the SAX handler
2835 * Initialize the default HTML SAX2 handler
2838 xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler
*hdlr
)
2840 if ((hdlr
== NULL
) || (hdlr
->initialized
!= 0))
2843 hdlr
->internalSubset
= xmlSAX2InternalSubset
;
2844 hdlr
->externalSubset
= NULL
;
2845 hdlr
->isStandalone
= NULL
;
2846 hdlr
->hasInternalSubset
= NULL
;
2847 hdlr
->hasExternalSubset
= NULL
;
2848 hdlr
->resolveEntity
= NULL
;
2849 hdlr
->getEntity
= xmlSAX2GetEntity
;
2850 hdlr
->getParameterEntity
= NULL
;
2851 hdlr
->entityDecl
= NULL
;
2852 hdlr
->attributeDecl
= NULL
;
2853 hdlr
->elementDecl
= NULL
;
2854 hdlr
->notationDecl
= NULL
;
2855 hdlr
->unparsedEntityDecl
= NULL
;
2856 hdlr
->setDocumentLocator
= xmlSAX2SetDocumentLocator
;
2857 hdlr
->startDocument
= xmlSAX2StartDocument
;
2858 hdlr
->endDocument
= xmlSAX2EndDocument
;
2859 hdlr
->startElement
= xmlSAX2StartElement
;
2860 hdlr
->endElement
= xmlSAX2EndElement
;
2861 hdlr
->reference
= NULL
;
2862 hdlr
->characters
= xmlSAX2Characters
;
2863 hdlr
->cdataBlock
= xmlSAX2CDataBlock
;
2864 hdlr
->ignorableWhitespace
= xmlSAX2IgnorableWhitespace
;
2865 hdlr
->processingInstruction
= xmlSAX2ProcessingInstruction
;
2866 hdlr
->comment
= xmlSAX2Comment
;
2867 hdlr
->warning
= xmlParserWarning
;
2868 hdlr
->error
= xmlParserError
;
2869 hdlr
->fatalError
= xmlParserError
;
2871 hdlr
->initialized
= 1;
2875 * htmlDefaultSAXHandlerInit:
2877 * Initialize the default SAX handler
2880 htmlDefaultSAXHandlerInit(void)
2882 xmlSAX2InitHtmlDefaultSAXHandler((xmlSAXHandlerPtr
) &htmlDefaultSAXHandler
);
2885 #endif /* LIBXML_HTML_ENABLED */
2887 #ifdef LIBXML_DOCB_ENABLED
2890 * xmlSAX2InitDocbDefaultSAXHandler:
2891 * @hdlr: the SAX handler
2893 * Initialize the default DocBook SAX2 handler
2896 xmlSAX2InitDocbDefaultSAXHandler(xmlSAXHandler
*hdlr
)
2898 if ((hdlr
== NULL
) || (hdlr
->initialized
!= 0))
2901 hdlr
->internalSubset
= xmlSAX2InternalSubset
;
2902 hdlr
->externalSubset
= NULL
;
2903 hdlr
->isStandalone
= xmlSAX2IsStandalone
;
2904 hdlr
->hasInternalSubset
= xmlSAX2HasInternalSubset
;
2905 hdlr
->hasExternalSubset
= xmlSAX2HasExternalSubset
;
2906 hdlr
->resolveEntity
= xmlSAX2ResolveEntity
;
2907 hdlr
->getEntity
= xmlSAX2GetEntity
;
2908 hdlr
->getParameterEntity
= NULL
;
2909 hdlr
->entityDecl
= xmlSAX2EntityDecl
;
2910 hdlr
->attributeDecl
= NULL
;
2911 hdlr
->elementDecl
= NULL
;
2912 hdlr
->notationDecl
= NULL
;
2913 hdlr
->unparsedEntityDecl
= NULL
;
2914 hdlr
->setDocumentLocator
= xmlSAX2SetDocumentLocator
;
2915 hdlr
->startDocument
= xmlSAX2StartDocument
;
2916 hdlr
->endDocument
= xmlSAX2EndDocument
;
2917 hdlr
->startElement
= xmlSAX2StartElement
;
2918 hdlr
->endElement
= xmlSAX2EndElement
;
2919 hdlr
->reference
= xmlSAX2Reference
;
2920 hdlr
->characters
= xmlSAX2Characters
;
2921 hdlr
->cdataBlock
= NULL
;
2922 hdlr
->ignorableWhitespace
= xmlSAX2IgnorableWhitespace
;
2923 hdlr
->processingInstruction
= NULL
;
2924 hdlr
->comment
= xmlSAX2Comment
;
2925 hdlr
->warning
= xmlParserWarning
;
2926 hdlr
->error
= xmlParserError
;
2927 hdlr
->fatalError
= xmlParserError
;
2929 hdlr
->initialized
= 1;
2933 * docbDefaultSAXHandlerInit:
2935 * Initialize the default SAX handler
2938 docbDefaultSAXHandlerInit(void)
2940 xmlSAX2InitDocbDefaultSAXHandler((xmlSAXHandlerPtr
) &docbDefaultSAXHandler
);
2943 #endif /* LIBXML_DOCB_ENABLED */
2945 #include "elfgcchack.h"