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 nodePush(ctxt
, ret
);
1671 * Link the child element
1673 if (parent
!= NULL
) {
1674 if (parent
->type
== XML_ELEMENT_NODE
) {
1675 #ifdef DEBUG_SAX_TREE
1676 xmlGenericError(xmlGenericErrorContext
,
1677 "adding child %s to %s\n", name
, parent
->name
);
1679 xmlAddChild(parent
, ret
);
1681 #ifdef DEBUG_SAX_TREE
1682 xmlGenericError(xmlGenericErrorContext
,
1683 "adding sibling %s to ", name
);
1684 xmlDebugDumpOneNode(stderr
, parent
, 0);
1686 xmlAddSibling(parent
, ret
);
1691 * Insert all the defaulted attributes from the DTD especially namespaces
1693 if ((!ctxt
->html
) &&
1694 ((ctxt
->myDoc
->intSubset
!= NULL
) ||
1695 (ctxt
->myDoc
->extSubset
!= NULL
))) {
1696 xmlCheckDefaultedAttributes(ctxt
, name
, prefix
, atts
);
1700 * process all the attributes whose name start with "xmlns"
1707 while ((att
!= NULL
) && (value
!= NULL
)) {
1708 if ((att
[0] == 'x') && (att
[1] == 'm') && (att
[2] == 'l') &&
1709 (att
[3] == 'n') && (att
[4] == 's'))
1710 xmlSAX2AttributeInternal(ctxt
, att
, value
, prefix
);
1719 * Search the namespace, note that since the attributes have been
1720 * processed, the local namespaces are available.
1722 ns
= xmlSearchNs(ctxt
->myDoc
, ret
, prefix
);
1723 if ((ns
== NULL
) && (parent
!= NULL
))
1724 ns
= xmlSearchNs(ctxt
->myDoc
, parent
, prefix
);
1725 if ((prefix
!= NULL
) && (ns
== NULL
)) {
1726 ns
= xmlNewNs(ret
, NULL
, prefix
);
1727 xmlNsWarnMsg(ctxt
, XML_NS_ERR_UNDEFINED_NAMESPACE
,
1728 "Namespace prefix %s is not defined\n",
1733 * set the namespace node, making sure that if the default namspace
1734 * is unbound on a parent we simply kee it NULL
1736 if ((ns
!= NULL
) && (ns
->href
!= NULL
) &&
1737 ((ns
->href
[0] != 0) || (ns
->prefix
!= NULL
)))
1741 * process all the other attributes
1748 while (att
!= NULL
) {
1749 xmlSAX2AttributeInternal(ctxt
, att
, value
, NULL
);
1754 while ((att
!= NULL
) && (value
!= NULL
)) {
1755 if ((att
[0] != 'x') || (att
[1] != 'm') || (att
[2] != 'l') ||
1756 (att
[3] != 'n') || (att
[4] != 's'))
1757 xmlSAX2AttributeInternal(ctxt
, att
, value
, NULL
);
1768 #ifdef LIBXML_VALID_ENABLED
1770 * If it's the Document root, finish the DTD validation and
1771 * check the document root element for validity
1773 if ((ctxt
->validate
) && (ctxt
->vctxt
.finishDtd
== XML_CTXT_FINISH_DTD_0
)) {
1776 chk
= xmlValidateDtdFinal(&ctxt
->vctxt
, ctxt
->myDoc
);
1780 ctxt
->wellFormed
= 0;
1781 ctxt
->valid
&= xmlValidateRoot(&ctxt
->vctxt
, ctxt
->myDoc
);
1782 ctxt
->vctxt
.finishDtd
= XML_CTXT_FINISH_DTD_1
;
1784 #endif /* LIBXML_VALID_ENABLED */
1792 * xmlSAX2EndElement:
1793 * @ctx: the user data (XML parser context)
1794 * @name: The element name
1796 * called when the end of an element has been detected.
1799 xmlSAX2EndElement(void *ctx
, const xmlChar
*name ATTRIBUTE_UNUSED
)
1801 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1804 if (ctx
== NULL
) return;
1808 xmlGenericError(xmlGenericErrorContext
, "SAX.xmlSAX2EndElement(NULL)\n");
1810 xmlGenericError(xmlGenericErrorContext
, "SAX.xmlSAX2EndElement(%s)\n", name
);
1813 /* Capture end position and add node */
1814 if (cur
!= NULL
&& ctxt
->record_info
) {
1815 ctxt
->nodeInfo
->end_pos
= ctxt
->input
->cur
- ctxt
->input
->base
;
1816 ctxt
->nodeInfo
->end_line
= ctxt
->input
->line
;
1817 ctxt
->nodeInfo
->node
= cur
;
1818 xmlParserAddNodeInfo(ctxt
, ctxt
->nodeInfo
);
1822 #ifdef LIBXML_VALID_ENABLED
1823 if (ctxt
->validate
&& ctxt
->wellFormed
&&
1824 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
1825 ctxt
->valid
&= xmlValidateOneElement(&ctxt
->vctxt
, ctxt
->myDoc
,
1827 #endif /* LIBXML_VALID_ENABLED */
1831 * end of parsing of this node.
1833 #ifdef DEBUG_SAX_TREE
1834 xmlGenericError(xmlGenericErrorContext
, "popping(%s)\n", cur
->name
);
1838 #endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLED || LIBXML_LEGACY_ENABLED */
1842 * @ctxt: the parser context
1843 * @str: the input string
1844 * @len: the string length
1846 * Callback for a text node
1848 * Returns the newly allocated string or NULL if not needed or error
1851 xmlSAX2TextNode(xmlParserCtxtPtr ctxt
, const xmlChar
*str
, int len
) {
1853 const xmlChar
*intern
= NULL
;
1858 if (ctxt
->freeElems
!= NULL
) {
1859 ret
= ctxt
->freeElems
;
1860 ctxt
->freeElems
= ret
->next
;
1861 ctxt
->freeElemsNr
--;
1863 ret
= (xmlNodePtr
) xmlMalloc(sizeof(xmlNode
));
1866 xmlErrMemory(ctxt
, "xmlSAX2Characters");
1869 memset(ret
, 0, sizeof(xmlNode
));
1871 * intern the formatting blanks found between tags, or the
1872 * very short strings
1874 if (ctxt
->dictNames
) {
1875 xmlChar cur
= str
[len
];
1877 if ((len
< (int) (2 * sizeof(void *))) &&
1878 (ctxt
->options
& XML_PARSE_COMPACT
)) {
1879 /* store the string in the node overriding properties and nsDef */
1880 xmlChar
*tmp
= (xmlChar
*) &(ret
->properties
);
1881 memcpy(tmp
, str
, len
);
1884 } else if ((len
<= 3) && ((cur
== '"') || (cur
== '\'') ||
1885 ((cur
== '<') && (str
[len
+ 1] != '!')))) {
1886 intern
= xmlDictLookup(ctxt
->dict
, str
, len
);
1887 } else if (IS_BLANK_CH(*str
) && (len
< 60) && (cur
== '<') &&
1888 (str
[len
+ 1] != '!')) {
1891 for (i
= 1;i
< len
;i
++) {
1892 if (!IS_BLANK_CH(str
[i
])) goto skip
;
1894 intern
= xmlDictLookup(ctxt
->dict
, str
, len
);
1898 ret
->type
= XML_TEXT_NODE
;
1900 ret
->name
= xmlStringText
;
1901 if (intern
== NULL
) {
1902 ret
->content
= xmlStrndup(str
, len
);
1903 if (ret
->content
== NULL
) {
1904 xmlSAX2ErrMemory(ctxt
, "xmlSAX2TextNode");
1909 ret
->content
= (xmlChar
*) intern
;
1911 if (ctxt
->linenumbers
) {
1912 if (ctxt
->input
!= NULL
) {
1913 if (ctxt
->input
->line
< 65535)
1914 ret
->line
= (short) ctxt
->input
->line
;
1917 if (ctxt
->options
& XML_PARSE_BIG_LINES
)
1918 ret
->psvi
= (void *) (ptrdiff_t) ctxt
->input
->line
;
1923 if ((__xmlRegisterCallbacks
) && (xmlRegisterNodeDefaultValue
))
1924 xmlRegisterNodeDefaultValue(ret
);
1928 #ifdef LIBXML_VALID_ENABLED
1930 * xmlSAX2DecodeAttrEntities:
1931 * @ctxt: the parser context
1932 * @str: the input string
1933 * @len: the string length
1935 * Remove the entities from an attribute value
1937 * Returns the newly allocated string or NULL if not needed or error
1940 xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt
, const xmlChar
*str
,
1941 const xmlChar
*end
) {
1952 ret
= xmlStringLenDecodeEntities(ctxt
, str
, end
- str
,
1953 XML_SUBSTITUTE_REF
, 0,0,0);
1957 #endif /* LIBXML_VALID_ENABLED */
1960 * xmlSAX2AttributeNs:
1961 * @ctx: the user data (XML parser context)
1962 * @localname: the local name of the attribute
1963 * @prefix: the attribute namespace prefix if available
1964 * @URI: the attribute namespace name if available
1965 * @value: Start of the attribute value
1966 * @valueend: end of the attribute value
1968 * Handle an attribute that has been read by the parser.
1969 * The default handling is to convert the attribute into an
1970 * DOM subtree and past it in a new xmlAttr element added to
1974 xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt
,
1975 const xmlChar
* localname
,
1976 const xmlChar
* prefix
,
1977 const xmlChar
* value
,
1978 const xmlChar
* valueend
)
1981 xmlNsPtr
namespace = NULL
;
1982 xmlChar
*dup
= NULL
;
1985 * Note: if prefix == NULL, the attribute is not in the default namespace
1988 namespace = xmlSearchNs(ctxt
->myDoc
, ctxt
->node
, prefix
);
1993 if (ctxt
->freeAttrs
!= NULL
) {
1994 ret
= ctxt
->freeAttrs
;
1995 ctxt
->freeAttrs
= ret
->next
;
1996 ctxt
->freeAttrsNr
--;
1997 memset(ret
, 0, sizeof(xmlAttr
));
1998 ret
->type
= XML_ATTRIBUTE_NODE
;
2000 ret
->parent
= ctxt
->node
;
2001 ret
->doc
= ctxt
->myDoc
;
2002 ret
->ns
= namespace;
2004 if (ctxt
->dictNames
)
2005 ret
->name
= localname
;
2007 ret
->name
= xmlStrdup(localname
);
2009 /* link at the end to preserv order, TODO speed up with a last */
2010 if (ctxt
->node
->properties
== NULL
) {
2011 ctxt
->node
->properties
= ret
;
2013 xmlAttrPtr prev
= ctxt
->node
->properties
;
2015 while (prev
->next
!= NULL
) prev
= prev
->next
;
2020 if ((__xmlRegisterCallbacks
) && (xmlRegisterNodeDefaultValue
))
2021 xmlRegisterNodeDefaultValue((xmlNodePtr
)ret
);
2023 if (ctxt
->dictNames
)
2024 ret
= xmlNewNsPropEatName(ctxt
->node
, namespace,
2025 (xmlChar
*) localname
, NULL
);
2027 ret
= xmlNewNsProp(ctxt
->node
, namespace, localname
, NULL
);
2029 xmlErrMemory(ctxt
, "xmlSAX2AttributeNs");
2034 if ((ctxt
->replaceEntities
== 0) && (!ctxt
->html
)) {
2038 * We know that if there is an entity reference, then
2039 * the string has been dup'ed and terminates with 0
2040 * otherwise with ' or "
2042 if (*valueend
!= 0) {
2043 tmp
= xmlSAX2TextNode(ctxt
, value
, valueend
- value
);
2044 ret
->children
= tmp
;
2047 tmp
->doc
= ret
->doc
;
2048 tmp
->parent
= (xmlNodePtr
) ret
;
2051 ret
->children
= xmlStringLenGetNodeList(ctxt
->myDoc
, value
,
2053 tmp
= ret
->children
;
2054 while (tmp
!= NULL
) {
2055 tmp
->doc
= ret
->doc
;
2056 tmp
->parent
= (xmlNodePtr
) ret
;
2057 if (tmp
->next
== NULL
)
2062 } else if (value
!= NULL
) {
2065 tmp
= xmlSAX2TextNode(ctxt
, value
, valueend
- value
);
2066 ret
->children
= tmp
;
2069 tmp
->doc
= ret
->doc
;
2070 tmp
->parent
= (xmlNodePtr
) ret
;
2074 #ifdef LIBXML_VALID_ENABLED
2075 if ((!ctxt
->html
) && ctxt
->validate
&& ctxt
->wellFormed
&&
2076 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
) {
2078 * If we don't substitute entities, the validation should be
2079 * done on a value with replaced entities anyway.
2081 if (!ctxt
->replaceEntities
) {
2082 dup
= xmlSAX2DecodeAttrEntities(ctxt
, value
, valueend
);
2084 if (*valueend
== 0) {
2085 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2086 ctxt
->myDoc
, ctxt
->node
, ret
, value
);
2089 * That should already be normalized.
2090 * cheaper to finally allocate here than duplicate
2091 * entry points in the full validation code
2093 dup
= xmlStrndup(value
, valueend
- value
);
2095 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2096 ctxt
->myDoc
, ctxt
->node
, ret
, dup
);
2100 * dup now contains a string of the flattened attribute
2101 * content with entities substitued. Check if we need to
2102 * apply an extra layer of normalization.
2103 * It need to be done twice ... it's an extra burden related
2104 * to the ability to keep references in attributes
2106 if (ctxt
->attsSpecial
!= NULL
) {
2111 fullname
= xmlBuildQName(localname
, prefix
, fn
, 50);
2112 if (fullname
!= NULL
) {
2113 ctxt
->vctxt
.valid
= 1;
2114 nvalnorm
= xmlValidCtxtNormalizeAttributeValue(
2115 &ctxt
->vctxt
, ctxt
->myDoc
,
2116 ctxt
->node
, fullname
, dup
);
2117 if (ctxt
->vctxt
.valid
!= 1)
2120 if ((fullname
!= fn
) && (fullname
!= localname
))
2122 if (nvalnorm
!= NULL
) {
2129 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2130 ctxt
->myDoc
, ctxt
->node
, ret
, dup
);
2134 * if entities already have been substitued, then
2135 * the attribute as passed is already normalized
2137 dup
= xmlStrndup(value
, valueend
- value
);
2139 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2140 ctxt
->myDoc
, ctxt
->node
, ret
, dup
);
2143 #endif /* LIBXML_VALID_ENABLED */
2144 if (((ctxt
->loadsubset
& XML_SKIP_IDS
) == 0) &&
2145 (((ctxt
->replaceEntities
== 0) && (ctxt
->external
!= 2)) ||
2146 ((ctxt
->replaceEntities
!= 0) && (ctxt
->inSubset
== 0)))) {
2148 * when validating, the ID registration is done at the attribute
2149 * validation level. Otherwise we have to do specific handling here.
2151 if ((prefix
== ctxt
->str_xml
) &&
2152 (localname
[0] == 'i') && (localname
[1] == 'd') &&
2153 (localname
[2] == 0)) {
2155 * Add the xml:id value
2157 * Open issue: normalization of the value.
2160 dup
= xmlStrndup(value
, valueend
- value
);
2161 #if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
2162 #ifdef LIBXML_VALID_ENABLED
2163 if (xmlValidateNCName(dup
, 1) != 0) {
2164 xmlErrValid(ctxt
, XML_DTD_XMLID_VALUE
,
2165 "xml:id : attribute value %s is not an NCName\n",
2166 (const char *) dup
, NULL
);
2170 xmlAddID(&ctxt
->vctxt
, ctxt
->myDoc
, dup
, ret
);
2171 } else if (xmlIsID(ctxt
->myDoc
, ctxt
->node
, ret
)) {
2172 /* might be worth duplicate entry points and not copy */
2174 dup
= xmlStrndup(value
, valueend
- value
);
2175 xmlAddID(&ctxt
->vctxt
, ctxt
->myDoc
, dup
, ret
);
2176 } else if (xmlIsRef(ctxt
->myDoc
, ctxt
->node
, ret
)) {
2178 dup
= xmlStrndup(value
, valueend
- value
);
2179 xmlAddRef(&ctxt
->vctxt
, ctxt
->myDoc
, dup
, ret
);
2187 * xmlSAX2StartElementNs:
2188 * @ctx: the user data (XML parser context)
2189 * @localname: the local name of the element
2190 * @prefix: the element namespace prefix if available
2191 * @URI: the element namespace name if available
2192 * @nb_namespaces: number of namespace definitions on that node
2193 * @namespaces: pointer to the array of prefix/URI pairs namespace definitions
2194 * @nb_attributes: the number of attributes on that node
2195 * @nb_defaulted: the number of defaulted attributes.
2196 * @attributes: pointer to the array of (localname/prefix/URI/value/end)
2199 * SAX2 callback when an element start has been detected by the parser.
2200 * It provides the namespace informations for the element, as well as
2201 * the new namespace declarations on the element.
2204 xmlSAX2StartElementNs(void *ctx
,
2205 const xmlChar
*localname
,
2206 const xmlChar
*prefix
,
2209 const xmlChar
**namespaces
,
2212 const xmlChar
**attributes
)
2214 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2217 xmlNsPtr last
= NULL
, ns
;
2218 const xmlChar
*uri
, *pref
;
2219 xmlChar
*lname
= NULL
;
2222 if (ctx
== NULL
) return;
2223 parent
= ctxt
->node
;
2225 * First check on validity:
2227 if (ctxt
->validate
&& (ctxt
->myDoc
->extSubset
== NULL
) &&
2228 ((ctxt
->myDoc
->intSubset
== NULL
) ||
2229 ((ctxt
->myDoc
->intSubset
->notations
== NULL
) &&
2230 (ctxt
->myDoc
->intSubset
->elements
== NULL
) &&
2231 (ctxt
->myDoc
->intSubset
->attributes
== NULL
) &&
2232 (ctxt
->myDoc
->intSubset
->entities
== NULL
)))) {
2233 xmlErrValid(ctxt
, XML_DTD_NO_DTD
,
2234 "Validation failed: no DTD found !", NULL
, NULL
);
2239 * Take care of the rare case of an undefined namespace prefix
2241 if ((prefix
!= NULL
) && (URI
== NULL
)) {
2242 if (ctxt
->dictNames
) {
2243 const xmlChar
*fullname
;
2245 fullname
= xmlDictQLookup(ctxt
->dict
, prefix
, localname
);
2246 if (fullname
!= NULL
)
2247 localname
= fullname
;
2249 lname
= xmlBuildQName(localname
, prefix
, NULL
, 0);
2255 if (ctxt
->freeElems
!= NULL
) {
2256 ret
= ctxt
->freeElems
;
2257 ctxt
->freeElems
= ret
->next
;
2258 ctxt
->freeElemsNr
--;
2259 memset(ret
, 0, sizeof(xmlNode
));
2260 ret
->type
= XML_ELEMENT_NODE
;
2262 if (ctxt
->dictNames
)
2263 ret
->name
= localname
;
2266 ret
->name
= xmlStrdup(localname
);
2269 if (ret
->name
== NULL
) {
2270 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2274 if ((__xmlRegisterCallbacks
) && (xmlRegisterNodeDefaultValue
))
2275 xmlRegisterNodeDefaultValue(ret
);
2277 if (ctxt
->dictNames
)
2278 ret
= xmlNewDocNodeEatName(ctxt
->myDoc
, NULL
,
2279 (xmlChar
*) localname
, NULL
);
2280 else if (lname
== NULL
)
2281 ret
= xmlNewDocNode(ctxt
->myDoc
, NULL
, localname
, NULL
);
2283 ret
= xmlNewDocNodeEatName(ctxt
->myDoc
, NULL
,
2284 (xmlChar
*) lname
, NULL
);
2286 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2290 if (ctxt
->linenumbers
) {
2291 if (ctxt
->input
!= NULL
) {
2292 if (ctxt
->input
->line
< 65535)
2293 ret
->line
= (short) ctxt
->input
->line
;
2299 if (parent
== NULL
) {
2300 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
2303 * Build the namespace list
2305 for (i
= 0,j
= 0;j
< nb_namespaces
;j
++) {
2306 pref
= namespaces
[i
++];
2307 uri
= namespaces
[i
++];
2308 ns
= xmlNewNs(NULL
, uri
, pref
);
2311 ret
->nsDef
= last
= ns
;
2316 if ((URI
!= NULL
) && (prefix
== pref
))
2320 * any out of memory error would already have been raised
2321 * but we can't be guaranteed it's the actual error due to the
2322 * API, best is to skip in this case
2326 #ifdef LIBXML_VALID_ENABLED
2327 if ((!ctxt
->html
) && ctxt
->validate
&& ctxt
->wellFormed
&&
2328 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
) {
2329 ctxt
->valid
&= xmlValidateOneNamespace(&ctxt
->vctxt
, ctxt
->myDoc
,
2330 ret
, prefix
, ns
, uri
);
2332 #endif /* LIBXML_VALID_ENABLED */
2337 * We are parsing a new node.
2339 nodePush(ctxt
, ret
);
2342 * Link the child element
2344 if (parent
!= NULL
) {
2345 if (parent
->type
== XML_ELEMENT_NODE
) {
2346 xmlAddChild(parent
, ret
);
2348 xmlAddSibling(parent
, ret
);
2353 * Insert the defaulted attributes from the DTD only if requested:
2355 if ((nb_defaulted
!= 0) &&
2356 ((ctxt
->loadsubset
& XML_COMPLETE_ATTRS
) == 0))
2357 nb_attributes
-= nb_defaulted
;
2360 * Search the namespace if it wasn't already found
2361 * Note that, if prefix is NULL, this searches for the default Ns
2363 if ((URI
!= NULL
) && (ret
->ns
== NULL
)) {
2364 ret
->ns
= xmlSearchNs(ctxt
->myDoc
, parent
, prefix
);
2365 if ((ret
->ns
== NULL
) && (xmlStrEqual(prefix
, BAD_CAST
"xml"))) {
2366 ret
->ns
= xmlSearchNs(ctxt
->myDoc
, ret
, prefix
);
2368 if (ret
->ns
== NULL
) {
2369 ns
= xmlNewNs(ret
, NULL
, prefix
);
2372 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2376 xmlNsWarnMsg(ctxt
, XML_NS_ERR_UNDEFINED_NAMESPACE
,
2377 "Namespace prefix %s was not found\n",
2380 xmlNsWarnMsg(ctxt
, XML_NS_ERR_UNDEFINED_NAMESPACE
,
2381 "Namespace default prefix was not found\n",
2387 * process all the other attributes
2389 if (nb_attributes
> 0) {
2390 for (j
= 0,i
= 0;i
< nb_attributes
;i
++,j
+=5) {
2392 * Handle the rare case of an undefined atribute prefix
2394 if ((attributes
[j
+1] != NULL
) && (attributes
[j
+2] == NULL
)) {
2395 if (ctxt
->dictNames
) {
2396 const xmlChar
*fullname
;
2398 fullname
= xmlDictQLookup(ctxt
->dict
, attributes
[j
+1],
2400 if (fullname
!= NULL
) {
2401 xmlSAX2AttributeNs(ctxt
, fullname
, NULL
,
2402 attributes
[j
+3], attributes
[j
+4]);
2406 lname
= xmlBuildQName(attributes
[j
], attributes
[j
+1],
2408 if (lname
!= NULL
) {
2409 xmlSAX2AttributeNs(ctxt
, lname
, NULL
,
2410 attributes
[j
+3], attributes
[j
+4]);
2416 xmlSAX2AttributeNs(ctxt
, attributes
[j
], attributes
[j
+1],
2417 attributes
[j
+3], attributes
[j
+4]);
2421 #ifdef LIBXML_VALID_ENABLED
2423 * If it's the Document root, finish the DTD validation and
2424 * check the document root element for validity
2426 if ((ctxt
->validate
) && (ctxt
->vctxt
.finishDtd
== XML_CTXT_FINISH_DTD_0
)) {
2429 chk
= xmlValidateDtdFinal(&ctxt
->vctxt
, ctxt
->myDoc
);
2433 ctxt
->wellFormed
= 0;
2434 ctxt
->valid
&= xmlValidateRoot(&ctxt
->vctxt
, ctxt
->myDoc
);
2435 ctxt
->vctxt
.finishDtd
= XML_CTXT_FINISH_DTD_1
;
2437 #endif /* LIBXML_VALID_ENABLED */
2441 * xmlSAX2EndElementNs:
2442 * @ctx: the user data (XML parser context)
2443 * @localname: the local name of the element
2444 * @prefix: the element namespace prefix if available
2445 * @URI: the element namespace name if available
2447 * SAX2 callback when an element end has been detected by the parser.
2448 * It provides the namespace informations for the element.
2451 xmlSAX2EndElementNs(void *ctx
,
2452 const xmlChar
* localname ATTRIBUTE_UNUSED
,
2453 const xmlChar
* prefix ATTRIBUTE_UNUSED
,
2454 const xmlChar
* URI ATTRIBUTE_UNUSED
)
2456 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2457 xmlParserNodeInfo node_info
;
2460 if (ctx
== NULL
) return;
2462 /* Capture end position and add node */
2463 if ((ctxt
->record_info
) && (cur
!= NULL
)) {
2464 node_info
.end_pos
= ctxt
->input
->cur
- ctxt
->input
->base
;
2465 node_info
.end_line
= ctxt
->input
->line
;
2466 node_info
.node
= cur
;
2467 xmlParserAddNodeInfo(ctxt
, &node_info
);
2471 #ifdef LIBXML_VALID_ENABLED
2472 if (ctxt
->validate
&& ctxt
->wellFormed
&&
2473 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
2474 ctxt
->valid
&= xmlValidateOneElement(&ctxt
->vctxt
, ctxt
->myDoc
, cur
);
2475 #endif /* LIBXML_VALID_ENABLED */
2478 * end of parsing of this node.
2485 * @ctx: the user data (XML parser context)
2486 * @name: The entity name
2488 * called when an entity xmlSAX2Reference is detected.
2491 xmlSAX2Reference(void *ctx
, const xmlChar
*name
)
2493 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2496 if (ctx
== NULL
) return;
2498 xmlGenericError(xmlGenericErrorContext
,
2499 "SAX.xmlSAX2Reference(%s)\n", name
);
2502 ret
= xmlNewCharRef(ctxt
->myDoc
, name
);
2504 ret
= xmlNewReference(ctxt
->myDoc
, name
);
2505 #ifdef DEBUG_SAX_TREE
2506 xmlGenericError(xmlGenericErrorContext
,
2507 "add xmlSAX2Reference %s to %s \n", name
, ctxt
->node
->name
);
2509 if (xmlAddChild(ctxt
->node
, ret
) == NULL
) {
2515 * xmlSAX2Characters:
2516 * @ctx: the user data (XML parser context)
2517 * @ch: a xmlChar string
2518 * @len: the number of xmlChar
2520 * receiving some chars from the parser.
2523 xmlSAX2Characters(void *ctx
, const xmlChar
*ch
, int len
)
2525 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2526 xmlNodePtr lastChild
;
2528 if (ctx
== NULL
) return;
2530 xmlGenericError(xmlGenericErrorContext
,
2531 "SAX.xmlSAX2Characters(%.30s, %d)\n", ch
, len
);
2534 * Handle the data if any. If there is no child
2535 * add it as content, otherwise if the last child is text,
2536 * concatenate it, else create a new node of type text.
2539 if (ctxt
->node
== NULL
) {
2540 #ifdef DEBUG_SAX_TREE
2541 xmlGenericError(xmlGenericErrorContext
,
2542 "add chars: ctxt->node == NULL !\n");
2546 lastChild
= ctxt
->node
->last
;
2547 #ifdef DEBUG_SAX_TREE
2548 xmlGenericError(xmlGenericErrorContext
,
2549 "add chars to %s \n", ctxt
->node
->name
);
2553 * Here we needed an accelerator mechanism in case of very large
2554 * elements. Use an attribute in the structure !!!
2556 if (lastChild
== NULL
) {
2557 lastChild
= xmlSAX2TextNode(ctxt
, ch
, len
);
2558 if (lastChild
!= NULL
) {
2559 ctxt
->node
->children
= lastChild
;
2560 ctxt
->node
->last
= lastChild
;
2561 lastChild
->parent
= ctxt
->node
;
2562 lastChild
->doc
= ctxt
->node
->doc
;
2563 ctxt
->nodelen
= len
;
2564 ctxt
->nodemem
= len
+ 1;
2566 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters");
2570 int coalesceText
= (lastChild
!= NULL
) &&
2571 (lastChild
->type
== XML_TEXT_NODE
) &&
2572 (lastChild
->name
== xmlStringText
);
2573 if ((coalesceText
) && (ctxt
->nodemem
!= 0)) {
2575 * The whole point of maintaining nodelen and nodemem,
2576 * xmlTextConcat is too costly, i.e. compute length,
2577 * reallocate a new buffer, move data, append ch. Here
2578 * We try to minimaze realloc() uses and avoid copying
2579 * and recomputing length over and over.
2581 if (lastChild
->content
== (xmlChar
*)&(lastChild
->properties
)) {
2582 lastChild
->content
= xmlStrdup(lastChild
->content
);
2583 lastChild
->properties
= NULL
;
2584 } else if ((ctxt
->nodemem
== ctxt
->nodelen
+ 1) &&
2585 (xmlDictOwns(ctxt
->dict
, lastChild
->content
))) {
2586 lastChild
->content
= xmlStrdup(lastChild
->content
);
2588 if (lastChild
->content
== NULL
) {
2589 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters: xmlStrdup returned NULL");
2592 if (((size_t)ctxt
->nodelen
+ (size_t)len
> XML_MAX_TEXT_LENGTH
) &&
2593 ((ctxt
->options
& XML_PARSE_HUGE
) == 0)) {
2594 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters: huge text node");
2597 if ((size_t)ctxt
->nodelen
> SIZE_T_MAX
- (size_t)len
||
2598 (size_t)ctxt
->nodemem
+ (size_t)len
> SIZE_T_MAX
/ 2) {
2599 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters overflow prevented");
2602 if (ctxt
->nodelen
+ len
>= ctxt
->nodemem
) {
2606 size
= ctxt
->nodemem
+ len
;
2608 newbuf
= (xmlChar
*) xmlRealloc(lastChild
->content
,size
);
2609 if (newbuf
== NULL
) {
2610 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters");
2613 ctxt
->nodemem
= size
;
2614 lastChild
->content
= newbuf
;
2616 memcpy(&lastChild
->content
[ctxt
->nodelen
], ch
, len
);
2617 ctxt
->nodelen
+= len
;
2618 lastChild
->content
[ctxt
->nodelen
] = 0;
2619 } else if (coalesceText
) {
2620 if (xmlTextConcat(lastChild
, ch
, len
)) {
2621 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters");
2623 if (ctxt
->node
->children
!= NULL
) {
2624 ctxt
->nodelen
= xmlStrlen(lastChild
->content
);
2625 ctxt
->nodemem
= ctxt
->nodelen
+ 1;
2628 /* Mixed content, first time */
2629 lastChild
= xmlSAX2TextNode(ctxt
, ch
, len
);
2630 if (lastChild
!= NULL
) {
2631 xmlAddChild(ctxt
->node
, lastChild
);
2632 if (ctxt
->node
->children
!= NULL
) {
2633 ctxt
->nodelen
= len
;
2634 ctxt
->nodemem
= len
+ 1;
2642 * xmlSAX2IgnorableWhitespace:
2643 * @ctx: the user data (XML parser context)
2644 * @ch: a xmlChar string
2645 * @len: the number of xmlChar
2647 * receiving some ignorable whitespaces from the parser.
2648 * UNUSED: by default the DOM building will use xmlSAX2Characters
2651 xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED
, const xmlChar
*ch ATTRIBUTE_UNUSED
, int len ATTRIBUTE_UNUSED
)
2653 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
2655 xmlGenericError(xmlGenericErrorContext
,
2656 "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch
, len
);
2661 * xmlSAX2ProcessingInstruction:
2662 * @ctx: the user data (XML parser context)
2663 * @target: the target name
2664 * @data: the PI data's
2666 * A processing instruction has been parsed.
2669 xmlSAX2ProcessingInstruction(void *ctx
, const xmlChar
*target
,
2670 const xmlChar
*data
)
2672 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2676 if (ctx
== NULL
) return;
2677 parent
= ctxt
->node
;
2679 xmlGenericError(xmlGenericErrorContext
,
2680 "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target
, data
);
2683 ret
= xmlNewDocPI(ctxt
->myDoc
, target
, data
);
2684 if (ret
== NULL
) return;
2686 if (ctxt
->linenumbers
) {
2687 if (ctxt
->input
!= NULL
) {
2688 if (ctxt
->input
->line
< 65535)
2689 ret
->line
= (short) ctxt
->input
->line
;
2694 if (ctxt
->inSubset
== 1) {
2695 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->intSubset
, ret
);
2697 } else if (ctxt
->inSubset
== 2) {
2698 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->extSubset
, ret
);
2701 if (parent
== NULL
) {
2702 #ifdef DEBUG_SAX_TREE
2703 xmlGenericError(xmlGenericErrorContext
,
2704 "Setting PI %s as root\n", target
);
2706 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
2709 if (parent
->type
== XML_ELEMENT_NODE
) {
2710 #ifdef DEBUG_SAX_TREE
2711 xmlGenericError(xmlGenericErrorContext
,
2712 "adding PI %s child to %s\n", target
, parent
->name
);
2714 xmlAddChild(parent
, ret
);
2716 #ifdef DEBUG_SAX_TREE
2717 xmlGenericError(xmlGenericErrorContext
,
2718 "adding PI %s sibling to ", target
);
2719 xmlDebugDumpOneNode(stderr
, parent
, 0);
2721 xmlAddSibling(parent
, ret
);
2727 * @ctx: the user data (XML parser context)
2728 * @value: the xmlSAX2Comment content
2730 * A xmlSAX2Comment has been parsed.
2733 xmlSAX2Comment(void *ctx
, const xmlChar
*value
)
2735 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2739 if (ctx
== NULL
) return;
2740 parent
= ctxt
->node
;
2742 xmlGenericError(xmlGenericErrorContext
, "SAX.xmlSAX2Comment(%s)\n", value
);
2744 ret
= xmlNewDocComment(ctxt
->myDoc
, value
);
2745 if (ret
== NULL
) return;
2746 if (ctxt
->linenumbers
) {
2747 if (ctxt
->input
!= NULL
) {
2748 if (ctxt
->input
->line
< 65535)
2749 ret
->line
= (short) ctxt
->input
->line
;
2755 if (ctxt
->inSubset
== 1) {
2756 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->intSubset
, ret
);
2758 } else if (ctxt
->inSubset
== 2) {
2759 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->extSubset
, ret
);
2762 if (parent
== NULL
) {
2763 #ifdef DEBUG_SAX_TREE
2764 xmlGenericError(xmlGenericErrorContext
,
2765 "Setting xmlSAX2Comment as root\n");
2767 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
2770 if (parent
->type
== XML_ELEMENT_NODE
) {
2771 #ifdef DEBUG_SAX_TREE
2772 xmlGenericError(xmlGenericErrorContext
,
2773 "adding xmlSAX2Comment child to %s\n", parent
->name
);
2775 xmlAddChild(parent
, ret
);
2777 #ifdef DEBUG_SAX_TREE
2778 xmlGenericError(xmlGenericErrorContext
,
2779 "adding xmlSAX2Comment sibling to ");
2780 xmlDebugDumpOneNode(stderr
, parent
, 0);
2782 xmlAddSibling(parent
, ret
);
2787 * xmlSAX2CDataBlock:
2788 * @ctx: the user data (XML parser context)
2789 * @value: The pcdata content
2790 * @len: the block length
2792 * called when a pcdata block has been parsed
2795 xmlSAX2CDataBlock(void *ctx
, const xmlChar
*value
, int len
)
2797 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2798 xmlNodePtr ret
, lastChild
;
2800 if (ctx
== NULL
) return;
2802 xmlGenericError(xmlGenericErrorContext
,
2803 "SAX.pcdata(%.10s, %d)\n", value
, len
);
2805 lastChild
= xmlGetLastChild(ctxt
->node
);
2806 #ifdef DEBUG_SAX_TREE
2807 xmlGenericError(xmlGenericErrorContext
,
2808 "add chars to %s \n", ctxt
->node
->name
);
2810 if ((lastChild
!= NULL
) &&
2811 (lastChild
->type
== XML_CDATA_SECTION_NODE
)) {
2812 xmlTextConcat(lastChild
, value
, len
);
2814 ret
= xmlNewCDataBlock(ctxt
->myDoc
, value
, len
);
2815 if (xmlAddChild(ctxt
->node
, ret
) == NULL
)
2820 static int xmlSAX2DefaultVersionValue
= 2;
2822 #ifdef LIBXML_SAX1_ENABLED
2824 * xmlSAXDefaultVersion:
2825 * @version: the version, 1 or 2
2827 * Set the default version of SAX used globally by the library.
2828 * By default, during initialization the default is set to 2.
2829 * Note that it is generally a better coding style to use
2830 * xmlSAXVersion() to set up the version explicitly for a given
2833 * Returns the previous value in case of success and -1 in case of error.
2836 xmlSAXDefaultVersion(int version
)
2838 int ret
= xmlSAX2DefaultVersionValue
;
2840 if ((version
!= 1) && (version
!= 2))
2842 xmlSAX2DefaultVersionValue
= version
;
2845 #endif /* LIBXML_SAX1_ENABLED */
2849 * @hdlr: the SAX handler
2850 * @version: the version, 1 or 2
2852 * Initialize the default XML SAX handler according to the version
2854 * Returns 0 in case of success and -1 in case of error.
2857 xmlSAXVersion(xmlSAXHandler
*hdlr
, int version
)
2859 if (hdlr
== NULL
) return(-1);
2861 hdlr
->startElement
= NULL
;
2862 hdlr
->endElement
= NULL
;
2863 hdlr
->startElementNs
= xmlSAX2StartElementNs
;
2864 hdlr
->endElementNs
= xmlSAX2EndElementNs
;
2865 hdlr
->serror
= NULL
;
2866 hdlr
->initialized
= XML_SAX2_MAGIC
;
2867 #ifdef LIBXML_SAX1_ENABLED
2868 } else if (version
== 1) {
2869 hdlr
->startElement
= xmlSAX2StartElement
;
2870 hdlr
->endElement
= xmlSAX2EndElement
;
2871 hdlr
->initialized
= 1;
2872 #endif /* LIBXML_SAX1_ENABLED */
2875 hdlr
->internalSubset
= xmlSAX2InternalSubset
;
2876 hdlr
->externalSubset
= xmlSAX2ExternalSubset
;
2877 hdlr
->isStandalone
= xmlSAX2IsStandalone
;
2878 hdlr
->hasInternalSubset
= xmlSAX2HasInternalSubset
;
2879 hdlr
->hasExternalSubset
= xmlSAX2HasExternalSubset
;
2880 hdlr
->resolveEntity
= xmlSAX2ResolveEntity
;
2881 hdlr
->getEntity
= xmlSAX2GetEntity
;
2882 hdlr
->getParameterEntity
= xmlSAX2GetParameterEntity
;
2883 hdlr
->entityDecl
= xmlSAX2EntityDecl
;
2884 hdlr
->attributeDecl
= xmlSAX2AttributeDecl
;
2885 hdlr
->elementDecl
= xmlSAX2ElementDecl
;
2886 hdlr
->notationDecl
= xmlSAX2NotationDecl
;
2887 hdlr
->unparsedEntityDecl
= xmlSAX2UnparsedEntityDecl
;
2888 hdlr
->setDocumentLocator
= xmlSAX2SetDocumentLocator
;
2889 hdlr
->startDocument
= xmlSAX2StartDocument
;
2890 hdlr
->endDocument
= xmlSAX2EndDocument
;
2891 hdlr
->reference
= xmlSAX2Reference
;
2892 hdlr
->characters
= xmlSAX2Characters
;
2893 hdlr
->cdataBlock
= xmlSAX2CDataBlock
;
2894 hdlr
->ignorableWhitespace
= xmlSAX2Characters
;
2895 hdlr
->processingInstruction
= xmlSAX2ProcessingInstruction
;
2896 hdlr
->comment
= xmlSAX2Comment
;
2897 hdlr
->warning
= xmlParserWarning
;
2898 hdlr
->error
= xmlParserError
;
2899 hdlr
->fatalError
= xmlParserError
;
2905 * xmlSAX2InitDefaultSAXHandler:
2906 * @hdlr: the SAX handler
2907 * @warning: flag if non-zero sets the handler warning procedure
2909 * Initialize the default XML SAX2 handler
2912 xmlSAX2InitDefaultSAXHandler(xmlSAXHandler
*hdlr
, int warning
)
2914 if ((hdlr
== NULL
) || (hdlr
->initialized
!= 0))
2917 xmlSAXVersion(hdlr
, xmlSAX2DefaultVersionValue
);
2919 hdlr
->warning
= NULL
;
2921 hdlr
->warning
= xmlParserWarning
;
2925 * xmlDefaultSAXHandlerInit:
2927 * Initialize the default SAX2 handler
2930 xmlDefaultSAXHandlerInit(void)
2932 #ifdef LIBXML_SAX1_ENABLED
2933 xmlSAXVersion((xmlSAXHandlerPtr
) &xmlDefaultSAXHandler
, 1);
2934 #endif /* LIBXML_SAX1_ENABLED */
2937 #ifdef LIBXML_HTML_ENABLED
2940 * xmlSAX2InitHtmlDefaultSAXHandler:
2941 * @hdlr: the SAX handler
2943 * Initialize the default HTML SAX2 handler
2946 xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler
*hdlr
)
2948 if ((hdlr
== NULL
) || (hdlr
->initialized
!= 0))
2951 hdlr
->internalSubset
= xmlSAX2InternalSubset
;
2952 hdlr
->externalSubset
= NULL
;
2953 hdlr
->isStandalone
= NULL
;
2954 hdlr
->hasInternalSubset
= NULL
;
2955 hdlr
->hasExternalSubset
= NULL
;
2956 hdlr
->resolveEntity
= NULL
;
2957 hdlr
->getEntity
= xmlSAX2GetEntity
;
2958 hdlr
->getParameterEntity
= NULL
;
2959 hdlr
->entityDecl
= NULL
;
2960 hdlr
->attributeDecl
= NULL
;
2961 hdlr
->elementDecl
= NULL
;
2962 hdlr
->notationDecl
= NULL
;
2963 hdlr
->unparsedEntityDecl
= NULL
;
2964 hdlr
->setDocumentLocator
= xmlSAX2SetDocumentLocator
;
2965 hdlr
->startDocument
= xmlSAX2StartDocument
;
2966 hdlr
->endDocument
= xmlSAX2EndDocument
;
2967 hdlr
->startElement
= xmlSAX2StartElement
;
2968 hdlr
->endElement
= xmlSAX2EndElement
;
2969 hdlr
->reference
= NULL
;
2970 hdlr
->characters
= xmlSAX2Characters
;
2971 hdlr
->cdataBlock
= xmlSAX2CDataBlock
;
2972 hdlr
->ignorableWhitespace
= xmlSAX2IgnorableWhitespace
;
2973 hdlr
->processingInstruction
= xmlSAX2ProcessingInstruction
;
2974 hdlr
->comment
= xmlSAX2Comment
;
2975 hdlr
->warning
= xmlParserWarning
;
2976 hdlr
->error
= xmlParserError
;
2977 hdlr
->fatalError
= xmlParserError
;
2979 hdlr
->initialized
= 1;
2983 * htmlDefaultSAXHandlerInit:
2985 * Initialize the default SAX handler
2988 htmlDefaultSAXHandlerInit(void)
2990 xmlSAX2InitHtmlDefaultSAXHandler((xmlSAXHandlerPtr
) &htmlDefaultSAXHandler
);
2993 #endif /* LIBXML_HTML_ENABLED */
2995 #ifdef LIBXML_DOCB_ENABLED
2998 * xmlSAX2InitDocbDefaultSAXHandler:
2999 * @hdlr: the SAX handler
3001 * Initialize the default DocBook SAX2 handler
3004 xmlSAX2InitDocbDefaultSAXHandler(xmlSAXHandler
*hdlr
)
3006 if ((hdlr
== NULL
) || (hdlr
->initialized
!= 0))
3009 hdlr
->internalSubset
= xmlSAX2InternalSubset
;
3010 hdlr
->externalSubset
= NULL
;
3011 hdlr
->isStandalone
= xmlSAX2IsStandalone
;
3012 hdlr
->hasInternalSubset
= xmlSAX2HasInternalSubset
;
3013 hdlr
->hasExternalSubset
= xmlSAX2HasExternalSubset
;
3014 hdlr
->resolveEntity
= xmlSAX2ResolveEntity
;
3015 hdlr
->getEntity
= xmlSAX2GetEntity
;
3016 hdlr
->getParameterEntity
= NULL
;
3017 hdlr
->entityDecl
= xmlSAX2EntityDecl
;
3018 hdlr
->attributeDecl
= NULL
;
3019 hdlr
->elementDecl
= NULL
;
3020 hdlr
->notationDecl
= NULL
;
3021 hdlr
->unparsedEntityDecl
= NULL
;
3022 hdlr
->setDocumentLocator
= xmlSAX2SetDocumentLocator
;
3023 hdlr
->startDocument
= xmlSAX2StartDocument
;
3024 hdlr
->endDocument
= xmlSAX2EndDocument
;
3025 hdlr
->startElement
= xmlSAX2StartElement
;
3026 hdlr
->endElement
= xmlSAX2EndElement
;
3027 hdlr
->reference
= xmlSAX2Reference
;
3028 hdlr
->characters
= xmlSAX2Characters
;
3029 hdlr
->cdataBlock
= NULL
;
3030 hdlr
->ignorableWhitespace
= xmlSAX2IgnorableWhitespace
;
3031 hdlr
->processingInstruction
= NULL
;
3032 hdlr
->comment
= xmlSAX2Comment
;
3033 hdlr
->warning
= xmlParserWarning
;
3034 hdlr
->error
= xmlParserError
;
3035 hdlr
->fatalError
= xmlParserError
;
3037 hdlr
->initialized
= 1;
3041 * docbDefaultSAXHandlerInit:
3043 * Initialize the default SAX handler
3046 docbDefaultSAXHandlerInit(void)
3048 xmlSAX2InitDocbDefaultSAXHandler((xmlSAXHandlerPtr
) &docbDefaultSAXHandler
);
3051 #endif /* LIBXML_DOCB_ENABLED */
3053 #include "elfgcchack.h"