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 /* Define SIZE_T_MAX unless defined through <limits.h>. */
33 # define SIZE_T_MAX ((size_t)-1)
34 #endif /* !SIZE_T_MAX */
36 /* #define DEBUG_SAX2 */
37 /* #define DEBUG_SAX2_TREE */
42 * macro to flag unimplemented blocks
43 * XML_CATALOG_PREFER user env to select between system/public prefered
44 * option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk>
45 *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with
46 *> values "system" and "public". I have made the default be "system" to
50 xmlGenericError(xmlGenericErrorContext, \
51 "Unimplemented block at %s:%d\n", \
56 * @ctxt: an XML validation parser context
57 * @msg: a string to accompany the error message
59 static void LIBXML_ATTR_FORMAT(2,0)
60 xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt
, const char *msg
) {
61 xmlStructuredErrorFunc schannel
= NULL
;
62 const char *str1
= "out of memory\n";
65 ctxt
->errNo
= XML_ERR_NO_MEMORY
;
66 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->initialized
== XML_SAX2_MAGIC
))
67 schannel
= ctxt
->sax
->serror
;
68 __xmlRaiseError(schannel
,
69 ctxt
->vctxt
.error
, ctxt
->vctxt
.userData
,
70 ctxt
, NULL
, XML_FROM_PARSER
, XML_ERR_NO_MEMORY
,
71 XML_ERR_ERROR
, NULL
, 0, (const char *) str1
,
73 msg
, (const char *) str1
, NULL
);
74 ctxt
->errNo
= XML_ERR_NO_MEMORY
;
75 ctxt
->instate
= XML_PARSER_EOF
;
78 __xmlRaiseError(schannel
,
80 ctxt
, NULL
, XML_FROM_PARSER
, XML_ERR_NO_MEMORY
,
81 XML_ERR_ERROR
, NULL
, 0, (const char *) str1
,
83 msg
, (const char *) str1
, NULL
);
89 * @ctxt: an XML validation parser context
90 * @error: the error number
91 * @msg: the error message
95 * Handle a validation error
97 static void LIBXML_ATTR_FORMAT(3,0)
98 xmlErrValid(xmlParserCtxtPtr ctxt
, xmlParserErrors error
,
99 const char *msg
, const char *str1
, const char *str2
)
101 xmlStructuredErrorFunc schannel
= NULL
;
103 if ((ctxt
!= NULL
) && (ctxt
->disableSAX
!= 0) &&
104 (ctxt
->instate
== XML_PARSER_EOF
))
108 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->initialized
== XML_SAX2_MAGIC
))
109 schannel
= ctxt
->sax
->serror
;
110 __xmlRaiseError(schannel
,
111 ctxt
->vctxt
.error
, ctxt
->vctxt
.userData
,
112 ctxt
, NULL
, XML_FROM_DTD
, error
,
113 XML_ERR_ERROR
, NULL
, 0, (const char *) str1
,
114 (const char *) str2
, NULL
, 0, 0,
115 msg
, (const char *) str1
, (const char *) str2
);
118 __xmlRaiseError(schannel
,
120 ctxt
, NULL
, XML_FROM_DTD
, error
,
121 XML_ERR_ERROR
, NULL
, 0, (const char *) str1
,
122 (const char *) str2
, NULL
, 0, 0,
123 msg
, (const char *) str1
, (const char *) str2
);
129 * @ctxt: an XML parser context
130 * @error: the error number
131 * @msg: the error message
132 * @str1: an error string
133 * @str2: an error string
135 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
137 static void LIBXML_ATTR_FORMAT(3,0)
138 xmlFatalErrMsg(xmlParserCtxtPtr ctxt
, xmlParserErrors error
,
139 const char *msg
, const xmlChar
*str1
, const xmlChar
*str2
)
141 if ((ctxt
!= NULL
) && (ctxt
->disableSAX
!= 0) &&
142 (ctxt
->instate
== XML_PARSER_EOF
))
146 __xmlRaiseError(NULL
, NULL
, NULL
, ctxt
, NULL
, XML_FROM_PARSER
, error
,
147 XML_ERR_FATAL
, NULL
, 0,
148 (const char *) str1
, (const char *) str2
,
149 NULL
, 0, 0, msg
, str1
, str2
);
151 ctxt
->wellFormed
= 0;
153 if (ctxt
->recovery
== 0)
154 ctxt
->disableSAX
= 1;
160 * @ctxt: an XML parser context
161 * @error: the error number
162 * @msg: the error message
163 * @str1: an error string
164 * @str2: an error string
166 * Handle a parser warning
168 static void LIBXML_ATTR_FORMAT(3,0)
169 xmlWarnMsg(xmlParserCtxtPtr ctxt
, xmlParserErrors error
,
170 const char *msg
, const xmlChar
*str1
)
172 if ((ctxt
!= NULL
) && (ctxt
->disableSAX
!= 0) &&
173 (ctxt
->instate
== XML_PARSER_EOF
))
177 __xmlRaiseError(NULL
, NULL
, NULL
, ctxt
, NULL
, XML_FROM_PARSER
, error
,
178 XML_ERR_WARNING
, NULL
, 0,
179 (const char *) str1
, NULL
,
180 NULL
, 0, 0, msg
, str1
);
185 * @ctxt: an XML parser context
186 * @error: the error number
187 * @msg: the error message
188 * @str1: an error string
189 * @str2: an error string
191 * Handle a namespace error
193 static void LIBXML_ATTR_FORMAT(3,0)
194 xmlNsErrMsg(xmlParserCtxtPtr ctxt
, xmlParserErrors error
,
195 const char *msg
, const xmlChar
*str1
, const xmlChar
*str2
)
197 if ((ctxt
!= NULL
) && (ctxt
->disableSAX
!= 0) &&
198 (ctxt
->instate
== XML_PARSER_EOF
))
202 __xmlRaiseError(NULL
, NULL
, NULL
, ctxt
, NULL
, XML_FROM_NAMESPACE
, error
,
203 XML_ERR_ERROR
, NULL
, 0,
204 (const char *) str1
, (const char *) str2
,
205 NULL
, 0, 0, msg
, str1
, str2
);
210 * @ctxt: an XML parser context
211 * @error: the error number
212 * @msg: the error message
213 * @str1: an error string
215 * Handle a namespace warning
217 static void LIBXML_ATTR_FORMAT(3,0)
218 xmlNsWarnMsg(xmlParserCtxtPtr ctxt
, xmlParserErrors error
,
219 const char *msg
, const xmlChar
*str1
, const xmlChar
*str2
)
221 if ((ctxt
!= NULL
) && (ctxt
->disableSAX
!= 0) &&
222 (ctxt
->instate
== XML_PARSER_EOF
))
226 __xmlRaiseError(NULL
, NULL
, NULL
, ctxt
, NULL
, XML_FROM_NAMESPACE
, error
,
227 XML_ERR_WARNING
, NULL
, 0,
228 (const char *) str1
, (const char *) str2
,
229 NULL
, 0, 0, msg
, str1
, str2
);
233 * xmlSAX2GetPublicId:
234 * @ctx: the user data (XML parser context)
236 * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
238 * Returns a xmlChar *
241 xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED
)
243 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
248 * xmlSAX2GetSystemId:
249 * @ctx: the user data (XML parser context)
251 * Provides the system ID, basically URL or filename e.g.
252 * http://www.sgmlsource.com/dtds/memo.dtd
254 * Returns a xmlChar *
257 xmlSAX2GetSystemId(void *ctx
)
259 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
260 if ((ctx
== NULL
) || (ctxt
->input
== NULL
)) return(NULL
);
261 return((const xmlChar
*) ctxt
->input
->filename
);
265 * xmlSAX2GetLineNumber:
266 * @ctx: the user data (XML parser context)
268 * Provide the line number of the current parsing point.
273 xmlSAX2GetLineNumber(void *ctx
)
275 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
276 if ((ctx
== NULL
) || (ctxt
->input
== NULL
)) return(0);
277 return(ctxt
->input
->line
);
281 * xmlSAX2GetColumnNumber:
282 * @ctx: the user data (XML parser context)
284 * Provide the column number of the current parsing point.
289 xmlSAX2GetColumnNumber(void *ctx
)
291 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
292 if ((ctx
== NULL
) || (ctxt
->input
== NULL
)) return(0);
293 return(ctxt
->input
->col
);
297 * xmlSAX2IsStandalone:
298 * @ctx: the user data (XML parser context)
300 * Is this document tagged standalone ?
305 xmlSAX2IsStandalone(void *ctx
)
307 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
308 if ((ctx
== NULL
) || (ctxt
->myDoc
== NULL
)) return(0);
309 return(ctxt
->myDoc
->standalone
== 1);
313 * xmlSAX2HasInternalSubset:
314 * @ctx: the user data (XML parser context)
316 * Does this document has an internal subset
321 xmlSAX2HasInternalSubset(void *ctx
)
323 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
324 if ((ctxt
== NULL
) || (ctxt
->myDoc
== NULL
)) return(0);
325 return(ctxt
->myDoc
->intSubset
!= NULL
);
329 * xmlSAX2HasExternalSubset:
330 * @ctx: the user data (XML parser context)
332 * Does this document has an external subset
337 xmlSAX2HasExternalSubset(void *ctx
)
339 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
340 if ((ctxt
== NULL
) || (ctxt
->myDoc
== NULL
)) return(0);
341 return(ctxt
->myDoc
->extSubset
!= NULL
);
345 * xmlSAX2InternalSubset:
346 * @ctx: the user data (XML parser context)
347 * @name: the root element name
348 * @ExternalID: the external ID
349 * @SystemID: the SYSTEM ID (e.g. filename or URL)
351 * Callback on internal subset declaration.
354 xmlSAX2InternalSubset(void *ctx
, const xmlChar
*name
,
355 const xmlChar
*ExternalID
, const xmlChar
*SystemID
)
357 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
359 if (ctx
== NULL
) return;
361 xmlGenericError(xmlGenericErrorContext
,
362 "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n",
363 name
, ExternalID
, SystemID
);
366 if (ctxt
->myDoc
== NULL
)
368 dtd
= xmlGetIntSubset(ctxt
->myDoc
);
372 xmlUnlinkNode((xmlNodePtr
) dtd
);
374 ctxt
->myDoc
->intSubset
= NULL
;
376 ctxt
->myDoc
->intSubset
=
377 xmlCreateIntSubset(ctxt
->myDoc
, name
, ExternalID
, SystemID
);
378 if (ctxt
->myDoc
->intSubset
== NULL
)
379 xmlSAX2ErrMemory(ctxt
, "xmlSAX2InternalSubset");
383 * xmlSAX2ExternalSubset:
384 * @ctx: the user data (XML parser context)
385 * @name: the root element name
386 * @ExternalID: the external ID
387 * @SystemID: the SYSTEM ID (e.g. filename or URL)
389 * Callback on external subset declaration.
392 xmlSAX2ExternalSubset(void *ctx
, const xmlChar
*name
,
393 const xmlChar
*ExternalID
, const xmlChar
*SystemID
)
395 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
396 if (ctx
== NULL
) return;
398 xmlGenericError(xmlGenericErrorContext
,
399 "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n",
400 name
, ExternalID
, SystemID
);
402 if (((ExternalID
!= NULL
) || (SystemID
!= NULL
)) &&
403 (((ctxt
->validate
) || (ctxt
->loadsubset
!= 0)) &&
404 (ctxt
->wellFormed
&& ctxt
->myDoc
))) {
406 * Try to fetch and parse the external subset.
408 xmlParserInputPtr oldinput
;
411 xmlParserInputPtr
*oldinputTab
;
412 xmlParserInputPtr input
= NULL
;
415 const xmlChar
*oldencoding
;
418 * Ask the Entity resolver to load the damn thing
420 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->resolveEntity
!= NULL
))
421 input
= ctxt
->sax
->resolveEntity(ctxt
->userData
, ExternalID
,
427 xmlNewDtd(ctxt
->myDoc
, name
, ExternalID
, SystemID
);
430 * make sure we won't destroy the main document context
432 oldinput
= ctxt
->input
;
433 oldinputNr
= ctxt
->inputNr
;
434 oldinputMax
= ctxt
->inputMax
;
435 oldinputTab
= ctxt
->inputTab
;
436 oldcharset
= ctxt
->charset
;
437 oldencoding
= ctxt
->encoding
;
438 ctxt
->encoding
= NULL
;
440 ctxt
->inputTab
= (xmlParserInputPtr
*)
441 xmlMalloc(5 * sizeof(xmlParserInputPtr
));
442 if (ctxt
->inputTab
== NULL
) {
443 xmlSAX2ErrMemory(ctxt
, "xmlSAX2ExternalSubset");
444 ctxt
->input
= oldinput
;
445 ctxt
->inputNr
= oldinputNr
;
446 ctxt
->inputMax
= oldinputMax
;
447 ctxt
->inputTab
= oldinputTab
;
448 ctxt
->charset
= oldcharset
;
449 ctxt
->encoding
= oldencoding
;
455 xmlPushInput(ctxt
, input
);
458 * On the fly encoding conversion if needed
460 if (ctxt
->input
->length
>= 4) {
461 enc
= xmlDetectCharEncoding(ctxt
->input
->cur
, 4);
462 xmlSwitchEncoding(ctxt
, enc
);
465 if (input
->filename
== NULL
)
466 input
->filename
= (char *) xmlCanonicPath(SystemID
);
469 input
->base
= ctxt
->input
->cur
;
470 input
->cur
= ctxt
->input
->cur
;
474 * let's parse that entity knowing it's an external subset.
476 xmlParseExternalSubset(ctxt
, ExternalID
, SystemID
);
479 * Free up the external entities
482 while (ctxt
->inputNr
> 1)
484 xmlFreeInputStream(ctxt
->input
);
485 xmlFree(ctxt
->inputTab
);
488 * Restore the parsing context of the main entity
490 ctxt
->input
= oldinput
;
491 ctxt
->inputNr
= oldinputNr
;
492 ctxt
->inputMax
= oldinputMax
;
493 ctxt
->inputTab
= oldinputTab
;
494 ctxt
->charset
= oldcharset
;
495 if ((ctxt
->encoding
!= NULL
) &&
496 ((ctxt
->dict
== NULL
) ||
497 (!xmlDictOwns(ctxt
->dict
, ctxt
->encoding
))))
498 xmlFree((xmlChar
*) ctxt
->encoding
);
499 ctxt
->encoding
= oldencoding
;
500 /* ctxt->wellFormed = oldwellFormed; */
505 * xmlSAX2ResolveEntity:
506 * @ctx: the user data (XML parser context)
507 * @publicId: The public ID of the entity
508 * @systemId: The system ID of the entity
510 * The entity loader, to control the loading of external entities,
511 * the application can either:
512 * - override this xmlSAX2ResolveEntity() callback in the SAX block
513 * - or better use the xmlSetExternalEntityLoader() function to
514 * set up it's own entity resolution routine
516 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
519 xmlSAX2ResolveEntity(void *ctx
, const xmlChar
*publicId
, const xmlChar
*systemId
)
521 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
522 xmlParserInputPtr ret
;
524 const char *base
= NULL
;
526 if (ctx
== NULL
) return(NULL
);
527 if (ctxt
->input
!= NULL
)
528 base
= ctxt
->input
->filename
;
530 base
= ctxt
->directory
;
532 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
535 xmlGenericError(xmlGenericErrorContext
,
536 "SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId
, systemId
);
539 ret
= xmlLoadExternalEntity((const char *) URI
,
540 (const char *) publicId
, ctxt
);
548 * @ctx: the user data (XML parser context)
549 * @name: The entity name
551 * Get an entity by name
553 * Returns the xmlEntityPtr if found.
556 xmlSAX2GetEntity(void *ctx
, const xmlChar
*name
)
558 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
559 xmlEntityPtr ret
= NULL
;
561 if (ctx
== NULL
) return(NULL
);
563 xmlGenericError(xmlGenericErrorContext
,
564 "SAX.xmlSAX2GetEntity(%s)\n", name
);
567 if (ctxt
->inSubset
== 0) {
568 ret
= xmlGetPredefinedEntity(name
);
572 if ((ctxt
->myDoc
!= NULL
) && (ctxt
->myDoc
->standalone
== 1)) {
573 if (ctxt
->inSubset
== 2) {
574 ctxt
->myDoc
->standalone
= 0;
575 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
576 ctxt
->myDoc
->standalone
= 1;
578 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
580 ctxt
->myDoc
->standalone
= 0;
581 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
583 xmlFatalErrMsg(ctxt
, XML_ERR_NOT_STANDALONE
,
584 "Entity(%s) document marked standalone but requires external subset\n",
587 ctxt
->myDoc
->standalone
= 1;
591 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
594 ((ctxt
->validate
) || (ctxt
->replaceEntities
)) &&
595 (ret
->children
== NULL
) &&
596 (ret
->etype
== XML_EXTERNAL_GENERAL_PARSED_ENTITY
)) {
600 * for validation purposes we really need to fetch and
601 * parse the external entity
604 unsigned long oldnbent
= ctxt
->nbentities
;
606 val
= xmlParseCtxtExternalEntity(ctxt
, ret
->URI
,
607 ret
->ExternalID
, &children
);
609 xmlAddChildList((xmlNodePtr
) ret
, children
);
611 xmlFatalErrMsg(ctxt
, XML_ERR_ENTITY_PROCESSING
,
612 "Failure to process entity %s\n", name
, NULL
);
617 if (ret
->checked
== 0) {
618 ret
->checked
= (ctxt
->nbentities
- oldnbent
+ 1) * 2;
619 if ((ret
->content
!= NULL
) && (xmlStrchr(ret
->content
, '<')))
627 * xmlSAX2GetParameterEntity:
628 * @ctx: the user data (XML parser context)
629 * @name: The entity name
631 * Get a parameter entity by name
633 * Returns the xmlEntityPtr if found.
636 xmlSAX2GetParameterEntity(void *ctx
, const xmlChar
*name
)
638 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
641 if (ctx
== NULL
) return(NULL
);
643 xmlGenericError(xmlGenericErrorContext
,
644 "SAX.xmlSAX2GetParameterEntity(%s)\n", name
);
647 ret
= xmlGetParameterEntity(ctxt
->myDoc
, name
);
654 * @ctx: the user data (XML parser context)
655 * @name: the entity name
656 * @type: the entity type
657 * @publicId: The public ID of the entity
658 * @systemId: The system ID of the entity
659 * @content: the entity value (without processing).
661 * An entity definition has been parsed
664 xmlSAX2EntityDecl(void *ctx
, const xmlChar
*name
, int type
,
665 const xmlChar
*publicId
, const xmlChar
*systemId
, xmlChar
*content
)
668 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
670 if (ctx
== NULL
) return;
672 xmlGenericError(xmlGenericErrorContext
,
673 "SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n",
674 name
, type
, publicId
, systemId
, content
);
676 if (ctxt
->inSubset
== 1) {
677 ent
= xmlAddDocEntity(ctxt
->myDoc
, name
, type
, publicId
,
679 if ((ent
== NULL
) && (ctxt
->pedantic
))
680 xmlWarnMsg(ctxt
, XML_WAR_ENTITY_REDEFINED
,
681 "Entity(%s) already defined in the internal subset\n",
683 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
685 const char *base
= NULL
;
687 if (ctxt
->input
!= NULL
)
688 base
= ctxt
->input
->filename
;
690 base
= ctxt
->directory
;
692 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
695 } else if (ctxt
->inSubset
== 2) {
696 ent
= xmlAddDtdEntity(ctxt
->myDoc
, name
, type
, publicId
,
698 if ((ent
== NULL
) && (ctxt
->pedantic
) &&
699 (ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
700 ctxt
->sax
->warning(ctxt
->userData
,
701 "Entity(%s) already defined in the external subset\n", name
);
702 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
704 const char *base
= NULL
;
706 if (ctxt
->input
!= NULL
)
707 base
= ctxt
->input
->filename
;
709 base
= ctxt
->directory
;
711 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
715 xmlFatalErrMsg(ctxt
, XML_ERR_ENTITY_PROCESSING
,
716 "SAX.xmlSAX2EntityDecl(%s) called while not in subset\n",
722 * xmlSAX2AttributeDecl:
723 * @ctx: the user data (XML parser context)
724 * @elem: the name of the element
725 * @fullname: the attribute name
726 * @type: the attribute type
727 * @def: the type of default value
728 * @defaultValue: the attribute default value
729 * @tree: the tree of enumerated value set
731 * An attribute definition has been parsed
734 xmlSAX2AttributeDecl(void *ctx
, const xmlChar
*elem
, const xmlChar
*fullname
,
735 int type
, int def
, const xmlChar
*defaultValue
,
736 xmlEnumerationPtr tree
)
738 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
739 xmlAttributePtr attr
;
740 xmlChar
*name
= NULL
, *prefix
= NULL
;
742 if ((ctxt
== NULL
) || (ctxt
->myDoc
== NULL
))
746 xmlGenericError(xmlGenericErrorContext
,
747 "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n",
748 elem
, fullname
, type
, def
, defaultValue
);
750 if ((xmlStrEqual(fullname
, BAD_CAST
"xml:id")) &&
751 (type
!= XML_ATTRIBUTE_ID
)) {
753 * Raise the error but keep the validity flag
755 int tmp
= ctxt
->valid
;
756 xmlErrValid(ctxt
, XML_DTD_XMLID_TYPE
,
757 "xml:id : attribute type should be ID\n", NULL
, NULL
);
760 /* TODO: optimize name/prefix allocation */
761 name
= xmlSplitQName(ctxt
, fullname
, &prefix
);
762 ctxt
->vctxt
.valid
= 1;
763 if (ctxt
->inSubset
== 1)
764 attr
= xmlAddAttributeDecl(&ctxt
->vctxt
, ctxt
->myDoc
->intSubset
, elem
,
765 name
, prefix
, (xmlAttributeType
) type
,
766 (xmlAttributeDefault
) def
, defaultValue
, tree
);
767 else if (ctxt
->inSubset
== 2)
768 attr
= xmlAddAttributeDecl(&ctxt
->vctxt
, ctxt
->myDoc
->extSubset
, elem
,
769 name
, prefix
, (xmlAttributeType
) type
,
770 (xmlAttributeDefault
) def
, defaultValue
, tree
);
772 xmlFatalErrMsg(ctxt
, XML_ERR_INTERNAL_ERROR
,
773 "SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n",
775 xmlFreeEnumeration(tree
);
778 #ifdef LIBXML_VALID_ENABLED
779 if (ctxt
->vctxt
.valid
== 0)
781 if ((attr
!= NULL
) && (ctxt
->validate
) && (ctxt
->wellFormed
) &&
782 (ctxt
->myDoc
->intSubset
!= NULL
))
783 ctxt
->valid
&= xmlValidateAttributeDecl(&ctxt
->vctxt
, ctxt
->myDoc
,
785 #endif /* LIBXML_VALID_ENABLED */
793 * xmlSAX2ElementDecl:
794 * @ctx: the user data (XML parser context)
795 * @name: the element name
796 * @type: the element type
797 * @content: the element value tree
799 * An element definition has been parsed
802 xmlSAX2ElementDecl(void *ctx
, const xmlChar
* name
, int type
,
803 xmlElementContentPtr content
)
805 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
806 xmlElementPtr elem
= NULL
;
808 if ((ctxt
== NULL
) || (ctxt
->myDoc
== NULL
))
812 xmlGenericError(xmlGenericErrorContext
,
813 "SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name
, type
);
816 if (ctxt
->inSubset
== 1)
817 elem
= xmlAddElementDecl(&ctxt
->vctxt
, ctxt
->myDoc
->intSubset
,
818 name
, (xmlElementTypeVal
) type
, content
);
819 else if (ctxt
->inSubset
== 2)
820 elem
= xmlAddElementDecl(&ctxt
->vctxt
, ctxt
->myDoc
->extSubset
,
821 name
, (xmlElementTypeVal
) type
, content
);
823 xmlFatalErrMsg(ctxt
, XML_ERR_INTERNAL_ERROR
,
824 "SAX.xmlSAX2ElementDecl(%s) called while not in subset\n",
828 #ifdef LIBXML_VALID_ENABLED
831 if (ctxt
->validate
&& ctxt
->wellFormed
&&
832 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
834 xmlValidateElementDecl(&ctxt
->vctxt
, ctxt
->myDoc
, elem
);
835 #endif /* LIBXML_VALID_ENABLED */
839 * xmlSAX2NotationDecl:
840 * @ctx: the user data (XML parser context)
841 * @name: The name of the notation
842 * @publicId: The public ID of the entity
843 * @systemId: The system ID of the entity
845 * What to do when a notation declaration has been parsed.
848 xmlSAX2NotationDecl(void *ctx
, const xmlChar
*name
,
849 const xmlChar
*publicId
, const xmlChar
*systemId
)
851 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
852 xmlNotationPtr nota
= NULL
;
854 if ((ctxt
== NULL
) || (ctxt
->myDoc
== NULL
))
858 xmlGenericError(xmlGenericErrorContext
,
859 "SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name
, publicId
, systemId
);
862 if ((publicId
== NULL
) && (systemId
== NULL
)) {
863 xmlFatalErrMsg(ctxt
, XML_ERR_NOTATION_PROCESSING
,
864 "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n",
867 } else if (ctxt
->inSubset
== 1)
868 nota
= xmlAddNotationDecl(&ctxt
->vctxt
, ctxt
->myDoc
->intSubset
, name
,
870 else if (ctxt
->inSubset
== 2)
871 nota
= xmlAddNotationDecl(&ctxt
->vctxt
, ctxt
->myDoc
->extSubset
, name
,
874 xmlFatalErrMsg(ctxt
, XML_ERR_NOTATION_PROCESSING
,
875 "SAX.xmlSAX2NotationDecl(%s) called while not in subset\n",
879 #ifdef LIBXML_VALID_ENABLED
880 if (nota
== NULL
) ctxt
->valid
= 0;
881 if ((ctxt
->validate
) && (ctxt
->wellFormed
) &&
882 (ctxt
->myDoc
->intSubset
!= NULL
))
883 ctxt
->valid
&= xmlValidateNotationDecl(&ctxt
->vctxt
, ctxt
->myDoc
,
885 #endif /* LIBXML_VALID_ENABLED */
889 * xmlSAX2UnparsedEntityDecl:
890 * @ctx: the user data (XML parser context)
891 * @name: The name of the entity
892 * @publicId: The public ID of the entity
893 * @systemId: The system ID of the entity
894 * @notationName: the name of the notation
896 * What to do when an unparsed entity declaration is parsed
899 xmlSAX2UnparsedEntityDecl(void *ctx
, const xmlChar
*name
,
900 const xmlChar
*publicId
, const xmlChar
*systemId
,
901 const xmlChar
*notationName
)
904 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
905 if (ctx
== NULL
) return;
907 xmlGenericError(xmlGenericErrorContext
,
908 "SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n",
909 name
, publicId
, systemId
, notationName
);
911 if (ctxt
->inSubset
== 1) {
912 ent
= xmlAddDocEntity(ctxt
->myDoc
, name
,
913 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY
,
914 publicId
, systemId
, notationName
);
915 if ((ent
== NULL
) && (ctxt
->pedantic
) &&
916 (ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
917 ctxt
->sax
->warning(ctxt
->userData
,
918 "Entity(%s) already defined in the internal subset\n", name
);
919 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
921 const char *base
= NULL
;
923 if (ctxt
->input
!= NULL
)
924 base
= ctxt
->input
->filename
;
926 base
= ctxt
->directory
;
928 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
931 } else if (ctxt
->inSubset
== 2) {
932 ent
= xmlAddDtdEntity(ctxt
->myDoc
, name
,
933 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY
,
934 publicId
, systemId
, notationName
);
935 if ((ent
== NULL
) && (ctxt
->pedantic
) &&
936 (ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
937 ctxt
->sax
->warning(ctxt
->userData
,
938 "Entity(%s) already defined in the external subset\n", name
);
939 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
941 const char *base
= NULL
;
943 if (ctxt
->input
!= NULL
)
944 base
= ctxt
->input
->filename
;
946 base
= ctxt
->directory
;
948 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
952 xmlFatalErrMsg(ctxt
, XML_ERR_INTERNAL_ERROR
,
953 "SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n",
959 * xmlSAX2SetDocumentLocator:
960 * @ctx: the user data (XML parser context)
961 * @loc: A SAX Locator
963 * Receive the document locator at startup, actually xmlDefaultSAXLocator
964 * Everything is available on the context, so this is useless in our case.
967 xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED
, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED
)
969 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
971 xmlGenericError(xmlGenericErrorContext
,
972 "SAX.xmlSAX2SetDocumentLocator()\n");
977 * xmlSAX2StartDocument:
978 * @ctx: the user data (XML parser context)
980 * called when the document start being processed.
983 xmlSAX2StartDocument(void *ctx
)
985 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
988 if (ctx
== NULL
) return;
991 xmlGenericError(xmlGenericErrorContext
,
992 "SAX.xmlSAX2StartDocument()\n");
995 #ifdef LIBXML_HTML_ENABLED
996 if (ctxt
->myDoc
== NULL
)
997 ctxt
->myDoc
= htmlNewDocNoDtD(NULL
, NULL
);
998 if (ctxt
->myDoc
== NULL
) {
999 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartDocument");
1002 ctxt
->myDoc
->properties
= XML_DOC_HTML
;
1003 ctxt
->myDoc
->parseFlags
= ctxt
->options
;
1005 xmlGenericError(xmlGenericErrorContext
,
1006 "libxml2 built without HTML support\n");
1007 ctxt
->errNo
= XML_ERR_INTERNAL_ERROR
;
1008 ctxt
->instate
= XML_PARSER_EOF
;
1009 ctxt
->disableSAX
= 1;
1013 doc
= ctxt
->myDoc
= xmlNewDoc(ctxt
->version
);
1015 doc
->properties
= 0;
1016 if (ctxt
->options
& XML_PARSE_OLD10
)
1017 doc
->properties
|= XML_DOC_OLD10
;
1018 doc
->parseFlags
= ctxt
->options
;
1019 if (ctxt
->encoding
!= NULL
)
1020 doc
->encoding
= xmlStrdup(ctxt
->encoding
);
1022 doc
->encoding
= NULL
;
1023 doc
->standalone
= ctxt
->standalone
;
1025 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartDocument");
1028 if ((ctxt
->dictNames
) && (doc
!= NULL
)) {
1029 doc
->dict
= ctxt
->dict
;
1030 xmlDictReference(doc
->dict
);
1033 if ((ctxt
->myDoc
!= NULL
) && (ctxt
->myDoc
->URL
== NULL
) &&
1034 (ctxt
->input
!= NULL
) && (ctxt
->input
->filename
!= NULL
)) {
1035 ctxt
->myDoc
->URL
= xmlPathToURI((const xmlChar
*)ctxt
->input
->filename
);
1036 if (ctxt
->myDoc
->URL
== NULL
)
1037 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartDocument");
1042 * xmlSAX2EndDocument:
1043 * @ctx: the user data (XML parser context)
1045 * called when the document end has been detected.
1048 xmlSAX2EndDocument(void *ctx
)
1050 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1052 xmlGenericError(xmlGenericErrorContext
,
1053 "SAX.xmlSAX2EndDocument()\n");
1055 if (ctx
== NULL
) return;
1056 #ifdef LIBXML_VALID_ENABLED
1057 if (ctxt
->validate
&& ctxt
->wellFormed
&&
1058 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
1059 ctxt
->valid
&= xmlValidateDocumentFinal(&ctxt
->vctxt
, ctxt
->myDoc
);
1060 #endif /* LIBXML_VALID_ENABLED */
1063 * Grab the encoding if it was added on-the-fly
1065 if ((ctxt
->encoding
!= NULL
) && (ctxt
->myDoc
!= NULL
) &&
1066 (ctxt
->myDoc
->encoding
== NULL
)) {
1067 ctxt
->myDoc
->encoding
= ctxt
->encoding
;
1068 ctxt
->encoding
= NULL
;
1070 if ((ctxt
->inputTab
!= NULL
) &&
1071 (ctxt
->inputNr
> 0) && (ctxt
->inputTab
[0] != NULL
) &&
1072 (ctxt
->inputTab
[0]->encoding
!= NULL
) && (ctxt
->myDoc
!= NULL
) &&
1073 (ctxt
->myDoc
->encoding
== NULL
)) {
1074 ctxt
->myDoc
->encoding
= xmlStrdup(ctxt
->inputTab
[0]->encoding
);
1076 if ((ctxt
->charset
!= XML_CHAR_ENCODING_NONE
) && (ctxt
->myDoc
!= NULL
) &&
1077 (ctxt
->myDoc
->charset
== XML_CHAR_ENCODING_NONE
)) {
1078 ctxt
->myDoc
->charset
= ctxt
->charset
;
1082 #if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
1084 * xmlSAX2AttributeInternal:
1085 * @ctx: the user data (XML parser context)
1086 * @fullname: The attribute name, including namespace prefix
1087 * @value: The attribute value
1088 * @prefix: the prefix on the element node
1090 * Handle an attribute that has been read by the parser.
1091 * The default handling is to convert the attribute into an
1092 * DOM subtree and past it in a new xmlAttr element added to
1096 xmlSAX2AttributeInternal(void *ctx
, const xmlChar
*fullname
,
1097 const xmlChar
*value
, const xmlChar
*prefix ATTRIBUTE_UNUSED
)
1099 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1107 name
= xmlStrdup(fullname
);
1112 * Split the full name into a namespace prefix and the tag name
1114 name
= xmlSplitQName(ctxt
, fullname
, &ns
);
1115 if ((name
!= NULL
) && (name
[0] == 0)) {
1116 if (xmlStrEqual(ns
, BAD_CAST
"xmlns")) {
1117 xmlNsErrMsg(ctxt
, XML_ERR_NS_DECL_ERROR
,
1118 "invalid namespace declaration '%s'\n",
1121 xmlNsWarnMsg(ctxt
, XML_WAR_NS_COLUMN
,
1122 "Avoid attribute ending with ':' like '%s'\n",
1129 name
= xmlStrdup(fullname
);
1133 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1139 #ifdef LIBXML_HTML_ENABLED
1141 (value
== NULL
) && (htmlIsBooleanAttr(fullname
))) {
1142 nval
= xmlStrdup(fullname
);
1143 value
= (const xmlChar
*) nval
;
1147 #ifdef LIBXML_VALID_ENABLED
1149 * Do the last stage of the attribute normalization
1150 * Needed for HTML too:
1151 * http://www.w3.org/TR/html4/types.html#h-6.2
1153 ctxt
->vctxt
.valid
= 1;
1154 nval
= xmlValidCtxtNormalizeAttributeValue(&ctxt
->vctxt
,
1155 ctxt
->myDoc
, ctxt
->node
,
1157 if (ctxt
->vctxt
.valid
!= 1) {
1164 #endif /* LIBXML_VALID_ENABLED */
1168 * Check whether it's a namespace definition
1170 if ((!ctxt
->html
) && (ns
== NULL
) &&
1171 (name
[0] == 'x') && (name
[1] == 'm') && (name
[2] == 'l') &&
1172 (name
[3] == 'n') && (name
[4] == 's') && (name
[5] == 0)) {
1176 if (!ctxt
->replaceEntities
) {
1178 val
= xmlStringDecodeEntities(ctxt
, value
, XML_SUBSTITUTE_REF
,
1182 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1190 val
= (xmlChar
*) value
;
1196 uri
= xmlParseURI((const char *)val
);
1198 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
1199 ctxt
->sax
->warning(ctxt
->userData
,
1200 "xmlns: %s not a valid URI\n", val
);
1202 if (uri
->scheme
== NULL
) {
1203 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
1204 ctxt
->sax
->warning(ctxt
->userData
,
1205 "xmlns: URI %s is not absolute\n", val
);
1211 /* a default namespace definition */
1212 nsret
= xmlNewNs(ctxt
->node
, val
, NULL
);
1214 #ifdef LIBXML_VALID_ENABLED
1216 * Validate also for namespace decls, they are attributes from
1217 * an XML-1.0 perspective
1219 if (nsret
!= NULL
&& ctxt
->validate
&& ctxt
->wellFormed
&&
1220 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
1221 ctxt
->valid
&= xmlValidateOneNamespace(&ctxt
->vctxt
, ctxt
->myDoc
,
1222 ctxt
->node
, prefix
, nsret
, val
);
1223 #endif /* LIBXML_VALID_ENABLED */
1232 if ((!ctxt
->html
) &&
1233 (ns
!= NULL
) && (ns
[0] == 'x') && (ns
[1] == 'm') && (ns
[2] == 'l') &&
1234 (ns
[3] == 'n') && (ns
[4] == 's') && (ns
[5] == 0)) {
1238 if (!ctxt
->replaceEntities
) {
1240 val
= xmlStringDecodeEntities(ctxt
, value
, XML_SUBSTITUTE_REF
,
1244 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1253 val
= (xmlChar
*) value
;
1257 xmlNsErrMsg(ctxt
, XML_NS_ERR_EMPTY
,
1258 "Empty namespace name for prefix %s\n", name
, NULL
);
1260 if ((ctxt
->pedantic
!= 0) && (val
[0] != 0)) {
1263 uri
= xmlParseURI((const char *)val
);
1265 xmlNsWarnMsg(ctxt
, XML_WAR_NS_URI
,
1266 "xmlns:%s: %s not a valid URI\n", name
, value
);
1268 if (uri
->scheme
== NULL
) {
1269 xmlNsWarnMsg(ctxt
, XML_WAR_NS_URI_RELATIVE
,
1270 "xmlns:%s: URI %s is not absolute\n", name
, value
);
1276 /* a standard namespace definition */
1277 nsret
= xmlNewNs(ctxt
->node
, val
, name
);
1279 #ifdef LIBXML_VALID_ENABLED
1281 * Validate also for namespace decls, they are attributes from
1282 * an XML-1.0 perspective
1284 if (nsret
!= NULL
&& ctxt
->validate
&& ctxt
->wellFormed
&&
1285 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
1286 ctxt
->valid
&= xmlValidateOneNamespace(&ctxt
->vctxt
, ctxt
->myDoc
,
1287 ctxt
->node
, prefix
, nsret
, value
);
1288 #endif /* LIBXML_VALID_ENABLED */
1299 namespace = xmlSearchNs(ctxt
->myDoc
, ctxt
->node
, ns
);
1301 if (namespace == NULL
) {
1302 xmlNsErrMsg(ctxt
, XML_NS_ERR_UNDEFINED_NAMESPACE
,
1303 "Namespace prefix %s of attribute %s is not defined\n",
1308 prop
= ctxt
->node
->properties
;
1309 while (prop
!= NULL
) {
1310 if (prop
->ns
!= NULL
) {
1311 if ((xmlStrEqual(name
, prop
->name
)) &&
1312 ((namespace == prop
->ns
) ||
1313 (xmlStrEqual(namespace->href
, prop
->ns
->href
)))) {
1314 xmlNsErrMsg(ctxt
, XML_ERR_ATTRIBUTE_REDEFINED
,
1315 "Attribute %s in %s redefined\n",
1316 name
, namespace->href
);
1317 ctxt
->wellFormed
= 0;
1318 if (ctxt
->recovery
== 0) ctxt
->disableSAX
= 1;
1331 /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
1332 ret
= xmlNewNsPropEatName(ctxt
->node
, namespace, name
, NULL
);
1335 if ((ctxt
->replaceEntities
== 0) && (!ctxt
->html
)) {
1338 ret
->children
= xmlStringGetNodeList(ctxt
->myDoc
, value
);
1339 tmp
= ret
->children
;
1340 while (tmp
!= NULL
) {
1341 tmp
->parent
= (xmlNodePtr
) ret
;
1342 if (tmp
->next
== NULL
)
1346 } else if (value
!= NULL
) {
1347 ret
->children
= xmlNewDocText(ctxt
->myDoc
, value
);
1348 ret
->last
= ret
->children
;
1349 if (ret
->children
!= NULL
)
1350 ret
->children
->parent
= (xmlNodePtr
) ret
;
1354 #ifdef LIBXML_VALID_ENABLED
1355 if ((!ctxt
->html
) && ctxt
->validate
&& ctxt
->wellFormed
&&
1356 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
) {
1359 * If we don't substitute entities, the validation should be
1360 * done on a value with replaced entities anyway.
1362 if (!ctxt
->replaceEntities
) {
1366 val
= xmlStringDecodeEntities(ctxt
, value
, XML_SUBSTITUTE_REF
,
1371 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
1372 ctxt
->myDoc
, ctxt
->node
, ret
, value
);
1377 * Do the last stage of the attribute normalization
1378 * It need to be done twice ... it's an extra burden related
1379 * to the ability to keep xmlSAX2References in attributes
1381 nvalnorm
= xmlValidNormalizeAttributeValue(ctxt
->myDoc
,
1382 ctxt
->node
, fullname
, val
);
1383 if (nvalnorm
!= NULL
) {
1388 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
1389 ctxt
->myDoc
, ctxt
->node
, ret
, val
);
1393 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
, ctxt
->myDoc
,
1394 ctxt
->node
, ret
, value
);
1397 #endif /* LIBXML_VALID_ENABLED */
1398 if (((ctxt
->loadsubset
& XML_SKIP_IDS
) == 0) &&
1399 (((ctxt
->replaceEntities
== 0) && (ctxt
->external
!= 2)) ||
1400 ((ctxt
->replaceEntities
!= 0) && (ctxt
->inSubset
== 0)))) {
1402 * when validating, the ID registration is done at the attribute
1403 * validation level. Otherwise we have to do specific handling here.
1405 if (xmlStrEqual(fullname
, BAD_CAST
"xml:id")) {
1407 * Add the xml:id value
1409 * Open issue: normalization of the value.
1411 if (xmlValidateNCName(value
, 1) != 0) {
1412 xmlErrValid(ctxt
, XML_DTD_XMLID_VALUE
,
1413 "xml:id : attribute value %s is not an NCName\n",
1414 (const char *) value
, NULL
);
1416 xmlAddID(&ctxt
->vctxt
, ctxt
->myDoc
, value
, ret
);
1417 } else if (xmlIsID(ctxt
->myDoc
, ctxt
->node
, ret
))
1418 xmlAddID(&ctxt
->vctxt
, ctxt
->myDoc
, value
, ret
);
1419 else if (xmlIsRef(ctxt
->myDoc
, ctxt
->node
, ret
))
1420 xmlAddRef(&ctxt
->vctxt
, ctxt
->myDoc
, value
, ret
);
1431 * xmlCheckDefaultedAttributes:
1433 * Check defaulted attributes from the DTD
1436 xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt
, const xmlChar
*name
,
1437 const xmlChar
*prefix
, const xmlChar
**atts
) {
1438 xmlElementPtr elemDecl
;
1443 elemDecl
= xmlGetDtdQElementDesc(ctxt
->myDoc
->intSubset
, name
, prefix
);
1444 if (elemDecl
== NULL
) {
1445 elemDecl
= xmlGetDtdQElementDesc(ctxt
->myDoc
->extSubset
, name
, prefix
);
1449 process_external_subset
:
1451 if (elemDecl
!= NULL
) {
1452 xmlAttributePtr attr
= elemDecl
->attributes
;
1454 * Check against defaulted attributes from the external subset
1455 * if the document is stamped as standalone
1457 if ((ctxt
->myDoc
->standalone
== 1) &&
1458 (ctxt
->myDoc
->extSubset
!= NULL
) &&
1460 while (attr
!= NULL
) {
1461 if ((attr
->defaultValue
!= NULL
) &&
1462 (xmlGetDtdQAttrDesc(ctxt
->myDoc
->extSubset
,
1463 attr
->elem
, attr
->name
,
1464 attr
->prefix
) == attr
) &&
1465 (xmlGetDtdQAttrDesc(ctxt
->myDoc
->intSubset
,
1466 attr
->elem
, attr
->name
,
1467 attr
->prefix
) == NULL
)) {
1470 if (attr
->prefix
!= NULL
) {
1471 fulln
= xmlStrdup(attr
->prefix
);
1472 fulln
= xmlStrcat(fulln
, BAD_CAST
":");
1473 fulln
= xmlStrcat(fulln
, attr
->name
);
1475 fulln
= xmlStrdup(attr
->name
);
1477 if (fulln
== NULL
) {
1478 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1483 * Check that the attribute is not declared in the
1490 while (att
!= NULL
) {
1491 if (xmlStrEqual(att
, fulln
))
1498 xmlErrValid(ctxt
, XML_DTD_STANDALONE_DEFAULTED
,
1499 "standalone: attribute %s on %s defaulted from external subset\n",
1500 (const char *)fulln
,
1501 (const char *)attr
->elem
);
1510 * Actually insert defaulted values when needed
1512 attr
= elemDecl
->attributes
;
1513 while (attr
!= NULL
) {
1515 * Make sure that attributes redefinition occuring in the
1516 * internal subset are not overriden by definitions in the
1519 if (attr
->defaultValue
!= NULL
) {
1521 * the element should be instantiated in the tree if:
1522 * - this is a namespace prefix
1523 * - the user required for completion in the tree
1525 * - there isn't already an attribute definition
1526 * in the internal subset overriding it.
1528 if (((attr
->prefix
!= NULL
) &&
1529 (xmlStrEqual(attr
->prefix
, BAD_CAST
"xmlns"))) ||
1530 ((attr
->prefix
== NULL
) &&
1531 (xmlStrEqual(attr
->name
, BAD_CAST
"xmlns"))) ||
1532 (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)) {
1533 xmlAttributePtr tst
;
1535 tst
= xmlGetDtdQAttrDesc(ctxt
->myDoc
->intSubset
,
1536 attr
->elem
, attr
->name
,
1538 if ((tst
== attr
) || (tst
== NULL
)) {
1542 fulln
= xmlBuildQName(attr
->name
, attr
->prefix
, fn
, 50);
1543 if (fulln
== NULL
) {
1544 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1549 * Check that the attribute is not declared in the
1556 while (att
!= NULL
) {
1557 if (xmlStrEqual(att
, fulln
))
1564 xmlSAX2AttributeInternal(ctxt
, fulln
,
1565 attr
->defaultValue
, prefix
);
1567 if ((fulln
!= fn
) && (fulln
!= attr
->name
))
1574 if (internal
== 1) {
1575 elemDecl
= xmlGetDtdQElementDesc(ctxt
->myDoc
->extSubset
,
1578 goto process_external_subset
;
1584 * xmlSAX2StartElement:
1585 * @ctx: the user data (XML parser context)
1586 * @fullname: The element name, including namespace prefix
1587 * @atts: An array of name/value attributes pairs, NULL terminated
1589 * called when an opening tag has been processed.
1592 xmlSAX2StartElement(void *ctx
, const xmlChar
*fullname
, const xmlChar
**atts
)
1594 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1601 const xmlChar
*value
;
1604 if ((ctx
== NULL
) || (fullname
== NULL
) || (ctxt
->myDoc
== NULL
)) return;
1605 parent
= ctxt
->node
;
1607 xmlGenericError(xmlGenericErrorContext
,
1608 "SAX.xmlSAX2StartElement(%s)\n", fullname
);
1612 * First check on validity:
1614 if (ctxt
->validate
&& (ctxt
->myDoc
->extSubset
== NULL
) &&
1615 ((ctxt
->myDoc
->intSubset
== NULL
) ||
1616 ((ctxt
->myDoc
->intSubset
->notations
== NULL
) &&
1617 (ctxt
->myDoc
->intSubset
->elements
== NULL
) &&
1618 (ctxt
->myDoc
->intSubset
->attributes
== NULL
) &&
1619 (ctxt
->myDoc
->intSubset
->entities
== NULL
)))) {
1620 xmlErrValid(ctxt
, XML_ERR_NO_DTD
,
1621 "Validation failed: no DTD found !", NULL
, NULL
);
1627 * Split the full name into a namespace prefix and the tag name
1629 name
= xmlSplitQName(ctxt
, fullname
, &prefix
);
1633 * Note : the namespace resolution is deferred until the end of the
1634 * attributes parsing, since local namespace can be defined as
1635 * an attribute at this level.
1637 ret
= xmlNewDocNodeEatName(ctxt
->myDoc
, NULL
, name
, NULL
);
1641 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1644 if (ctxt
->myDoc
->children
== NULL
) {
1645 #ifdef DEBUG_SAX_TREE
1646 xmlGenericError(xmlGenericErrorContext
, "Setting %s as root\n", name
);
1648 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
1649 } else if (parent
== NULL
) {
1650 parent
= ctxt
->myDoc
->children
;
1653 if (ctxt
->linenumbers
) {
1654 if (ctxt
->input
!= NULL
) {
1655 if (ctxt
->input
->line
< 65535)
1656 ret
->line
= (short) ctxt
->input
->line
;
1663 * We are parsing a new node.
1665 #ifdef DEBUG_SAX_TREE
1666 xmlGenericError(xmlGenericErrorContext
, "pushing(%s)\n", name
);
1668 if (nodePush(ctxt
, ret
) < 0) {
1675 * Link the child element
1677 if (parent
!= NULL
) {
1678 if (parent
->type
== XML_ELEMENT_NODE
) {
1679 #ifdef DEBUG_SAX_TREE
1680 xmlGenericError(xmlGenericErrorContext
,
1681 "adding child %s to %s\n", name
, parent
->name
);
1683 xmlAddChild(parent
, ret
);
1685 #ifdef DEBUG_SAX_TREE
1686 xmlGenericError(xmlGenericErrorContext
,
1687 "adding sibling %s to ", name
);
1688 xmlDebugDumpOneNode(stderr
, parent
, 0);
1690 xmlAddSibling(parent
, ret
);
1695 * Insert all the defaulted attributes from the DTD especially namespaces
1697 if ((!ctxt
->html
) &&
1698 ((ctxt
->myDoc
->intSubset
!= NULL
) ||
1699 (ctxt
->myDoc
->extSubset
!= NULL
))) {
1700 xmlCheckDefaultedAttributes(ctxt
, name
, prefix
, atts
);
1704 * process all the attributes whose name start with "xmlns"
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
, prefix
);
1723 * Search the namespace, note that since the attributes have been
1724 * processed, the local namespaces are available.
1726 ns
= xmlSearchNs(ctxt
->myDoc
, ret
, prefix
);
1727 if ((ns
== NULL
) && (parent
!= NULL
))
1728 ns
= xmlSearchNs(ctxt
->myDoc
, parent
, prefix
);
1729 if ((prefix
!= NULL
) && (ns
== NULL
)) {
1730 ns
= xmlNewNs(ret
, NULL
, prefix
);
1731 xmlNsWarnMsg(ctxt
, XML_NS_ERR_UNDEFINED_NAMESPACE
,
1732 "Namespace prefix %s is not defined\n",
1737 * set the namespace node, making sure that if the default namspace
1738 * is unbound on a parent we simply kee it NULL
1740 if ((ns
!= NULL
) && (ns
->href
!= NULL
) &&
1741 ((ns
->href
[0] != 0) || (ns
->prefix
!= NULL
)))
1745 * process all the other attributes
1752 while (att
!= NULL
) {
1753 xmlSAX2AttributeInternal(ctxt
, att
, value
, NULL
);
1758 while ((att
!= NULL
) && (value
!= NULL
)) {
1759 if ((att
[0] != 'x') || (att
[1] != 'm') || (att
[2] != 'l') ||
1760 (att
[3] != 'n') || (att
[4] != 's'))
1761 xmlSAX2AttributeInternal(ctxt
, att
, value
, NULL
);
1772 #ifdef LIBXML_VALID_ENABLED
1774 * If it's the Document root, finish the DTD validation and
1775 * check the document root element for validity
1777 if ((ctxt
->validate
) && (ctxt
->vctxt
.finishDtd
== XML_CTXT_FINISH_DTD_0
)) {
1780 chk
= xmlValidateDtdFinal(&ctxt
->vctxt
, ctxt
->myDoc
);
1784 ctxt
->wellFormed
= 0;
1785 ctxt
->valid
&= xmlValidateRoot(&ctxt
->vctxt
, ctxt
->myDoc
);
1786 ctxt
->vctxt
.finishDtd
= XML_CTXT_FINISH_DTD_1
;
1788 #endif /* LIBXML_VALID_ENABLED */
1796 * xmlSAX2EndElement:
1797 * @ctx: the user data (XML parser context)
1798 * @name: The element name
1800 * called when the end of an element has been detected.
1803 xmlSAX2EndElement(void *ctx
, const xmlChar
*name ATTRIBUTE_UNUSED
)
1805 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1808 if (ctx
== NULL
) return;
1812 xmlGenericError(xmlGenericErrorContext
, "SAX.xmlSAX2EndElement(NULL)\n");
1814 xmlGenericError(xmlGenericErrorContext
, "SAX.xmlSAX2EndElement(%s)\n", name
);
1817 /* Capture end position and add node */
1818 if (cur
!= NULL
&& ctxt
->record_info
) {
1819 ctxt
->nodeInfo
->end_pos
= ctxt
->input
->cur
- ctxt
->input
->base
;
1820 ctxt
->nodeInfo
->end_line
= ctxt
->input
->line
;
1821 ctxt
->nodeInfo
->node
= cur
;
1822 xmlParserAddNodeInfo(ctxt
, ctxt
->nodeInfo
);
1826 #ifdef LIBXML_VALID_ENABLED
1827 if (ctxt
->validate
&& ctxt
->wellFormed
&&
1828 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
1829 ctxt
->valid
&= xmlValidateOneElement(&ctxt
->vctxt
, ctxt
->myDoc
,
1831 #endif /* LIBXML_VALID_ENABLED */
1835 * end of parsing of this node.
1837 #ifdef DEBUG_SAX_TREE
1838 xmlGenericError(xmlGenericErrorContext
, "popping(%s)\n", cur
->name
);
1842 #endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLED || LIBXML_LEGACY_ENABLED */
1846 * @ctxt: the parser context
1847 * @str: the input string
1848 * @len: the string length
1850 * Callback for a text node
1852 * Returns the newly allocated string or NULL if not needed or error
1855 xmlSAX2TextNode(xmlParserCtxtPtr ctxt
, const xmlChar
*str
, int len
) {
1857 const xmlChar
*intern
= NULL
;
1862 if (ctxt
->freeElems
!= NULL
) {
1863 ret
= ctxt
->freeElems
;
1864 ctxt
->freeElems
= ret
->next
;
1865 ctxt
->freeElemsNr
--;
1867 ret
= (xmlNodePtr
) xmlMalloc(sizeof(xmlNode
));
1870 xmlErrMemory(ctxt
, "xmlSAX2Characters");
1873 memset(ret
, 0, sizeof(xmlNode
));
1875 * intern the formatting blanks found between tags, or the
1876 * very short strings
1878 if (ctxt
->dictNames
) {
1879 xmlChar cur
= str
[len
];
1881 if ((len
< (int) (2 * sizeof(void *))) &&
1882 (ctxt
->options
& XML_PARSE_COMPACT
)) {
1883 /* store the string in the node overriding properties and nsDef */
1884 xmlChar
*tmp
= (xmlChar
*) &(ret
->properties
);
1885 memcpy(tmp
, str
, len
);
1888 } else if ((len
<= 3) && ((cur
== '"') || (cur
== '\'') ||
1889 ((cur
== '<') && (str
[len
+ 1] != '!')))) {
1890 intern
= xmlDictLookup(ctxt
->dict
, str
, len
);
1891 } else if (IS_BLANK_CH(*str
) && (len
< 60) && (cur
== '<') &&
1892 (str
[len
+ 1] != '!')) {
1895 for (i
= 1;i
< len
;i
++) {
1896 if (!IS_BLANK_CH(str
[i
])) goto skip
;
1898 intern
= xmlDictLookup(ctxt
->dict
, str
, len
);
1902 ret
->type
= XML_TEXT_NODE
;
1904 ret
->name
= xmlStringText
;
1905 if (intern
== NULL
) {
1906 ret
->content
= xmlStrndup(str
, len
);
1907 if (ret
->content
== NULL
) {
1908 xmlSAX2ErrMemory(ctxt
, "xmlSAX2TextNode");
1913 ret
->content
= (xmlChar
*) intern
;
1915 if (ctxt
->linenumbers
) {
1916 if (ctxt
->input
!= NULL
) {
1917 if (ctxt
->input
->line
< 65535)
1918 ret
->line
= (short) ctxt
->input
->line
;
1921 if (ctxt
->options
& XML_PARSE_BIG_LINES
)
1922 ret
->psvi
= (void *) (ptrdiff_t) ctxt
->input
->line
;
1927 if ((__xmlRegisterCallbacks
) && (xmlRegisterNodeDefaultValue
))
1928 xmlRegisterNodeDefaultValue(ret
);
1932 #ifdef LIBXML_VALID_ENABLED
1934 * xmlSAX2DecodeAttrEntities:
1935 * @ctxt: the parser context
1936 * @str: the input string
1937 * @len: the string length
1939 * Remove the entities from an attribute value
1941 * Returns the newly allocated string or NULL if not needed or error
1944 xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt
, const xmlChar
*str
,
1945 const xmlChar
*end
) {
1956 ret
= xmlStringLenDecodeEntities(ctxt
, str
, end
- str
,
1957 XML_SUBSTITUTE_REF
, 0,0,0);
1961 #endif /* LIBXML_VALID_ENABLED */
1964 * xmlSAX2AttributeNs:
1965 * @ctx: the user data (XML parser context)
1966 * @localname: the local name of the attribute
1967 * @prefix: the attribute namespace prefix if available
1968 * @URI: the attribute namespace name if available
1969 * @value: Start of the attribute value
1970 * @valueend: end of the attribute value
1972 * Handle an attribute that has been read by the parser.
1973 * The default handling is to convert the attribute into an
1974 * DOM subtree and past it in a new xmlAttr element added to
1978 xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt
,
1979 const xmlChar
* localname
,
1980 const xmlChar
* prefix
,
1981 const xmlChar
* value
,
1982 const xmlChar
* valueend
)
1985 xmlNsPtr
namespace = NULL
;
1986 xmlChar
*dup
= NULL
;
1989 * Note: if prefix == NULL, the attribute is not in the default namespace
1992 namespace = xmlSearchNs(ctxt
->myDoc
, ctxt
->node
, prefix
);
1997 if (ctxt
->freeAttrs
!= NULL
) {
1998 ret
= ctxt
->freeAttrs
;
1999 ctxt
->freeAttrs
= ret
->next
;
2000 ctxt
->freeAttrsNr
--;
2001 memset(ret
, 0, sizeof(xmlAttr
));
2002 ret
->type
= XML_ATTRIBUTE_NODE
;
2004 ret
->parent
= ctxt
->node
;
2005 ret
->doc
= ctxt
->myDoc
;
2006 ret
->ns
= namespace;
2008 if (ctxt
->dictNames
)
2009 ret
->name
= localname
;
2011 ret
->name
= xmlStrdup(localname
);
2013 /* link at the end to preserv order, TODO speed up with a last */
2014 if (ctxt
->node
->properties
== NULL
) {
2015 ctxt
->node
->properties
= ret
;
2017 xmlAttrPtr prev
= ctxt
->node
->properties
;
2019 while (prev
->next
!= NULL
) prev
= prev
->next
;
2024 if ((__xmlRegisterCallbacks
) && (xmlRegisterNodeDefaultValue
))
2025 xmlRegisterNodeDefaultValue((xmlNodePtr
)ret
);
2027 if (ctxt
->dictNames
)
2028 ret
= xmlNewNsPropEatName(ctxt
->node
, namespace,
2029 (xmlChar
*) localname
, NULL
);
2031 ret
= xmlNewNsProp(ctxt
->node
, namespace, localname
, NULL
);
2033 xmlErrMemory(ctxt
, "xmlSAX2AttributeNs");
2038 if ((ctxt
->replaceEntities
== 0) && (!ctxt
->html
)) {
2042 * We know that if there is an entity reference, then
2043 * the string has been dup'ed and terminates with 0
2044 * otherwise with ' or "
2046 if (*valueend
!= 0) {
2047 tmp
= xmlSAX2TextNode(ctxt
, value
, valueend
- value
);
2048 ret
->children
= tmp
;
2051 tmp
->doc
= ret
->doc
;
2052 tmp
->parent
= (xmlNodePtr
) ret
;
2055 ret
->children
= xmlStringLenGetNodeList(ctxt
->myDoc
, value
,
2057 tmp
= ret
->children
;
2058 while (tmp
!= NULL
) {
2059 tmp
->doc
= ret
->doc
;
2060 tmp
->parent
= (xmlNodePtr
) ret
;
2061 if (tmp
->next
== NULL
)
2066 } else if (value
!= NULL
) {
2069 tmp
= xmlSAX2TextNode(ctxt
, value
, valueend
- value
);
2070 ret
->children
= tmp
;
2073 tmp
->doc
= ret
->doc
;
2074 tmp
->parent
= (xmlNodePtr
) ret
;
2078 #ifdef LIBXML_VALID_ENABLED
2079 if ((!ctxt
->html
) && ctxt
->validate
&& ctxt
->wellFormed
&&
2080 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
) {
2082 * If we don't substitute entities, the validation should be
2083 * done on a value with replaced entities anyway.
2085 if (!ctxt
->replaceEntities
) {
2086 dup
= xmlSAX2DecodeAttrEntities(ctxt
, value
, valueend
);
2088 if (*valueend
== 0) {
2089 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2090 ctxt
->myDoc
, ctxt
->node
, ret
, value
);
2093 * That should already be normalized.
2094 * cheaper to finally allocate here than duplicate
2095 * entry points in the full validation code
2097 dup
= xmlStrndup(value
, valueend
- value
);
2099 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2100 ctxt
->myDoc
, ctxt
->node
, ret
, dup
);
2104 * dup now contains a string of the flattened attribute
2105 * content with entities substitued. Check if we need to
2106 * apply an extra layer of normalization.
2107 * It need to be done twice ... it's an extra burden related
2108 * to the ability to keep references in attributes
2110 if (ctxt
->attsSpecial
!= NULL
) {
2115 fullname
= xmlBuildQName(localname
, prefix
, fn
, 50);
2116 if (fullname
!= NULL
) {
2117 ctxt
->vctxt
.valid
= 1;
2118 nvalnorm
= xmlValidCtxtNormalizeAttributeValue(
2119 &ctxt
->vctxt
, ctxt
->myDoc
,
2120 ctxt
->node
, fullname
, dup
);
2121 if (ctxt
->vctxt
.valid
!= 1)
2124 if ((fullname
!= fn
) && (fullname
!= localname
))
2126 if (nvalnorm
!= NULL
) {
2133 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2134 ctxt
->myDoc
, ctxt
->node
, ret
, dup
);
2138 * if entities already have been substitued, then
2139 * the attribute as passed is already normalized
2141 dup
= xmlStrndup(value
, valueend
- value
);
2143 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2144 ctxt
->myDoc
, ctxt
->node
, ret
, dup
);
2147 #endif /* LIBXML_VALID_ENABLED */
2148 if (((ctxt
->loadsubset
& XML_SKIP_IDS
) == 0) &&
2149 (((ctxt
->replaceEntities
== 0) && (ctxt
->external
!= 2)) ||
2150 ((ctxt
->replaceEntities
!= 0) && (ctxt
->inSubset
== 0)))) {
2152 * when validating, the ID registration is done at the attribute
2153 * validation level. Otherwise we have to do specific handling here.
2155 if ((prefix
== ctxt
->str_xml
) &&
2156 (localname
[0] == 'i') && (localname
[1] == 'd') &&
2157 (localname
[2] == 0)) {
2159 * Add the xml:id value
2161 * Open issue: normalization of the value.
2164 dup
= xmlStrndup(value
, valueend
- value
);
2165 #if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
2166 #ifdef LIBXML_VALID_ENABLED
2167 if (xmlValidateNCName(dup
, 1) != 0) {
2168 xmlErrValid(ctxt
, XML_DTD_XMLID_VALUE
,
2169 "xml:id : attribute value %s is not an NCName\n",
2170 (const char *) dup
, NULL
);
2174 xmlAddID(&ctxt
->vctxt
, ctxt
->myDoc
, dup
, ret
);
2175 } else if (xmlIsID(ctxt
->myDoc
, ctxt
->node
, ret
)) {
2176 /* might be worth duplicate entry points and not copy */
2178 dup
= xmlStrndup(value
, valueend
- value
);
2179 xmlAddID(&ctxt
->vctxt
, ctxt
->myDoc
, dup
, ret
);
2180 } else if (xmlIsRef(ctxt
->myDoc
, ctxt
->node
, ret
)) {
2182 dup
= xmlStrndup(value
, valueend
- value
);
2183 xmlAddRef(&ctxt
->vctxt
, ctxt
->myDoc
, dup
, ret
);
2191 * xmlSAX2StartElementNs:
2192 * @ctx: the user data (XML parser context)
2193 * @localname: the local name of the element
2194 * @prefix: the element namespace prefix if available
2195 * @URI: the element namespace name if available
2196 * @nb_namespaces: number of namespace definitions on that node
2197 * @namespaces: pointer to the array of prefix/URI pairs namespace definitions
2198 * @nb_attributes: the number of attributes on that node
2199 * @nb_defaulted: the number of defaulted attributes.
2200 * @attributes: pointer to the array of (localname/prefix/URI/value/end)
2203 * SAX2 callback when an element start has been detected by the parser.
2204 * It provides the namespace informations for the element, as well as
2205 * the new namespace declarations on the element.
2208 xmlSAX2StartElementNs(void *ctx
,
2209 const xmlChar
*localname
,
2210 const xmlChar
*prefix
,
2213 const xmlChar
**namespaces
,
2216 const xmlChar
**attributes
)
2218 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2221 xmlNsPtr last
= NULL
, ns
;
2222 const xmlChar
*uri
, *pref
;
2223 xmlChar
*lname
= NULL
;
2226 if (ctx
== NULL
) return;
2227 parent
= ctxt
->node
;
2229 * First check on validity:
2231 if (ctxt
->validate
&& (ctxt
->myDoc
->extSubset
== NULL
) &&
2232 ((ctxt
->myDoc
->intSubset
== NULL
) ||
2233 ((ctxt
->myDoc
->intSubset
->notations
== NULL
) &&
2234 (ctxt
->myDoc
->intSubset
->elements
== NULL
) &&
2235 (ctxt
->myDoc
->intSubset
->attributes
== NULL
) &&
2236 (ctxt
->myDoc
->intSubset
->entities
== NULL
)))) {
2237 xmlErrValid(ctxt
, XML_DTD_NO_DTD
,
2238 "Validation failed: no DTD found !", NULL
, NULL
);
2243 * Take care of the rare case of an undefined namespace prefix
2245 if ((prefix
!= NULL
) && (URI
== NULL
)) {
2246 if (ctxt
->dictNames
) {
2247 const xmlChar
*fullname
;
2249 fullname
= xmlDictQLookup(ctxt
->dict
, prefix
, localname
);
2250 if (fullname
!= NULL
)
2251 localname
= fullname
;
2253 lname
= xmlBuildQName(localname
, prefix
, NULL
, 0);
2259 if (ctxt
->freeElems
!= NULL
) {
2260 ret
= ctxt
->freeElems
;
2261 ctxt
->freeElems
= ret
->next
;
2262 ctxt
->freeElemsNr
--;
2263 memset(ret
, 0, sizeof(xmlNode
));
2264 ret
->doc
= ctxt
->myDoc
;
2265 ret
->type
= XML_ELEMENT_NODE
;
2267 if (ctxt
->dictNames
)
2268 ret
->name
= localname
;
2271 ret
->name
= xmlStrdup(localname
);
2274 if (ret
->name
== NULL
) {
2275 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2279 if ((__xmlRegisterCallbacks
) && (xmlRegisterNodeDefaultValue
))
2280 xmlRegisterNodeDefaultValue(ret
);
2282 if (ctxt
->dictNames
)
2283 ret
= xmlNewDocNodeEatName(ctxt
->myDoc
, NULL
,
2284 (xmlChar
*) localname
, NULL
);
2285 else if (lname
== NULL
)
2286 ret
= xmlNewDocNode(ctxt
->myDoc
, NULL
, localname
, NULL
);
2288 ret
= xmlNewDocNodeEatName(ctxt
->myDoc
, NULL
,
2289 (xmlChar
*) lname
, NULL
);
2291 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2295 if (ctxt
->linenumbers
) {
2296 if (ctxt
->input
!= NULL
) {
2297 if (ctxt
->input
->line
< 65535)
2298 ret
->line
= (short) ctxt
->input
->line
;
2304 if (parent
== NULL
) {
2305 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
2308 * Build the namespace list
2310 for (i
= 0,j
= 0;j
< nb_namespaces
;j
++) {
2311 pref
= namespaces
[i
++];
2312 uri
= namespaces
[i
++];
2313 ns
= xmlNewNs(NULL
, uri
, pref
);
2316 ret
->nsDef
= last
= ns
;
2321 if ((URI
!= NULL
) && (prefix
== pref
))
2325 * any out of memory error would already have been raised
2326 * but we can't be guaranteed it's the actual error due to the
2327 * API, best is to skip in this case
2331 #ifdef LIBXML_VALID_ENABLED
2332 if ((!ctxt
->html
) && ctxt
->validate
&& ctxt
->wellFormed
&&
2333 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
) {
2334 ctxt
->valid
&= xmlValidateOneNamespace(&ctxt
->vctxt
, ctxt
->myDoc
,
2335 ret
, prefix
, ns
, uri
);
2337 #endif /* LIBXML_VALID_ENABLED */
2342 * We are parsing a new node.
2344 if (nodePush(ctxt
, ret
) < 0) {
2351 * Link the child element
2353 if (parent
!= NULL
) {
2354 if (parent
->type
== XML_ELEMENT_NODE
) {
2355 xmlAddChild(parent
, ret
);
2357 xmlAddSibling(parent
, ret
);
2362 * Insert the defaulted attributes from the DTD only if requested:
2364 if ((nb_defaulted
!= 0) &&
2365 ((ctxt
->loadsubset
& XML_COMPLETE_ATTRS
) == 0))
2366 nb_attributes
-= nb_defaulted
;
2369 * Search the namespace if it wasn't already found
2370 * Note that, if prefix is NULL, this searches for the default Ns
2372 if ((URI
!= NULL
) && (ret
->ns
== NULL
)) {
2373 ret
->ns
= xmlSearchNs(ctxt
->myDoc
, parent
, prefix
);
2374 if ((ret
->ns
== NULL
) && (xmlStrEqual(prefix
, BAD_CAST
"xml"))) {
2375 ret
->ns
= xmlSearchNs(ctxt
->myDoc
, ret
, prefix
);
2377 if (ret
->ns
== NULL
) {
2378 ns
= xmlNewNs(ret
, NULL
, prefix
);
2381 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2385 xmlNsWarnMsg(ctxt
, XML_NS_ERR_UNDEFINED_NAMESPACE
,
2386 "Namespace prefix %s was not found\n",
2389 xmlNsWarnMsg(ctxt
, XML_NS_ERR_UNDEFINED_NAMESPACE
,
2390 "Namespace default prefix was not found\n",
2396 * process all the other attributes
2398 if (nb_attributes
> 0) {
2399 for (j
= 0,i
= 0;i
< nb_attributes
;i
++,j
+=5) {
2401 * Handle the rare case of an undefined atribute prefix
2403 if ((attributes
[j
+1] != NULL
) && (attributes
[j
+2] == NULL
)) {
2404 if (ctxt
->dictNames
) {
2405 const xmlChar
*fullname
;
2407 fullname
= xmlDictQLookup(ctxt
->dict
, attributes
[j
+1],
2409 if (fullname
!= NULL
) {
2410 xmlSAX2AttributeNs(ctxt
, fullname
, NULL
,
2411 attributes
[j
+3], attributes
[j
+4]);
2415 lname
= xmlBuildQName(attributes
[j
], attributes
[j
+1],
2417 if (lname
!= NULL
) {
2418 xmlSAX2AttributeNs(ctxt
, lname
, NULL
,
2419 attributes
[j
+3], attributes
[j
+4]);
2425 xmlSAX2AttributeNs(ctxt
, attributes
[j
], attributes
[j
+1],
2426 attributes
[j
+3], attributes
[j
+4]);
2430 #ifdef LIBXML_VALID_ENABLED
2432 * If it's the Document root, finish the DTD validation and
2433 * check the document root element for validity
2435 if ((ctxt
->validate
) && (ctxt
->vctxt
.finishDtd
== XML_CTXT_FINISH_DTD_0
)) {
2438 chk
= xmlValidateDtdFinal(&ctxt
->vctxt
, ctxt
->myDoc
);
2442 ctxt
->wellFormed
= 0;
2443 ctxt
->valid
&= xmlValidateRoot(&ctxt
->vctxt
, ctxt
->myDoc
);
2444 ctxt
->vctxt
.finishDtd
= XML_CTXT_FINISH_DTD_1
;
2446 #endif /* LIBXML_VALID_ENABLED */
2450 * xmlSAX2EndElementNs:
2451 * @ctx: the user data (XML parser context)
2452 * @localname: the local name of the element
2453 * @prefix: the element namespace prefix if available
2454 * @URI: the element namespace name if available
2456 * SAX2 callback when an element end has been detected by the parser.
2457 * It provides the namespace informations for the element.
2460 xmlSAX2EndElementNs(void *ctx
,
2461 const xmlChar
* localname ATTRIBUTE_UNUSED
,
2462 const xmlChar
* prefix ATTRIBUTE_UNUSED
,
2463 const xmlChar
* URI ATTRIBUTE_UNUSED
)
2465 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2466 xmlParserNodeInfo node_info
;
2469 if (ctx
== NULL
) return;
2471 /* Capture end position and add node */
2472 if ((ctxt
->record_info
) && (cur
!= NULL
)) {
2473 node_info
.end_pos
= ctxt
->input
->cur
- ctxt
->input
->base
;
2474 node_info
.end_line
= ctxt
->input
->line
;
2475 node_info
.node
= cur
;
2476 xmlParserAddNodeInfo(ctxt
, &node_info
);
2480 #ifdef LIBXML_VALID_ENABLED
2481 if (ctxt
->validate
&& ctxt
->wellFormed
&&
2482 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
2483 ctxt
->valid
&= xmlValidateOneElement(&ctxt
->vctxt
, ctxt
->myDoc
, cur
);
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
) {
2524 * xmlSAX2Characters:
2525 * @ctx: the user data (XML parser context)
2526 * @ch: a xmlChar string
2527 * @len: the number of xmlChar
2529 * receiving some chars from the parser.
2532 xmlSAX2Characters(void *ctx
, const xmlChar
*ch
, int len
)
2534 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2535 xmlNodePtr lastChild
;
2537 if (ctx
== NULL
) return;
2539 xmlGenericError(xmlGenericErrorContext
,
2540 "SAX.xmlSAX2Characters(%.30s, %d)\n", ch
, len
);
2543 * Handle the data if any. If there is no child
2544 * add it as content, otherwise if the last child is text,
2545 * concatenate it, else create a new node of type text.
2548 if (ctxt
->node
== NULL
) {
2549 #ifdef DEBUG_SAX_TREE
2550 xmlGenericError(xmlGenericErrorContext
,
2551 "add chars: ctxt->node == NULL !\n");
2555 lastChild
= ctxt
->node
->last
;
2556 #ifdef DEBUG_SAX_TREE
2557 xmlGenericError(xmlGenericErrorContext
,
2558 "add chars to %s \n", ctxt
->node
->name
);
2562 * Here we needed an accelerator mechanism in case of very large
2563 * elements. Use an attribute in the structure !!!
2565 if (lastChild
== NULL
) {
2566 lastChild
= xmlSAX2TextNode(ctxt
, ch
, len
);
2567 if (lastChild
!= NULL
) {
2568 ctxt
->node
->children
= lastChild
;
2569 ctxt
->node
->last
= lastChild
;
2570 lastChild
->parent
= ctxt
->node
;
2571 lastChild
->doc
= ctxt
->node
->doc
;
2572 ctxt
->nodelen
= len
;
2573 ctxt
->nodemem
= len
+ 1;
2575 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters");
2579 int coalesceText
= (lastChild
!= NULL
) &&
2580 (lastChild
->type
== XML_TEXT_NODE
) &&
2581 (lastChild
->name
== xmlStringText
);
2582 if ((coalesceText
) && (ctxt
->nodemem
!= 0)) {
2584 * The whole point of maintaining nodelen and nodemem,
2585 * xmlTextConcat is too costly, i.e. compute length,
2586 * reallocate a new buffer, move data, append ch. Here
2587 * We try to minimaze realloc() uses and avoid copying
2588 * and recomputing length over and over.
2590 if (lastChild
->content
== (xmlChar
*)&(lastChild
->properties
)) {
2591 lastChild
->content
= xmlStrdup(lastChild
->content
);
2592 lastChild
->properties
= NULL
;
2593 } else if ((ctxt
->nodemem
== ctxt
->nodelen
+ 1) &&
2594 (xmlDictOwns(ctxt
->dict
, lastChild
->content
))) {
2595 lastChild
->content
= xmlStrdup(lastChild
->content
);
2597 if (lastChild
->content
== NULL
) {
2598 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters: xmlStrdup returned NULL");
2601 if (((size_t)ctxt
->nodelen
+ (size_t)len
> XML_MAX_TEXT_LENGTH
) &&
2602 ((ctxt
->options
& XML_PARSE_HUGE
) == 0)) {
2603 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters: huge text node");
2606 if ((size_t)ctxt
->nodelen
> SIZE_T_MAX
- (size_t)len
||
2607 (size_t)ctxt
->nodemem
+ (size_t)len
> SIZE_T_MAX
/ 2) {
2608 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters overflow prevented");
2611 if (ctxt
->nodelen
+ len
>= ctxt
->nodemem
) {
2615 size
= ctxt
->nodemem
+ len
;
2617 newbuf
= (xmlChar
*) xmlRealloc(lastChild
->content
,size
);
2618 if (newbuf
== NULL
) {
2619 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters");
2622 ctxt
->nodemem
= size
;
2623 lastChild
->content
= newbuf
;
2625 memcpy(&lastChild
->content
[ctxt
->nodelen
], ch
, len
);
2626 ctxt
->nodelen
+= len
;
2627 lastChild
->content
[ctxt
->nodelen
] = 0;
2628 } else if (coalesceText
) {
2629 if (xmlTextConcat(lastChild
, ch
, len
)) {
2630 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters");
2632 if (ctxt
->node
->children
!= NULL
) {
2633 ctxt
->nodelen
= xmlStrlen(lastChild
->content
);
2634 ctxt
->nodemem
= ctxt
->nodelen
+ 1;
2637 /* Mixed content, first time */
2638 lastChild
= xmlSAX2TextNode(ctxt
, ch
, len
);
2639 if (lastChild
!= NULL
) {
2640 xmlAddChild(ctxt
->node
, lastChild
);
2641 if (ctxt
->node
->children
!= NULL
) {
2642 ctxt
->nodelen
= len
;
2643 ctxt
->nodemem
= len
+ 1;
2651 * xmlSAX2IgnorableWhitespace:
2652 * @ctx: the user data (XML parser context)
2653 * @ch: a xmlChar string
2654 * @len: the number of xmlChar
2656 * receiving some ignorable whitespaces from the parser.
2657 * UNUSED: by default the DOM building will use xmlSAX2Characters
2660 xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED
, const xmlChar
*ch ATTRIBUTE_UNUSED
, int len ATTRIBUTE_UNUSED
)
2662 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
2664 xmlGenericError(xmlGenericErrorContext
,
2665 "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch
, len
);
2670 * xmlSAX2ProcessingInstruction:
2671 * @ctx: the user data (XML parser context)
2672 * @target: the target name
2673 * @data: the PI data's
2675 * A processing instruction has been parsed.
2678 xmlSAX2ProcessingInstruction(void *ctx
, const xmlChar
*target
,
2679 const xmlChar
*data
)
2681 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2685 if (ctx
== NULL
) return;
2686 parent
= ctxt
->node
;
2688 xmlGenericError(xmlGenericErrorContext
,
2689 "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target
, data
);
2692 ret
= xmlNewDocPI(ctxt
->myDoc
, target
, data
);
2693 if (ret
== NULL
) return;
2695 if (ctxt
->linenumbers
) {
2696 if (ctxt
->input
!= NULL
) {
2697 if (ctxt
->input
->line
< 65535)
2698 ret
->line
= (short) ctxt
->input
->line
;
2703 if (ctxt
->inSubset
== 1) {
2704 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->intSubset
, ret
);
2706 } else if (ctxt
->inSubset
== 2) {
2707 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->extSubset
, ret
);
2710 if (parent
== NULL
) {
2711 #ifdef DEBUG_SAX_TREE
2712 xmlGenericError(xmlGenericErrorContext
,
2713 "Setting PI %s as root\n", target
);
2715 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
2718 if (parent
->type
== XML_ELEMENT_NODE
) {
2719 #ifdef DEBUG_SAX_TREE
2720 xmlGenericError(xmlGenericErrorContext
,
2721 "adding PI %s child to %s\n", target
, parent
->name
);
2723 xmlAddChild(parent
, ret
);
2725 #ifdef DEBUG_SAX_TREE
2726 xmlGenericError(xmlGenericErrorContext
,
2727 "adding PI %s sibling to ", target
);
2728 xmlDebugDumpOneNode(stderr
, parent
, 0);
2730 xmlAddSibling(parent
, ret
);
2736 * @ctx: the user data (XML parser context)
2737 * @value: the xmlSAX2Comment content
2739 * A xmlSAX2Comment has been parsed.
2742 xmlSAX2Comment(void *ctx
, const xmlChar
*value
)
2744 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2748 if (ctx
== NULL
) return;
2749 parent
= ctxt
->node
;
2751 xmlGenericError(xmlGenericErrorContext
, "SAX.xmlSAX2Comment(%s)\n", value
);
2753 ret
= xmlNewDocComment(ctxt
->myDoc
, value
);
2754 if (ret
== NULL
) return;
2755 if (ctxt
->linenumbers
) {
2756 if (ctxt
->input
!= NULL
) {
2757 if (ctxt
->input
->line
< 65535)
2758 ret
->line
= (short) ctxt
->input
->line
;
2764 if (ctxt
->inSubset
== 1) {
2765 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->intSubset
, ret
);
2767 } else if (ctxt
->inSubset
== 2) {
2768 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->extSubset
, ret
);
2771 if (parent
== NULL
) {
2772 #ifdef DEBUG_SAX_TREE
2773 xmlGenericError(xmlGenericErrorContext
,
2774 "Setting xmlSAX2Comment as root\n");
2776 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
2779 if (parent
->type
== XML_ELEMENT_NODE
) {
2780 #ifdef DEBUG_SAX_TREE
2781 xmlGenericError(xmlGenericErrorContext
,
2782 "adding xmlSAX2Comment child to %s\n", parent
->name
);
2784 xmlAddChild(parent
, ret
);
2786 #ifdef DEBUG_SAX_TREE
2787 xmlGenericError(xmlGenericErrorContext
,
2788 "adding xmlSAX2Comment sibling to ");
2789 xmlDebugDumpOneNode(stderr
, parent
, 0);
2791 xmlAddSibling(parent
, ret
);
2796 * xmlSAX2CDataBlock:
2797 * @ctx: the user data (XML parser context)
2798 * @value: The pcdata content
2799 * @len: the block length
2801 * called when a pcdata block has been parsed
2804 xmlSAX2CDataBlock(void *ctx
, const xmlChar
*value
, int len
)
2806 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2807 xmlNodePtr ret
, lastChild
;
2809 if (ctx
== NULL
) return;
2811 xmlGenericError(xmlGenericErrorContext
,
2812 "SAX.pcdata(%.10s, %d)\n", value
, len
);
2814 lastChild
= xmlGetLastChild(ctxt
->node
);
2815 #ifdef DEBUG_SAX_TREE
2816 xmlGenericError(xmlGenericErrorContext
,
2817 "add chars to %s \n", ctxt
->node
->name
);
2819 if ((lastChild
!= NULL
) &&
2820 (lastChild
->type
== XML_CDATA_SECTION_NODE
)) {
2821 xmlTextConcat(lastChild
, value
, len
);
2823 ret
= xmlNewCDataBlock(ctxt
->myDoc
, value
, len
);
2824 if (xmlAddChild(ctxt
->node
, ret
) == NULL
)
2829 static int xmlSAX2DefaultVersionValue
= 2;
2831 #ifdef LIBXML_SAX1_ENABLED
2833 * xmlSAXDefaultVersion:
2834 * @version: the version, 1 or 2
2836 * Set the default version of SAX used globally by the library.
2837 * By default, during initialization the default is set to 2.
2838 * Note that it is generally a better coding style to use
2839 * xmlSAXVersion() to set up the version explicitly for a given
2842 * Returns the previous value in case of success and -1 in case of error.
2845 xmlSAXDefaultVersion(int version
)
2847 int ret
= xmlSAX2DefaultVersionValue
;
2849 if ((version
!= 1) && (version
!= 2))
2851 xmlSAX2DefaultVersionValue
= version
;
2854 #endif /* LIBXML_SAX1_ENABLED */
2858 * @hdlr: the SAX handler
2859 * @version: the version, 1 or 2
2861 * Initialize the default XML SAX handler according to the version
2863 * Returns 0 in case of success and -1 in case of error.
2866 xmlSAXVersion(xmlSAXHandler
*hdlr
, int version
)
2868 if (hdlr
== NULL
) return(-1);
2870 hdlr
->startElement
= NULL
;
2871 hdlr
->endElement
= NULL
;
2872 hdlr
->startElementNs
= xmlSAX2StartElementNs
;
2873 hdlr
->endElementNs
= xmlSAX2EndElementNs
;
2874 hdlr
->serror
= NULL
;
2875 hdlr
->initialized
= XML_SAX2_MAGIC
;
2876 #ifdef LIBXML_SAX1_ENABLED
2877 } else if (version
== 1) {
2878 hdlr
->startElement
= xmlSAX2StartElement
;
2879 hdlr
->endElement
= xmlSAX2EndElement
;
2880 hdlr
->initialized
= 1;
2881 #endif /* LIBXML_SAX1_ENABLED */
2884 hdlr
->internalSubset
= xmlSAX2InternalSubset
;
2885 hdlr
->externalSubset
= xmlSAX2ExternalSubset
;
2886 hdlr
->isStandalone
= xmlSAX2IsStandalone
;
2887 hdlr
->hasInternalSubset
= xmlSAX2HasInternalSubset
;
2888 hdlr
->hasExternalSubset
= xmlSAX2HasExternalSubset
;
2889 hdlr
->resolveEntity
= xmlSAX2ResolveEntity
;
2890 hdlr
->getEntity
= xmlSAX2GetEntity
;
2891 hdlr
->getParameterEntity
= xmlSAX2GetParameterEntity
;
2892 hdlr
->entityDecl
= xmlSAX2EntityDecl
;
2893 hdlr
->attributeDecl
= xmlSAX2AttributeDecl
;
2894 hdlr
->elementDecl
= xmlSAX2ElementDecl
;
2895 hdlr
->notationDecl
= xmlSAX2NotationDecl
;
2896 hdlr
->unparsedEntityDecl
= xmlSAX2UnparsedEntityDecl
;
2897 hdlr
->setDocumentLocator
= xmlSAX2SetDocumentLocator
;
2898 hdlr
->startDocument
= xmlSAX2StartDocument
;
2899 hdlr
->endDocument
= xmlSAX2EndDocument
;
2900 hdlr
->reference
= xmlSAX2Reference
;
2901 hdlr
->characters
= xmlSAX2Characters
;
2902 hdlr
->cdataBlock
= xmlSAX2CDataBlock
;
2903 hdlr
->ignorableWhitespace
= xmlSAX2Characters
;
2904 hdlr
->processingInstruction
= xmlSAX2ProcessingInstruction
;
2905 hdlr
->comment
= xmlSAX2Comment
;
2906 hdlr
->warning
= xmlParserWarning
;
2907 hdlr
->error
= xmlParserError
;
2908 hdlr
->fatalError
= xmlParserError
;
2914 * xmlSAX2InitDefaultSAXHandler:
2915 * @hdlr: the SAX handler
2916 * @warning: flag if non-zero sets the handler warning procedure
2918 * Initialize the default XML SAX2 handler
2921 xmlSAX2InitDefaultSAXHandler(xmlSAXHandler
*hdlr
, int warning
)
2923 if ((hdlr
== NULL
) || (hdlr
->initialized
!= 0))
2926 xmlSAXVersion(hdlr
, xmlSAX2DefaultVersionValue
);
2928 hdlr
->warning
= NULL
;
2930 hdlr
->warning
= xmlParserWarning
;
2934 * xmlDefaultSAXHandlerInit:
2936 * Initialize the default SAX2 handler
2939 xmlDefaultSAXHandlerInit(void)
2941 #ifdef LIBXML_SAX1_ENABLED
2942 xmlSAXVersion((xmlSAXHandlerPtr
) &xmlDefaultSAXHandler
, 1);
2943 #endif /* LIBXML_SAX1_ENABLED */
2946 #ifdef LIBXML_HTML_ENABLED
2949 * xmlSAX2InitHtmlDefaultSAXHandler:
2950 * @hdlr: the SAX handler
2952 * Initialize the default HTML SAX2 handler
2955 xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler
*hdlr
)
2957 if ((hdlr
== NULL
) || (hdlr
->initialized
!= 0))
2960 hdlr
->internalSubset
= xmlSAX2InternalSubset
;
2961 hdlr
->externalSubset
= NULL
;
2962 hdlr
->isStandalone
= NULL
;
2963 hdlr
->hasInternalSubset
= NULL
;
2964 hdlr
->hasExternalSubset
= NULL
;
2965 hdlr
->resolveEntity
= NULL
;
2966 hdlr
->getEntity
= xmlSAX2GetEntity
;
2967 hdlr
->getParameterEntity
= NULL
;
2968 hdlr
->entityDecl
= NULL
;
2969 hdlr
->attributeDecl
= NULL
;
2970 hdlr
->elementDecl
= NULL
;
2971 hdlr
->notationDecl
= NULL
;
2972 hdlr
->unparsedEntityDecl
= NULL
;
2973 hdlr
->setDocumentLocator
= xmlSAX2SetDocumentLocator
;
2974 hdlr
->startDocument
= xmlSAX2StartDocument
;
2975 hdlr
->endDocument
= xmlSAX2EndDocument
;
2976 hdlr
->startElement
= xmlSAX2StartElement
;
2977 hdlr
->endElement
= xmlSAX2EndElement
;
2978 hdlr
->reference
= NULL
;
2979 hdlr
->characters
= xmlSAX2Characters
;
2980 hdlr
->cdataBlock
= xmlSAX2CDataBlock
;
2981 hdlr
->ignorableWhitespace
= xmlSAX2IgnorableWhitespace
;
2982 hdlr
->processingInstruction
= xmlSAX2ProcessingInstruction
;
2983 hdlr
->comment
= xmlSAX2Comment
;
2984 hdlr
->warning
= xmlParserWarning
;
2985 hdlr
->error
= xmlParserError
;
2986 hdlr
->fatalError
= xmlParserError
;
2988 hdlr
->initialized
= 1;
2992 * htmlDefaultSAXHandlerInit:
2994 * Initialize the default SAX handler
2997 htmlDefaultSAXHandlerInit(void)
2999 xmlSAX2InitHtmlDefaultSAXHandler((xmlSAXHandlerPtr
) &htmlDefaultSAXHandler
);
3002 #endif /* LIBXML_HTML_ENABLED */
3004 #ifdef LIBXML_DOCB_ENABLED
3007 * xmlSAX2InitDocbDefaultSAXHandler:
3008 * @hdlr: the SAX handler
3010 * Initialize the default DocBook SAX2 handler
3013 xmlSAX2InitDocbDefaultSAXHandler(xmlSAXHandler
*hdlr
)
3015 if ((hdlr
== NULL
) || (hdlr
->initialized
!= 0))
3018 hdlr
->internalSubset
= xmlSAX2InternalSubset
;
3019 hdlr
->externalSubset
= NULL
;
3020 hdlr
->isStandalone
= xmlSAX2IsStandalone
;
3021 hdlr
->hasInternalSubset
= xmlSAX2HasInternalSubset
;
3022 hdlr
->hasExternalSubset
= xmlSAX2HasExternalSubset
;
3023 hdlr
->resolveEntity
= xmlSAX2ResolveEntity
;
3024 hdlr
->getEntity
= xmlSAX2GetEntity
;
3025 hdlr
->getParameterEntity
= NULL
;
3026 hdlr
->entityDecl
= xmlSAX2EntityDecl
;
3027 hdlr
->attributeDecl
= NULL
;
3028 hdlr
->elementDecl
= NULL
;
3029 hdlr
->notationDecl
= NULL
;
3030 hdlr
->unparsedEntityDecl
= NULL
;
3031 hdlr
->setDocumentLocator
= xmlSAX2SetDocumentLocator
;
3032 hdlr
->startDocument
= xmlSAX2StartDocument
;
3033 hdlr
->endDocument
= xmlSAX2EndDocument
;
3034 hdlr
->startElement
= xmlSAX2StartElement
;
3035 hdlr
->endElement
= xmlSAX2EndElement
;
3036 hdlr
->reference
= xmlSAX2Reference
;
3037 hdlr
->characters
= xmlSAX2Characters
;
3038 hdlr
->cdataBlock
= NULL
;
3039 hdlr
->ignorableWhitespace
= xmlSAX2IgnorableWhitespace
;
3040 hdlr
->processingInstruction
= NULL
;
3041 hdlr
->comment
= xmlSAX2Comment
;
3042 hdlr
->warning
= xmlParserWarning
;
3043 hdlr
->error
= xmlParserError
;
3044 hdlr
->fatalError
= xmlParserError
;
3046 hdlr
->initialized
= 1;
3050 * docbDefaultSAXHandlerInit:
3052 * Initialize the default SAX handler
3055 docbDefaultSAXHandlerInit(void)
3057 xmlSAX2InitDocbDefaultSAXHandler((xmlSAXHandlerPtr
) &docbDefaultSAXHandler
);
3060 #endif /* LIBXML_DOCB_ENABLED */
3062 #include "elfgcchack.h"