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>
14 #include <libxml/xmlmemory.h>
15 #include <libxml/tree.h>
16 #include <libxml/parser.h>
17 #include <libxml/parserInternals.h>
18 #include <libxml/valid.h>
19 #include <libxml/entities.h>
20 #include <libxml/xmlerror.h>
21 #include <libxml/debugXML.h>
22 #include <libxml/xmlIO.h>
23 #include <libxml/SAX.h>
24 #include <libxml/uri.h>
25 #include <libxml/valid.h>
26 #include <libxml/HTMLtree.h>
27 #include <libxml/globals.h>
29 /* #define DEBUG_SAX2 */
30 /* #define DEBUG_SAX2_TREE */
35 * macro to flag unimplemented blocks
36 * XML_CATALOG_PREFER user env to select between system/public prefered
37 * option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk>
38 *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with
39 *> values "system" and "public". I have made the default be "system" to
43 xmlGenericError(xmlGenericErrorContext, \
44 "Unimplemented block at %s:%d\n", \
49 * @ctxt: an XML validation parser context
50 * @msg: a string to accompany the error message
53 xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt
, const char *msg
) {
55 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->error
!= NULL
))
56 ctxt
->sax
->error(ctxt
->userData
, "%s: out of memory\n", msg
);
57 ctxt
->errNo
= XML_ERR_NO_MEMORY
;
58 ctxt
->instate
= XML_PARSER_EOF
;
65 * @ctxt: an XML validation parser context
66 * @error: the error number
67 * @msg: the error message
71 * Handle a validation error
74 xmlErrValid(xmlParserCtxtPtr ctxt
, xmlParserErrors error
,
75 const char *msg
, const char *str1
, const char *str2
)
77 xmlStructuredErrorFunc schannel
= NULL
;
79 if ((ctxt
!= NULL
) && (ctxt
->disableSAX
!= 0) &&
80 (ctxt
->instate
== XML_PARSER_EOF
))
84 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->initialized
== XML_SAX2_MAGIC
))
85 schannel
= ctxt
->sax
->serror
;
87 __xmlRaiseError(schannel
,
88 ctxt
->vctxt
.error
, ctxt
->vctxt
.userData
,
89 ctxt
, NULL
, XML_FROM_DTD
, error
,
90 XML_ERR_ERROR
, NULL
, 0, (const char *) str1
,
91 (const char *) str2
, NULL
, 0, 0,
92 msg
, (const char *) str1
, (const char *) str2
);
99 * @ctxt: an XML parser context
100 * @error: the error number
101 * @msg: the error message
102 * @str1: an error string
103 * @str2: an error string
105 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
108 xmlFatalErrMsg(xmlParserCtxtPtr ctxt
, xmlParserErrors error
,
109 const char *msg
, const xmlChar
*str1
, const xmlChar
*str2
)
111 if ((ctxt
!= NULL
) && (ctxt
->disableSAX
!= 0) &&
112 (ctxt
->instate
== XML_PARSER_EOF
))
116 __xmlRaiseError(NULL
, NULL
, NULL
, ctxt
, NULL
, XML_FROM_PARSER
, error
,
117 XML_ERR_FATAL
, NULL
, 0,
118 (const char *) str1
, (const char *) str2
,
119 NULL
, 0, 0, msg
, str1
, str2
);
121 ctxt
->wellFormed
= 0;
123 if (ctxt
->recovery
== 0)
124 ctxt
->disableSAX
= 1;
130 * @ctxt: an XML parser context
131 * @error: the error number
132 * @msg: the error message
133 * @str1: an error string
134 * @str2: an error string
136 * Handle a parser warning
139 xmlWarnMsg(xmlParserCtxtPtr ctxt
, xmlParserErrors error
,
140 const char *msg
, const xmlChar
*str1
)
142 if ((ctxt
!= NULL
) && (ctxt
->disableSAX
!= 0) &&
143 (ctxt
->instate
== XML_PARSER_EOF
))
147 __xmlRaiseError(NULL
, NULL
, NULL
, ctxt
, NULL
, XML_FROM_PARSER
, error
,
148 XML_ERR_WARNING
, NULL
, 0,
149 (const char *) str1
, NULL
,
150 NULL
, 0, 0, msg
, str1
);
155 * @ctxt: an XML parser context
156 * @error: the error number
157 * @msg: the error message
158 * @str1: an error string
159 * @str2: an error string
161 * Handle a namespace error
164 xmlNsErrMsg(xmlParserCtxtPtr ctxt
, xmlParserErrors error
,
165 const char *msg
, const xmlChar
*str1
, const xmlChar
*str2
)
167 if ((ctxt
!= NULL
) && (ctxt
->disableSAX
!= 0) &&
168 (ctxt
->instate
== XML_PARSER_EOF
))
172 __xmlRaiseError(NULL
, NULL
, NULL
, ctxt
, NULL
, XML_FROM_NAMESPACE
, error
,
173 XML_ERR_ERROR
, NULL
, 0,
174 (const char *) str1
, (const char *) str2
,
175 NULL
, 0, 0, msg
, str1
, str2
);
180 * @ctxt: an XML parser context
181 * @error: the error number
182 * @msg: the error message
183 * @str1: an error string
185 * Handle a namespace warning
188 xmlNsWarnMsg(xmlParserCtxtPtr ctxt
, xmlParserErrors error
,
189 const char *msg
, const xmlChar
*str1
, const xmlChar
*str2
)
191 if ((ctxt
!= NULL
) && (ctxt
->disableSAX
!= 0) &&
192 (ctxt
->instate
== XML_PARSER_EOF
))
196 __xmlRaiseError(NULL
, NULL
, NULL
, ctxt
, NULL
, XML_FROM_NAMESPACE
, error
,
197 XML_ERR_WARNING
, NULL
, 0,
198 (const char *) str1
, (const char *) str2
,
199 NULL
, 0, 0, msg
, str1
, str2
);
203 * xmlSAX2GetPublicId:
204 * @ctx: the user data (XML parser context)
206 * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
208 * Returns a xmlChar *
211 xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED
)
213 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
218 * xmlSAX2GetSystemId:
219 * @ctx: the user data (XML parser context)
221 * Provides the system ID, basically URL or filename e.g.
222 * http://www.sgmlsource.com/dtds/memo.dtd
224 * Returns a xmlChar *
227 xmlSAX2GetSystemId(void *ctx
)
229 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
230 if ((ctx
== NULL
) || (ctxt
->input
== NULL
)) return(0);
231 return((const xmlChar
*) ctxt
->input
->filename
);
235 * xmlSAX2GetLineNumber:
236 * @ctx: the user data (XML parser context)
238 * Provide the line number of the current parsing point.
243 xmlSAX2GetLineNumber(void *ctx
)
245 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
246 if ((ctx
== NULL
) || (ctxt
->input
== NULL
)) return(0);
247 return(ctxt
->input
->line
);
251 * xmlSAX2GetColumnNumber:
252 * @ctx: the user data (XML parser context)
254 * Provide the column number of the current parsing point.
259 xmlSAX2GetColumnNumber(void *ctx
)
261 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
262 if ((ctx
== NULL
) || (ctxt
->input
== NULL
)) return(0);
263 return(ctxt
->input
->col
);
267 * xmlSAX2IsStandalone:
268 * @ctx: the user data (XML parser context)
270 * Is this document tagged standalone ?
275 xmlSAX2IsStandalone(void *ctx
)
277 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
278 if ((ctx
== NULL
) || (ctxt
->myDoc
== NULL
)) return(0);
279 return(ctxt
->myDoc
->standalone
== 1);
283 * xmlSAX2HasInternalSubset:
284 * @ctx: the user data (XML parser context)
286 * Does this document has an internal subset
291 xmlSAX2HasInternalSubset(void *ctx
)
293 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
294 if ((ctxt
== NULL
) || (ctxt
->myDoc
== NULL
)) return(0);
295 return(ctxt
->myDoc
->intSubset
!= NULL
);
299 * xmlSAX2HasExternalSubset:
300 * @ctx: the user data (XML parser context)
302 * Does this document has an external subset
307 xmlSAX2HasExternalSubset(void *ctx
)
309 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
310 if ((ctxt
== NULL
) || (ctxt
->myDoc
== NULL
)) return(0);
311 return(ctxt
->myDoc
->extSubset
!= NULL
);
315 * xmlSAX2InternalSubset:
316 * @ctx: the user data (XML parser context)
317 * @name: the root element name
318 * @ExternalID: the external ID
319 * @SystemID: the SYSTEM ID (e.g. filename or URL)
321 * Callback on internal subset declaration.
324 xmlSAX2InternalSubset(void *ctx
, const xmlChar
*name
,
325 const xmlChar
*ExternalID
, const xmlChar
*SystemID
)
327 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
329 if (ctx
== NULL
) return;
331 xmlGenericError(xmlGenericErrorContext
,
332 "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n",
333 name
, ExternalID
, SystemID
);
336 if (ctxt
->myDoc
== NULL
)
338 dtd
= xmlGetIntSubset(ctxt
->myDoc
);
342 xmlUnlinkNode((xmlNodePtr
) dtd
);
344 ctxt
->myDoc
->intSubset
= NULL
;
346 ctxt
->myDoc
->intSubset
=
347 xmlCreateIntSubset(ctxt
->myDoc
, name
, ExternalID
, SystemID
);
348 if (ctxt
->myDoc
->intSubset
== NULL
)
349 xmlSAX2ErrMemory(ctxt
, "xmlSAX2InternalSubset");
353 * xmlSAX2ExternalSubset:
354 * @ctx: the user data (XML parser context)
355 * @name: the root element name
356 * @ExternalID: the external ID
357 * @SystemID: the SYSTEM ID (e.g. filename or URL)
359 * Callback on external subset declaration.
362 xmlSAX2ExternalSubset(void *ctx
, const xmlChar
*name
,
363 const xmlChar
*ExternalID
, const xmlChar
*SystemID
)
365 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
366 if (ctx
== NULL
) return;
368 xmlGenericError(xmlGenericErrorContext
,
369 "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n",
370 name
, ExternalID
, SystemID
);
372 if (((ExternalID
!= NULL
) || (SystemID
!= NULL
)) &&
373 (((ctxt
->validate
) || (ctxt
->loadsubset
!= 0)) &&
374 (ctxt
->wellFormed
&& ctxt
->myDoc
))) {
376 * Try to fetch and parse the external subset.
378 xmlParserInputPtr oldinput
;
381 xmlParserInputPtr
*oldinputTab
;
382 xmlParserInputPtr input
= NULL
;
387 * Ask the Entity resolver to load the damn thing
389 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->resolveEntity
!= NULL
))
390 input
= ctxt
->sax
->resolveEntity(ctxt
->userData
, ExternalID
,
396 xmlNewDtd(ctxt
->myDoc
, name
, ExternalID
, SystemID
);
399 * make sure we won't destroy the main document context
401 oldinput
= ctxt
->input
;
402 oldinputNr
= ctxt
->inputNr
;
403 oldinputMax
= ctxt
->inputMax
;
404 oldinputTab
= ctxt
->inputTab
;
405 oldcharset
= ctxt
->charset
;
407 ctxt
->inputTab
= (xmlParserInputPtr
*)
408 xmlMalloc(5 * sizeof(xmlParserInputPtr
));
409 if (ctxt
->inputTab
== NULL
) {
410 xmlSAX2ErrMemory(ctxt
, "xmlSAX2ExternalSubset");
411 ctxt
->input
= oldinput
;
412 ctxt
->inputNr
= oldinputNr
;
413 ctxt
->inputMax
= oldinputMax
;
414 ctxt
->inputTab
= oldinputTab
;
415 ctxt
->charset
= oldcharset
;
421 xmlPushInput(ctxt
, input
);
424 * On the fly encoding conversion if needed
426 if (ctxt
->input
->length
>= 4) {
427 enc
= xmlDetectCharEncoding(ctxt
->input
->cur
, 4);
428 xmlSwitchEncoding(ctxt
, enc
);
431 if (input
->filename
== NULL
)
432 input
->filename
= (char *) xmlCanonicPath(SystemID
);
435 input
->base
= ctxt
->input
->cur
;
436 input
->cur
= ctxt
->input
->cur
;
440 * let's parse that entity knowing it's an external subset.
442 xmlParseExternalSubset(ctxt
, ExternalID
, SystemID
);
445 * Free up the external entities
448 while (ctxt
->inputNr
> 1)
450 xmlFreeInputStream(ctxt
->input
);
451 xmlFree(ctxt
->inputTab
);
454 * Restore the parsing context of the main entity
456 ctxt
->input
= oldinput
;
457 ctxt
->inputNr
= oldinputNr
;
458 ctxt
->inputMax
= oldinputMax
;
459 ctxt
->inputTab
= oldinputTab
;
460 ctxt
->charset
= oldcharset
;
461 /* ctxt->wellFormed = oldwellFormed; */
466 * xmlSAX2ResolveEntity:
467 * @ctx: the user data (XML parser context)
468 * @publicId: The public ID of the entity
469 * @systemId: The system ID of the entity
471 * The entity loader, to control the loading of external entities,
472 * the application can either:
473 * - override this xmlSAX2ResolveEntity() callback in the SAX block
474 * - or better use the xmlSetExternalEntityLoader() function to
475 * set up it's own entity resolution routine
477 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
480 xmlSAX2ResolveEntity(void *ctx
, const xmlChar
*publicId
, const xmlChar
*systemId
)
482 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
483 xmlParserInputPtr ret
;
485 const char *base
= NULL
;
487 if (ctx
== NULL
) return(NULL
);
488 if (ctxt
->input
!= NULL
)
489 base
= ctxt
->input
->filename
;
491 base
= ctxt
->directory
;
493 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
496 xmlGenericError(xmlGenericErrorContext
,
497 "SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId
, systemId
);
500 ret
= xmlLoadExternalEntity((const char *) URI
,
501 (const char *) publicId
, ctxt
);
509 * @ctx: the user data (XML parser context)
510 * @name: The entity name
512 * Get an entity by name
514 * Returns the xmlEntityPtr if found.
517 xmlSAX2GetEntity(void *ctx
, const xmlChar
*name
)
519 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
520 xmlEntityPtr ret
= NULL
;
522 if (ctx
== NULL
) return(NULL
);
524 xmlGenericError(xmlGenericErrorContext
,
525 "SAX.xmlSAX2GetEntity(%s)\n", name
);
528 if (ctxt
->inSubset
== 0) {
529 ret
= xmlGetPredefinedEntity(name
);
533 if ((ctxt
->myDoc
!= NULL
) && (ctxt
->myDoc
->standalone
== 1)) {
534 if (ctxt
->inSubset
== 2) {
535 ctxt
->myDoc
->standalone
= 0;
536 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
537 ctxt
->myDoc
->standalone
= 1;
539 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
541 ctxt
->myDoc
->standalone
= 0;
542 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
544 xmlFatalErrMsg(ctxt
, XML_ERR_NOT_STANDALONE
,
545 "Entity(%s) document marked standalone but requires external subset\n",
548 ctxt
->myDoc
->standalone
= 1;
552 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
555 ((ctxt
->validate
) || (ctxt
->replaceEntities
)) &&
556 (ret
->children
== NULL
) &&
557 (ret
->etype
== XML_EXTERNAL_GENERAL_PARSED_ENTITY
)) {
561 * for validation purposes we really need to fetch and
562 * parse the external entity
566 val
= xmlParseCtxtExternalEntity(ctxt
, ret
->URI
,
567 ret
->ExternalID
, &children
);
569 xmlAddChildList((xmlNodePtr
) ret
, children
);
571 xmlFatalErrMsg(ctxt
, XML_ERR_ENTITY_PROCESSING
,
572 "Failure to process entity %s\n", name
, NULL
);
582 * xmlSAX2GetParameterEntity:
583 * @ctx: the user data (XML parser context)
584 * @name: The entity name
586 * Get a parameter entity by name
588 * Returns the xmlEntityPtr if found.
591 xmlSAX2GetParameterEntity(void *ctx
, const xmlChar
*name
)
593 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
596 if (ctx
== NULL
) return(NULL
);
598 xmlGenericError(xmlGenericErrorContext
,
599 "SAX.xmlSAX2GetParameterEntity(%s)\n", name
);
602 ret
= xmlGetParameterEntity(ctxt
->myDoc
, name
);
609 * @ctx: the user data (XML parser context)
610 * @name: the entity name
611 * @type: the entity type
612 * @publicId: The public ID of the entity
613 * @systemId: The system ID of the entity
614 * @content: the entity value (without processing).
616 * An entity definition has been parsed
619 xmlSAX2EntityDecl(void *ctx
, const xmlChar
*name
, int type
,
620 const xmlChar
*publicId
, const xmlChar
*systemId
, xmlChar
*content
)
623 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
625 if (ctx
== NULL
) return;
627 xmlGenericError(xmlGenericErrorContext
,
628 "SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n",
629 name
, type
, publicId
, systemId
, content
);
631 if (ctxt
->inSubset
== 1) {
632 ent
= xmlAddDocEntity(ctxt
->myDoc
, name
, type
, publicId
,
634 if ((ent
== NULL
) && (ctxt
->pedantic
))
635 xmlWarnMsg(ctxt
, XML_WAR_ENTITY_REDEFINED
,
636 "Entity(%s) already defined in the internal subset\n",
638 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
640 const char *base
= NULL
;
642 if (ctxt
->input
!= NULL
)
643 base
= ctxt
->input
->filename
;
645 base
= ctxt
->directory
;
647 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
650 } else if (ctxt
->inSubset
== 2) {
651 ent
= xmlAddDtdEntity(ctxt
->myDoc
, name
, type
, publicId
,
653 if ((ent
== NULL
) && (ctxt
->pedantic
) &&
654 (ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
655 ctxt
->sax
->warning(ctxt
->userData
,
656 "Entity(%s) already defined in the external subset\n", name
);
657 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
659 const char *base
= NULL
;
661 if (ctxt
->input
!= NULL
)
662 base
= ctxt
->input
->filename
;
664 base
= ctxt
->directory
;
666 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
670 xmlFatalErrMsg(ctxt
, XML_ERR_ENTITY_PROCESSING
,
671 "SAX.xmlSAX2EntityDecl(%s) called while not in subset\n",
677 * xmlSAX2AttributeDecl:
678 * @ctx: the user data (XML parser context)
679 * @elem: the name of the element
680 * @fullname: the attribute name
681 * @type: the attribute type
682 * @def: the type of default value
683 * @defaultValue: the attribute default value
684 * @tree: the tree of enumerated value set
686 * An attribute definition has been parsed
689 xmlSAX2AttributeDecl(void *ctx
, const xmlChar
*elem
, const xmlChar
*fullname
,
690 int type
, int def
, const xmlChar
*defaultValue
,
691 xmlEnumerationPtr tree
)
693 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
694 xmlAttributePtr attr
;
695 xmlChar
*name
= NULL
, *prefix
= NULL
;
697 if (ctx
== NULL
) return;
699 xmlGenericError(xmlGenericErrorContext
,
700 "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n",
701 elem
, fullname
, type
, def
, defaultValue
);
703 if ((xmlStrEqual(fullname
, BAD_CAST
"xml:id")) &&
704 (type
!= XML_ATTRIBUTE_ID
)) {
706 * Raise the error but keep the validity flag
708 int tmp
= ctxt
->valid
;
709 xmlErrValid(ctxt
, XML_DTD_XMLID_TYPE
,
710 "xml:id : attribute type should be ID\n", NULL
, NULL
);
713 /* TODO: optimize name/prefix allocation */
714 name
= xmlSplitQName(ctxt
, fullname
, &prefix
);
715 ctxt
->vctxt
.valid
= 1;
716 if (ctxt
->inSubset
== 1)
717 attr
= xmlAddAttributeDecl(&ctxt
->vctxt
, ctxt
->myDoc
->intSubset
, elem
,
718 name
, prefix
, (xmlAttributeType
) type
,
719 (xmlAttributeDefault
) def
, defaultValue
, tree
);
720 else if (ctxt
->inSubset
== 2)
721 attr
= xmlAddAttributeDecl(&ctxt
->vctxt
, ctxt
->myDoc
->extSubset
, elem
,
722 name
, prefix
, (xmlAttributeType
) type
,
723 (xmlAttributeDefault
) def
, defaultValue
, tree
);
725 xmlFatalErrMsg(ctxt
, XML_ERR_INTERNAL_ERROR
,
726 "SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n",
728 xmlFreeEnumeration(tree
);
731 #ifdef LIBXML_VALID_ENABLED
732 if (ctxt
->vctxt
.valid
== 0)
734 if ((attr
!= NULL
) && (ctxt
->validate
) && (ctxt
->wellFormed
) &&
735 (ctxt
->myDoc
!= NULL
) && (ctxt
->myDoc
->intSubset
!= NULL
))
736 ctxt
->valid
&= xmlValidateAttributeDecl(&ctxt
->vctxt
, ctxt
->myDoc
,
738 #endif /* LIBXML_VALID_ENABLED */
746 * xmlSAX2ElementDecl:
747 * @ctx: the user data (XML parser context)
748 * @name: the element name
749 * @type: the element type
750 * @content: the element value tree
752 * An element definition has been parsed
755 xmlSAX2ElementDecl(void *ctx
, const xmlChar
* name
, int type
,
756 xmlElementContentPtr content
)
758 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
759 xmlElementPtr elem
= NULL
;
761 if (ctx
== NULL
) return;
763 xmlGenericError(xmlGenericErrorContext
,
764 "SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name
, type
);
767 if (ctxt
->inSubset
== 1)
768 elem
= xmlAddElementDecl(&ctxt
->vctxt
, ctxt
->myDoc
->intSubset
,
769 name
, (xmlElementTypeVal
) type
, content
);
770 else if (ctxt
->inSubset
== 2)
771 elem
= xmlAddElementDecl(&ctxt
->vctxt
, ctxt
->myDoc
->extSubset
,
772 name
, (xmlElementTypeVal
) type
, content
);
774 xmlFatalErrMsg(ctxt
, XML_ERR_INTERNAL_ERROR
,
775 "SAX.xmlSAX2ElementDecl(%s) called while not in subset\n",
779 #ifdef LIBXML_VALID_ENABLED
782 if (ctxt
->validate
&& ctxt
->wellFormed
&&
783 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
785 xmlValidateElementDecl(&ctxt
->vctxt
, ctxt
->myDoc
, elem
);
786 #endif /* LIBXML_VALID_ENABLED */
790 * xmlSAX2NotationDecl:
791 * @ctx: the user data (XML parser context)
792 * @name: The name of the notation
793 * @publicId: The public ID of the entity
794 * @systemId: The system ID of the entity
796 * What to do when a notation declaration has been parsed.
799 xmlSAX2NotationDecl(void *ctx
, const xmlChar
*name
,
800 const xmlChar
*publicId
, const xmlChar
*systemId
)
802 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
803 xmlNotationPtr nota
= NULL
;
805 if (ctx
== NULL
) return;
807 xmlGenericError(xmlGenericErrorContext
,
808 "SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name
, publicId
, systemId
);
811 if ((publicId
== NULL
) && (systemId
== NULL
)) {
812 xmlFatalErrMsg(ctxt
, XML_ERR_NOTATION_PROCESSING
,
813 "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n",
816 } else if (ctxt
->inSubset
== 1)
817 nota
= xmlAddNotationDecl(&ctxt
->vctxt
, ctxt
->myDoc
->intSubset
, name
,
819 else if (ctxt
->inSubset
== 2)
820 nota
= xmlAddNotationDecl(&ctxt
->vctxt
, ctxt
->myDoc
->extSubset
, name
,
823 xmlFatalErrMsg(ctxt
, XML_ERR_NOTATION_PROCESSING
,
824 "SAX.xmlSAX2NotationDecl(%s) called while not in subset\n",
828 #ifdef LIBXML_VALID_ENABLED
829 if (nota
== NULL
) ctxt
->valid
= 0;
830 if (ctxt
->validate
&& ctxt
->wellFormed
&&
831 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
832 ctxt
->valid
&= xmlValidateNotationDecl(&ctxt
->vctxt
, ctxt
->myDoc
,
834 #endif /* LIBXML_VALID_ENABLED */
838 * xmlSAX2UnparsedEntityDecl:
839 * @ctx: the user data (XML parser context)
840 * @name: The name of the entity
841 * @publicId: The public ID of the entity
842 * @systemId: The system ID of the entity
843 * @notationName: the name of the notation
845 * What to do when an unparsed entity declaration is parsed
848 xmlSAX2UnparsedEntityDecl(void *ctx
, const xmlChar
*name
,
849 const xmlChar
*publicId
, const xmlChar
*systemId
,
850 const xmlChar
*notationName
)
853 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
854 if (ctx
== NULL
) return;
856 xmlGenericError(xmlGenericErrorContext
,
857 "SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n",
858 name
, publicId
, systemId
, notationName
);
860 if (ctxt
->inSubset
== 1) {
861 ent
= xmlAddDocEntity(ctxt
->myDoc
, name
,
862 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY
,
863 publicId
, systemId
, notationName
);
864 if ((ent
== NULL
) && (ctxt
->pedantic
) &&
865 (ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
866 ctxt
->sax
->warning(ctxt
->userData
,
867 "Entity(%s) already defined in the internal subset\n", name
);
868 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
870 const char *base
= NULL
;
872 if (ctxt
->input
!= NULL
)
873 base
= ctxt
->input
->filename
;
875 base
= ctxt
->directory
;
877 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
880 } else if (ctxt
->inSubset
== 2) {
881 ent
= xmlAddDtdEntity(ctxt
->myDoc
, name
,
882 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY
,
883 publicId
, systemId
, notationName
);
884 if ((ent
== NULL
) && (ctxt
->pedantic
) &&
885 (ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
886 ctxt
->sax
->warning(ctxt
->userData
,
887 "Entity(%s) already defined in the external subset\n", name
);
888 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
890 const char *base
= NULL
;
892 if (ctxt
->input
!= NULL
)
893 base
= ctxt
->input
->filename
;
895 base
= ctxt
->directory
;
897 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
901 xmlFatalErrMsg(ctxt
, XML_ERR_INTERNAL_ERROR
,
902 "SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n",
908 * xmlSAX2SetDocumentLocator:
909 * @ctx: the user data (XML parser context)
910 * @loc: A SAX Locator
912 * Receive the document locator at startup, actually xmlDefaultSAXLocator
913 * Everything is available on the context, so this is useless in our case.
916 xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED
, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED
)
918 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
920 xmlGenericError(xmlGenericErrorContext
,
921 "SAX.xmlSAX2SetDocumentLocator()\n");
926 * xmlSAX2StartDocument:
927 * @ctx: the user data (XML parser context)
929 * called when the document start being processed.
932 xmlSAX2StartDocument(void *ctx
)
934 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
937 if (ctx
== NULL
) return;
940 xmlGenericError(xmlGenericErrorContext
,
941 "SAX.xmlSAX2StartDocument()\n");
944 #ifdef LIBXML_HTML_ENABLED
945 if (ctxt
->myDoc
== NULL
)
946 ctxt
->myDoc
= htmlNewDocNoDtD(NULL
, NULL
);
947 if (ctxt
->myDoc
== NULL
) {
948 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartDocument");
952 xmlGenericError(xmlGenericErrorContext
,
953 "libxml2 built without HTML support\n");
954 ctxt
->errNo
= XML_ERR_INTERNAL_ERROR
;
955 ctxt
->instate
= XML_PARSER_EOF
;
956 ctxt
->disableSAX
= 1;
960 doc
= ctxt
->myDoc
= xmlNewDoc(ctxt
->version
);
962 if (ctxt
->encoding
!= NULL
)
963 doc
->encoding
= xmlStrdup(ctxt
->encoding
);
965 doc
->encoding
= NULL
;
966 doc
->standalone
= ctxt
->standalone
;
968 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartDocument");
971 if ((ctxt
->dictNames
) && (doc
!= NULL
)) {
972 doc
->dict
= ctxt
->dict
;
973 xmlDictReference(doc
->dict
);
976 if ((ctxt
->myDoc
!= NULL
) && (ctxt
->myDoc
->URL
== NULL
) &&
977 (ctxt
->input
!= NULL
) && (ctxt
->input
->filename
!= NULL
)) {
978 ctxt
->myDoc
->URL
= xmlCanonicPath((const xmlChar
*) ctxt
->input
->filename
);
979 if (ctxt
->myDoc
->URL
== NULL
)
980 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartDocument");
985 * xmlSAX2EndDocument:
986 * @ctx: the user data (XML parser context)
988 * called when the document end has been detected.
991 xmlSAX2EndDocument(void *ctx
)
993 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
995 xmlGenericError(xmlGenericErrorContext
,
996 "SAX.xmlSAX2EndDocument()\n");
998 if (ctx
== NULL
) return;
999 #ifdef LIBXML_VALID_ENABLED
1000 if (ctxt
->validate
&& ctxt
->wellFormed
&&
1001 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
1002 ctxt
->valid
&= xmlValidateDocumentFinal(&ctxt
->vctxt
, ctxt
->myDoc
);
1003 #endif /* LIBXML_VALID_ENABLED */
1006 * Grab the encoding if it was added on-the-fly
1008 if ((ctxt
->encoding
!= NULL
) && (ctxt
->myDoc
!= NULL
) &&
1009 (ctxt
->myDoc
->encoding
== NULL
)) {
1010 ctxt
->myDoc
->encoding
= ctxt
->encoding
;
1011 ctxt
->encoding
= NULL
;
1013 if ((ctxt
->inputTab
!= NULL
) &&
1014 (ctxt
->inputNr
> 0) && (ctxt
->inputTab
[0] != NULL
) &&
1015 (ctxt
->inputTab
[0]->encoding
!= NULL
) && (ctxt
->myDoc
!= NULL
) &&
1016 (ctxt
->myDoc
->encoding
== NULL
)) {
1017 ctxt
->myDoc
->encoding
= xmlStrdup(ctxt
->inputTab
[0]->encoding
);
1019 if ((ctxt
->charset
!= XML_CHAR_ENCODING_NONE
) && (ctxt
->myDoc
!= NULL
) &&
1020 (ctxt
->myDoc
->charset
== XML_CHAR_ENCODING_NONE
)) {
1021 ctxt
->myDoc
->charset
= ctxt
->charset
;
1025 #if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED)
1027 * xmlSAX2AttributeInternal:
1028 * @ctx: the user data (XML parser context)
1029 * @fullname: The attribute name, including namespace prefix
1030 * @value: The attribute value
1031 * @prefix: the prefix on the element node
1033 * Handle an attribute that has been read by the parser.
1034 * The default handling is to convert the attribute into an
1035 * DOM subtree and past it in a new xmlAttr element added to
1039 xmlSAX2AttributeInternal(void *ctx
, const xmlChar
*fullname
,
1040 const xmlChar
*value
, const xmlChar
*prefix ATTRIBUTE_UNUSED
)
1042 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1050 * Split the full name into a namespace prefix and the tag name
1052 name
= xmlSplitQName(ctxt
, fullname
, &ns
);
1053 if ((name
!= NULL
) && (name
[0] == 0)) {
1054 if (xmlStrEqual(ns
, BAD_CAST
"xmlns")) {
1055 xmlNsErrMsg(ctxt
, XML_ERR_NS_DECL_ERROR
,
1056 "invalid namespace declaration '%s'\n",
1059 xmlNsWarnMsg(ctxt
, XML_WAR_NS_COLUMN
,
1060 "Avoid attribute ending with ':' like '%s'\n",
1067 name
= xmlStrdup(fullname
);
1070 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1076 #ifdef LIBXML_VALID_ENABLED
1078 * Do the last stage of the attribute normalization
1079 * Needed for HTML too:
1080 * http://www.w3.org/TR/html4/types.html#h-6.2
1082 ctxt
->vctxt
.valid
= 1;
1083 nval
= xmlValidCtxtNormalizeAttributeValue(&ctxt
->vctxt
,
1084 ctxt
->myDoc
, ctxt
->node
,
1086 if (ctxt
->vctxt
.valid
!= 1) {
1093 #endif /* LIBXML_VALID_ENABLED */
1096 * Check whether it's a namespace definition
1098 if ((!ctxt
->html
) && (ns
== NULL
) &&
1099 (name
[0] == 'x') && (name
[1] == 'm') && (name
[2] == 'l') &&
1100 (name
[3] == 'n') && (name
[4] == 's') && (name
[5] == 0)) {
1104 if (!ctxt
->replaceEntities
) {
1106 val
= xmlStringDecodeEntities(ctxt
, value
, XML_SUBSTITUTE_REF
,
1110 val
= (xmlChar
*) value
;
1116 uri
= xmlParseURI((const char *)val
);
1118 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
1119 ctxt
->sax
->warning(ctxt
->userData
,
1120 "xmlns: %s not a valid URI\n", val
);
1122 if (uri
->scheme
== NULL
) {
1123 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
1124 ctxt
->sax
->warning(ctxt
->userData
,
1125 "xmlns: URI %s is not absolute\n", val
);
1131 /* a default namespace definition */
1132 nsret
= xmlNewNs(ctxt
->node
, val
, NULL
);
1134 #ifdef LIBXML_VALID_ENABLED
1136 * Validate also for namespace decls, they are attributes from
1137 * an XML-1.0 perspective
1139 if (nsret
!= NULL
&& ctxt
->validate
&& ctxt
->wellFormed
&&
1140 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
1141 ctxt
->valid
&= xmlValidateOneNamespace(&ctxt
->vctxt
, ctxt
->myDoc
,
1142 ctxt
->node
, prefix
, nsret
, val
);
1143 #endif /* LIBXML_VALID_ENABLED */
1152 if ((!ctxt
->html
) &&
1153 (ns
!= NULL
) && (ns
[0] == 'x') && (ns
[1] == 'm') && (ns
[2] == 'l') &&
1154 (ns
[3] == 'n') && (ns
[4] == 's') && (ns
[5] == 0)) {
1158 if (!ctxt
->replaceEntities
) {
1160 val
= xmlStringDecodeEntities(ctxt
, value
, XML_SUBSTITUTE_REF
,
1164 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1171 val
= (xmlChar
*) value
;
1175 xmlNsErrMsg(ctxt
, XML_NS_ERR_EMPTY
,
1176 "Empty namespace name for prefix %s\n", name
, NULL
);
1178 if ((ctxt
->pedantic
!= 0) && (val
[0] != 0)) {
1181 uri
= xmlParseURI((const char *)val
);
1183 xmlNsWarnMsg(ctxt
, XML_WAR_NS_URI
,
1184 "xmlns:%s: %s not a valid URI\n", name
, value
);
1186 if (uri
->scheme
== NULL
) {
1187 xmlNsWarnMsg(ctxt
, XML_WAR_NS_URI_RELATIVE
,
1188 "xmlns:%s: URI %s is not absolute\n", name
, value
);
1194 /* a standard namespace definition */
1195 nsret
= xmlNewNs(ctxt
->node
, val
, name
);
1197 #ifdef LIBXML_VALID_ENABLED
1199 * Validate also for namespace decls, they are attributes from
1200 * an XML-1.0 perspective
1202 if (nsret
!= NULL
&& ctxt
->validate
&& ctxt
->wellFormed
&&
1203 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
1204 ctxt
->valid
&= xmlValidateOneNamespace(&ctxt
->vctxt
, ctxt
->myDoc
,
1205 ctxt
->node
, prefix
, nsret
, value
);
1206 #endif /* LIBXML_VALID_ENABLED */
1218 namespace = xmlSearchNs(ctxt
->myDoc
, ctxt
->node
, ns
);
1219 if (namespace == NULL
) {
1220 xmlNsErrMsg(ctxt
, XML_NS_ERR_UNDEFINED_NAMESPACE
,
1221 "Namespace prefix %s of attribute %s is not defined\n",
1225 prop
= ctxt
->node
->properties
;
1226 while (prop
!= NULL
) {
1227 if (prop
->ns
!= NULL
) {
1228 if ((xmlStrEqual(name
, prop
->name
)) &&
1229 ((namespace == prop
->ns
) ||
1230 (xmlStrEqual(namespace->href
, prop
->ns
->href
)))) {
1231 xmlNsErrMsg(ctxt
, XML_ERR_ATTRIBUTE_REDEFINED
,
1232 "Attribute %s in %s redefined\n",
1233 name
, namespace->href
);
1234 ctxt
->wellFormed
= 0;
1235 if (ctxt
->recovery
== 0) ctxt
->disableSAX
= 1;
1245 /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
1246 ret
= xmlNewNsPropEatName(ctxt
->node
, namespace, name
, NULL
);
1249 if ((ctxt
->replaceEntities
== 0) && (!ctxt
->html
)) {
1252 ret
->children
= xmlStringGetNodeList(ctxt
->myDoc
, value
);
1253 tmp
= ret
->children
;
1254 while (tmp
!= NULL
) {
1255 tmp
->parent
= (xmlNodePtr
) ret
;
1256 if (tmp
->next
== NULL
)
1260 } else if (value
!= NULL
) {
1261 ret
->children
= xmlNewDocText(ctxt
->myDoc
, value
);
1262 ret
->last
= ret
->children
;
1263 if (ret
->children
!= NULL
)
1264 ret
->children
->parent
= (xmlNodePtr
) ret
;
1268 #ifdef LIBXML_VALID_ENABLED
1269 if ((!ctxt
->html
) && ctxt
->validate
&& ctxt
->wellFormed
&&
1270 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
) {
1273 * If we don't substitute entities, the validation should be
1274 * done on a value with replaced entities anyway.
1276 if (!ctxt
->replaceEntities
) {
1280 val
= xmlStringDecodeEntities(ctxt
, value
, XML_SUBSTITUTE_REF
,
1285 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
1286 ctxt
->myDoc
, ctxt
->node
, ret
, value
);
1291 * Do the last stage of the attribute normalization
1292 * It need to be done twice ... it's an extra burden related
1293 * to the ability to keep xmlSAX2References in attributes
1295 nvalnorm
= xmlValidNormalizeAttributeValue(ctxt
->myDoc
,
1296 ctxt
->node
, fullname
, val
);
1297 if (nvalnorm
!= NULL
) {
1302 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
1303 ctxt
->myDoc
, ctxt
->node
, ret
, val
);
1307 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
, ctxt
->myDoc
,
1308 ctxt
->node
, ret
, value
);
1311 #endif /* LIBXML_VALID_ENABLED */
1312 if (((ctxt
->loadsubset
& XML_SKIP_IDS
) == 0) &&
1313 (((ctxt
->replaceEntities
== 0) && (ctxt
->external
!= 2)) ||
1314 ((ctxt
->replaceEntities
!= 0) && (ctxt
->inSubset
== 0)))) {
1316 * when validating, the ID registration is done at the attribute
1317 * validation level. Otherwise we have to do specific handling here.
1319 if (xmlIsID(ctxt
->myDoc
, ctxt
->node
, ret
))
1320 xmlAddID(&ctxt
->vctxt
, ctxt
->myDoc
, value
, ret
);
1321 else if (xmlIsRef(ctxt
->myDoc
, ctxt
->node
, ret
))
1322 xmlAddRef(&ctxt
->vctxt
, ctxt
->myDoc
, value
, ret
);
1323 else if (xmlStrEqual(fullname
, BAD_CAST
"xml:id")) {
1325 * Add the xml:id value
1327 * Open issue: normalization of the value.
1329 if (xmlValidateNCName(value
, 1) != 0) {
1330 xmlErrValid(ctxt
, XML_DTD_XMLID_VALUE
,
1331 "xml:id : attribute value %s is not an NCName\n",
1332 (const char *) value
, NULL
);
1334 xmlAddID(&ctxt
->vctxt
, ctxt
->myDoc
, value
, ret
);
1346 * xmlCheckDefaultedAttributes:
1348 * Check defaulted attributes from the DTD
1351 xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt
, const xmlChar
*name
,
1352 const xmlChar
*prefix
, const xmlChar
**atts
) {
1353 xmlElementPtr elemDecl
;
1358 elemDecl
= xmlGetDtdQElementDesc(ctxt
->myDoc
->intSubset
, name
, prefix
);
1359 if (elemDecl
== NULL
) {
1360 elemDecl
= xmlGetDtdQElementDesc(ctxt
->myDoc
->extSubset
, name
, prefix
);
1364 process_external_subset
:
1366 if (elemDecl
!= NULL
) {
1367 xmlAttributePtr attr
= elemDecl
->attributes
;
1369 * Check against defaulted attributes from the external subset
1370 * if the document is stamped as standalone
1372 if ((ctxt
->myDoc
->standalone
== 1) &&
1373 (ctxt
->myDoc
->extSubset
!= NULL
) &&
1375 while (attr
!= NULL
) {
1376 if ((attr
->defaultValue
!= NULL
) &&
1377 (xmlGetDtdQAttrDesc(ctxt
->myDoc
->extSubset
,
1378 attr
->elem
, attr
->name
,
1379 attr
->prefix
) == attr
) &&
1380 (xmlGetDtdQAttrDesc(ctxt
->myDoc
->intSubset
,
1381 attr
->elem
, attr
->name
,
1382 attr
->prefix
) == NULL
)) {
1385 if (attr
->prefix
!= NULL
) {
1386 fulln
= xmlStrdup(attr
->prefix
);
1387 fulln
= xmlStrcat(fulln
, BAD_CAST
":");
1388 fulln
= xmlStrcat(fulln
, attr
->name
);
1390 fulln
= xmlStrdup(attr
->name
);
1394 * Check that the attribute is not declared in the
1401 while (att
!= NULL
) {
1402 if (xmlStrEqual(att
, fulln
))
1409 xmlErrValid(ctxt
, XML_DTD_STANDALONE_DEFAULTED
,
1410 "standalone: attribute %s on %s defaulted from external subset\n",
1411 (const char *)fulln
,
1412 (const char *)attr
->elem
);
1420 * Actually insert defaulted values when needed
1422 attr
= elemDecl
->attributes
;
1423 while (attr
!= NULL
) {
1425 * Make sure that attributes redefinition occuring in the
1426 * internal subset are not overriden by definitions in the
1429 if (attr
->defaultValue
!= NULL
) {
1431 * the element should be instantiated in the tree if:
1432 * - this is a namespace prefix
1433 * - the user required for completion in the tree
1435 * - there isn't already an attribute definition
1436 * in the internal subset overriding it.
1438 if (((attr
->prefix
!= NULL
) &&
1439 (xmlStrEqual(attr
->prefix
, BAD_CAST
"xmlns"))) ||
1440 ((attr
->prefix
== NULL
) &&
1441 (xmlStrEqual(attr
->name
, BAD_CAST
"xmlns"))) ||
1442 (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)) {
1443 xmlAttributePtr tst
;
1445 tst
= xmlGetDtdQAttrDesc(ctxt
->myDoc
->intSubset
,
1446 attr
->elem
, attr
->name
,
1448 if ((tst
== attr
) || (tst
== NULL
)) {
1452 fulln
= xmlBuildQName(attr
->name
, attr
->prefix
, fn
, 50);
1453 if (fulln
== NULL
) {
1454 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1459 * Check that the attribute is not declared in the
1466 while (att
!= NULL
) {
1467 if (xmlStrEqual(att
, fulln
))
1474 xmlSAX2AttributeInternal(ctxt
, fulln
,
1475 attr
->defaultValue
, prefix
);
1477 if ((fulln
!= fn
) && (fulln
!= attr
->name
))
1484 if (internal
== 1) {
1485 elemDecl
= xmlGetDtdQElementDesc(ctxt
->myDoc
->extSubset
,
1488 goto process_external_subset
;
1494 * xmlSAX2StartElement:
1495 * @ctx: the user data (XML parser context)
1496 * @fullname: The element name, including namespace prefix
1497 * @atts: An array of name/value attributes pairs, NULL terminated
1499 * called when an opening tag has been processed.
1502 xmlSAX2StartElement(void *ctx
, const xmlChar
*fullname
, const xmlChar
**atts
)
1504 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1511 const xmlChar
*value
;
1514 if ((ctx
== NULL
) || (fullname
== NULL
) || (ctxt
->myDoc
== NULL
)) return;
1515 parent
= ctxt
->node
;
1517 xmlGenericError(xmlGenericErrorContext
,
1518 "SAX.xmlSAX2StartElement(%s)\n", fullname
);
1522 * First check on validity:
1524 if (ctxt
->validate
&& (ctxt
->myDoc
->extSubset
== NULL
) &&
1525 ((ctxt
->myDoc
->intSubset
== NULL
) ||
1526 ((ctxt
->myDoc
->intSubset
->notations
== NULL
) &&
1527 (ctxt
->myDoc
->intSubset
->elements
== NULL
) &&
1528 (ctxt
->myDoc
->intSubset
->attributes
== NULL
) &&
1529 (ctxt
->myDoc
->intSubset
->entities
== NULL
)))) {
1530 xmlErrValid(ctxt
, XML_ERR_NO_DTD
,
1531 "Validation failed: no DTD found !", NULL
, NULL
);
1537 * Split the full name into a namespace prefix and the tag name
1539 name
= xmlSplitQName(ctxt
, fullname
, &prefix
);
1543 * Note : the namespace resolution is deferred until the end of the
1544 * attributes parsing, since local namespace can be defined as
1545 * an attribute at this level.
1547 ret
= xmlNewDocNodeEatName(ctxt
->myDoc
, NULL
, name
, NULL
);
1551 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElement");
1554 if (ctxt
->myDoc
->children
== NULL
) {
1555 #ifdef DEBUG_SAX_TREE
1556 xmlGenericError(xmlGenericErrorContext
, "Setting %s as root\n", name
);
1558 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
1559 } else if (parent
== NULL
) {
1560 parent
= ctxt
->myDoc
->children
;
1563 if (ctxt
->linenumbers
) {
1564 if (ctxt
->input
!= NULL
) {
1565 if (ctxt
->input
->line
< 65535)
1566 ret
->line
= (short) ctxt
->input
->line
;
1573 * We are parsing a new node.
1575 #ifdef DEBUG_SAX_TREE
1576 xmlGenericError(xmlGenericErrorContext
, "pushing(%s)\n", name
);
1578 nodePush(ctxt
, ret
);
1581 * Link the child element
1583 if (parent
!= NULL
) {
1584 if (parent
->type
== XML_ELEMENT_NODE
) {
1585 #ifdef DEBUG_SAX_TREE
1586 xmlGenericError(xmlGenericErrorContext
,
1587 "adding child %s to %s\n", name
, parent
->name
);
1589 xmlAddChild(parent
, ret
);
1591 #ifdef DEBUG_SAX_TREE
1592 xmlGenericError(xmlGenericErrorContext
,
1593 "adding sibling %s to ", name
);
1594 xmlDebugDumpOneNode(stderr
, parent
, 0);
1596 xmlAddSibling(parent
, ret
);
1601 * Insert all the defaulted attributes from the DTD especially namespaces
1603 if ((!ctxt
->html
) &&
1604 ((ctxt
->myDoc
->intSubset
!= NULL
) ||
1605 (ctxt
->myDoc
->extSubset
!= NULL
))) {
1606 xmlCheckDefaultedAttributes(ctxt
, name
, prefix
, atts
);
1610 * process all the attributes whose name start with "xmlns"
1617 while ((att
!= NULL
) && (value
!= NULL
)) {
1618 if ((att
[0] == 'x') && (att
[1] == 'm') && (att
[2] == 'l') &&
1619 (att
[3] == 'n') && (att
[4] == 's'))
1620 xmlSAX2AttributeInternal(ctxt
, att
, value
, prefix
);
1629 * Search the namespace, note that since the attributes have been
1630 * processed, the local namespaces are available.
1632 ns
= xmlSearchNs(ctxt
->myDoc
, ret
, prefix
);
1633 if ((ns
== NULL
) && (parent
!= NULL
))
1634 ns
= xmlSearchNs(ctxt
->myDoc
, parent
, prefix
);
1635 if ((prefix
!= NULL
) && (ns
== NULL
)) {
1636 ns
= xmlNewNs(ret
, NULL
, prefix
);
1637 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
1638 ctxt
->sax
->warning(ctxt
->userData
,
1639 "Namespace prefix %s is not defined\n", prefix
);
1643 * set the namespace node, making sure that if the default namspace
1644 * is unbound on a parent we simply kee it NULL
1646 if ((ns
!= NULL
) && (ns
->href
!= NULL
) &&
1647 ((ns
->href
[0] != 0) || (ns
->prefix
!= NULL
)))
1651 * process all the other attributes
1658 while (att
!= NULL
) {
1659 xmlSAX2AttributeInternal(ctxt
, att
, value
, NULL
);
1664 while ((att
!= NULL
) && (value
!= NULL
)) {
1665 if ((att
[0] != 'x') || (att
[1] != 'm') || (att
[2] != 'l') ||
1666 (att
[3] != 'n') || (att
[4] != 's'))
1667 xmlSAX2AttributeInternal(ctxt
, att
, value
, NULL
);
1678 #ifdef LIBXML_VALID_ENABLED
1680 * If it's the Document root, finish the DTD validation and
1681 * check the document root element for validity
1683 if ((ctxt
->validate
) && (ctxt
->vctxt
.finishDtd
== XML_CTXT_FINISH_DTD_0
)) {
1686 chk
= xmlValidateDtdFinal(&ctxt
->vctxt
, ctxt
->myDoc
);
1690 ctxt
->wellFormed
= 0;
1691 ctxt
->valid
&= xmlValidateRoot(&ctxt
->vctxt
, ctxt
->myDoc
);
1692 ctxt
->vctxt
.finishDtd
= XML_CTXT_FINISH_DTD_1
;
1694 #endif /* LIBXML_VALID_ENABLED */
1702 * xmlSAX2EndElement:
1703 * @ctx: the user data (XML parser context)
1704 * @name: The element name
1706 * called when the end of an element has been detected.
1709 xmlSAX2EndElement(void *ctx
, const xmlChar
*name ATTRIBUTE_UNUSED
)
1711 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1712 xmlParserNodeInfo node_info
;
1715 if (ctx
== NULL
) return;
1719 xmlGenericError(xmlGenericErrorContext
, "SAX.xmlSAX2EndElement(NULL)\n");
1721 xmlGenericError(xmlGenericErrorContext
, "SAX.xmlSAX2EndElement(%s)\n", name
);
1724 /* Capture end position and add node */
1725 if (cur
!= NULL
&& ctxt
->record_info
) {
1726 node_info
.end_pos
= ctxt
->input
->cur
- ctxt
->input
->base
;
1727 node_info
.end_line
= ctxt
->input
->line
;
1728 node_info
.node
= cur
;
1729 xmlParserAddNodeInfo(ctxt
, &node_info
);
1733 #ifdef LIBXML_VALID_ENABLED
1734 if (ctxt
->validate
&& ctxt
->wellFormed
&&
1735 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
1736 ctxt
->valid
&= xmlValidateOneElement(&ctxt
->vctxt
, ctxt
->myDoc
,
1738 #endif /* LIBXML_VALID_ENABLED */
1742 * end of parsing of this node.
1744 #ifdef DEBUG_SAX_TREE
1745 xmlGenericError(xmlGenericErrorContext
, "popping(%s)\n", cur
->name
);
1749 #endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLE */
1753 * @ctxt: the parser context
1754 * @str: the input string
1755 * @len: the string length
1757 * Remove the entities from an attribute value
1759 * Returns the newly allocated string or NULL if not needed or error
1762 xmlSAX2TextNode(xmlParserCtxtPtr ctxt
, const xmlChar
*str
, int len
) {
1764 const xmlChar
*intern
= NULL
;
1769 if (ctxt
->freeElems
!= NULL
) {
1770 ret
= ctxt
->freeElems
;
1771 ctxt
->freeElems
= ret
->next
;
1772 ctxt
->freeElemsNr
--;
1774 ret
= (xmlNodePtr
) xmlMalloc(sizeof(xmlNode
));
1777 xmlErrMemory(ctxt
, "xmlSAX2Characters");
1781 * intern the formatting blanks found between tags, or the
1782 * very short strings
1784 if (ctxt
->dictNames
) {
1785 xmlChar cur
= str
[len
];
1787 if ((len
<= 3) && ((cur
== '"') || (cur
== '\'') ||
1788 ((cur
== '<') && (str
[len
+ 1] != '!')))) {
1789 intern
= xmlDictLookup(ctxt
->dict
, str
, len
);
1790 } else if (IS_BLANK_CH(*str
) && (len
< 60) && (cur
== '<') &&
1791 (str
[len
+ 1] != '!')) {
1794 for (i
= 1;i
< len
;i
++) {
1795 if (!IS_BLANK_CH(str
[i
])) goto skip
;
1797 intern
= xmlDictLookup(ctxt
->dict
, str
, len
);
1801 memset(ret
, 0, sizeof(xmlNode
));
1802 ret
->type
= XML_TEXT_NODE
;
1804 ret
->name
= xmlStringText
;
1805 if (intern
== NULL
) {
1806 ret
->content
= xmlStrndup(str
, len
);
1807 if (ret
->content
== NULL
) {
1808 xmlSAX2ErrMemory(ctxt
, "xmlSAX2TextNode");
1813 ret
->content
= (xmlChar
*) intern
;
1815 if ((__xmlRegisterCallbacks
) && (xmlRegisterNodeDefaultValue
))
1816 xmlRegisterNodeDefaultValue(ret
);
1820 #ifdef LIBXML_VALID_ENABLED
1822 * xmlSAX2DecodeAttrEntities:
1823 * @ctxt: the parser context
1824 * @str: the input string
1825 * @len: the string length
1827 * Remove the entities from an attribute value
1829 * Returns the newly allocated string or NULL if not needed or error
1832 xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt
, const xmlChar
*str
,
1833 const xmlChar
*end
) {
1844 ret
= xmlStringLenDecodeEntities(ctxt
, str
, end
- str
,
1845 XML_SUBSTITUTE_REF
, 0,0,0);
1849 #endif /* LIBXML_VALID_ENABLED */
1852 * xmlSAX2AttributeNs:
1853 * @ctx: the user data (XML parser context)
1854 * @localname: the local name of the attribute
1855 * @prefix: the attribute namespace prefix if available
1856 * @URI: the attribute namespace name if available
1857 * @value: Start of the attribute value
1858 * @valueend: end of the attribute value
1860 * Handle an attribute that has been read by the parser.
1861 * The default handling is to convert the attribute into an
1862 * DOM subtree and past it in a new xmlAttr element added to
1866 xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt
,
1867 const xmlChar
* localname
,
1868 const xmlChar
* prefix
,
1869 const xmlChar
* value
,
1870 const xmlChar
* valueend
)
1873 xmlNsPtr
namespace = NULL
;
1874 xmlChar
*dup
= NULL
;
1877 * Note: if prefix == NULL, the attribute is not in the default namespace
1880 namespace = xmlSearchNs(ctxt
->myDoc
, ctxt
->node
, prefix
);
1885 if (ctxt
->freeAttrs
!= NULL
) {
1886 ret
= ctxt
->freeAttrs
;
1887 ctxt
->freeAttrs
= ret
->next
;
1888 ctxt
->freeAttrsNr
--;
1889 memset(ret
, 0, sizeof(xmlAttr
));
1890 ret
->type
= XML_ATTRIBUTE_NODE
;
1892 ret
->parent
= ctxt
->node
;
1893 ret
->doc
= ctxt
->myDoc
;
1894 ret
->ns
= namespace;
1896 if (ctxt
->dictNames
)
1897 ret
->name
= localname
;
1899 ret
->name
= xmlStrdup(localname
);
1901 /* link at the end to preserv order, TODO speed up with a last */
1902 if (ctxt
->node
->properties
== NULL
) {
1903 ctxt
->node
->properties
= ret
;
1905 xmlAttrPtr prev
= ctxt
->node
->properties
;
1907 while (prev
->next
!= NULL
) prev
= prev
->next
;
1912 if ((__xmlRegisterCallbacks
) && (xmlRegisterNodeDefaultValue
))
1913 xmlRegisterNodeDefaultValue((xmlNodePtr
)ret
);
1915 if (ctxt
->dictNames
)
1916 ret
= xmlNewNsPropEatName(ctxt
->node
, namespace,
1917 (xmlChar
*) localname
, NULL
);
1919 ret
= xmlNewNsProp(ctxt
->node
, namespace, localname
, NULL
);
1921 xmlErrMemory(ctxt
, "xmlSAX2AttributeNs");
1926 if ((ctxt
->replaceEntities
== 0) && (!ctxt
->html
)) {
1930 * We know that if there is an entity reference, then
1931 * the string has been dup'ed and terminates with 0
1932 * otherwise with ' or "
1934 if (*valueend
!= 0) {
1935 tmp
= xmlSAX2TextNode(ctxt
, value
, valueend
- value
);
1936 ret
->children
= tmp
;
1939 tmp
->doc
= ret
->doc
;
1940 tmp
->parent
= (xmlNodePtr
) ret
;
1943 ret
->children
= xmlStringLenGetNodeList(ctxt
->myDoc
, value
,
1945 tmp
= ret
->children
;
1946 while (tmp
!= NULL
) {
1947 tmp
->doc
= ret
->doc
;
1948 tmp
->parent
= (xmlNodePtr
) ret
;
1949 if (tmp
->next
== NULL
)
1954 } else if (value
!= NULL
) {
1957 tmp
= xmlSAX2TextNode(ctxt
, value
, valueend
- value
);
1958 ret
->children
= tmp
;
1961 tmp
->doc
= ret
->doc
;
1962 tmp
->parent
= (xmlNodePtr
) ret
;
1966 #ifdef LIBXML_VALID_ENABLED
1967 if ((!ctxt
->html
) && ctxt
->validate
&& ctxt
->wellFormed
&&
1968 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
) {
1970 * If we don't substitute entities, the validation should be
1971 * done on a value with replaced entities anyway.
1973 if (!ctxt
->replaceEntities
) {
1974 dup
= xmlSAX2DecodeAttrEntities(ctxt
, value
, valueend
);
1976 if (*valueend
== 0) {
1977 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
1978 ctxt
->myDoc
, ctxt
->node
, ret
, value
);
1981 * That should already be normalized.
1982 * cheaper to finally allocate here than duplicate
1983 * entry points in the full validation code
1985 dup
= xmlStrndup(value
, valueend
- value
);
1987 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
1988 ctxt
->myDoc
, ctxt
->node
, ret
, dup
);
1992 * dup now contains a string of the flattened attribute
1993 * content with entities substitued. Check if we need to
1994 * apply an extra layer of normalization.
1995 * It need to be done twice ... it's an extra burden related
1996 * to the ability to keep references in attributes
1998 if (ctxt
->attsSpecial
!= NULL
) {
2003 fullname
= xmlBuildQName(localname
, prefix
, fn
, 50);
2004 if (fullname
!= NULL
) {
2005 ctxt
->vctxt
.valid
= 1;
2006 nvalnorm
= xmlValidCtxtNormalizeAttributeValue(
2007 &ctxt
->vctxt
, ctxt
->myDoc
,
2008 ctxt
->node
, fullname
, dup
);
2009 if (ctxt
->vctxt
.valid
!= 1)
2012 if ((fullname
!= fn
) && (fullname
!= localname
))
2014 if (nvalnorm
!= NULL
) {
2021 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2022 ctxt
->myDoc
, ctxt
->node
, ret
, dup
);
2026 * if entities already have been substitued, then
2027 * the attribute as passed is already normalized
2029 dup
= xmlStrndup(value
, valueend
- value
);
2031 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
2032 ctxt
->myDoc
, ctxt
->node
, ret
, dup
);
2035 #endif /* LIBXML_VALID_ENABLED */
2036 if (((ctxt
->loadsubset
& XML_SKIP_IDS
) == 0) &&
2037 (((ctxt
->replaceEntities
== 0) && (ctxt
->external
!= 2)) ||
2038 ((ctxt
->replaceEntities
!= 0) && (ctxt
->inSubset
== 0)))) {
2040 * when validating, the ID registration is done at the attribute
2041 * validation level. Otherwise we have to do specific handling here.
2043 if (xmlIsID(ctxt
->myDoc
, ctxt
->node
, ret
)) {
2044 /* might be worth duplicate entry points and not copy */
2046 dup
= xmlStrndup(value
, valueend
- value
);
2047 xmlAddID(&ctxt
->vctxt
, ctxt
->myDoc
, dup
, ret
);
2048 } else if (xmlIsRef(ctxt
->myDoc
, ctxt
->node
, ret
)) {
2050 dup
= xmlStrndup(value
, valueend
- value
);
2051 xmlAddRef(&ctxt
->vctxt
, ctxt
->myDoc
, dup
, ret
);
2052 } else if ((prefix
== ctxt
->str_xml
) &&
2053 (localname
[0] == 'i') && (localname
[1] == 'd') &&
2054 (localname
[2] == 0)) {
2056 * Add the xml:id value
2058 * Open issue: normalization of the value.
2061 dup
= xmlStrndup(value
, valueend
- value
);
2062 #ifdef LIBXML_VALID_ENABLED
2063 if (xmlValidateNCName(dup
, 1) != 0) {
2064 xmlErrValid(ctxt
, XML_DTD_XMLID_VALUE
,
2065 "xml:id : attribute value %s is not an NCName\n",
2066 (const char *) dup
, NULL
);
2069 xmlAddID(&ctxt
->vctxt
, ctxt
->myDoc
, dup
, ret
);
2077 * xmlSAX2StartElementNs:
2078 * @ctx: the user data (XML parser context)
2079 * @localname: the local name of the element
2080 * @prefix: the element namespace prefix if available
2081 * @URI: the element namespace name if available
2082 * @nb_namespaces: number of namespace definitions on that node
2083 * @namespaces: pointer to the array of prefix/URI pairs namespace definitions
2084 * @nb_attributes: the number of attributes on that node
2085 * @nb_defaulted: the number of defaulted attributes.
2086 * @attributes: pointer to the array of (localname/prefix/URI/value/end)
2089 * SAX2 callback when an element start has been detected by the parser.
2090 * It provides the namespace informations for the element, as well as
2091 * the new namespace declarations on the element.
2094 xmlSAX2StartElementNs(void *ctx
,
2095 const xmlChar
*localname
,
2096 const xmlChar
*prefix
,
2099 const xmlChar
**namespaces
,
2102 const xmlChar
**attributes
)
2104 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2107 xmlNsPtr last
= NULL
, ns
;
2108 const xmlChar
*uri
, *pref
;
2111 if (ctx
== NULL
) return;
2112 parent
= ctxt
->node
;
2114 * First check on validity:
2116 if (ctxt
->validate
&& (ctxt
->myDoc
->extSubset
== NULL
) &&
2117 ((ctxt
->myDoc
->intSubset
== NULL
) ||
2118 ((ctxt
->myDoc
->intSubset
->notations
== NULL
) &&
2119 (ctxt
->myDoc
->intSubset
->elements
== NULL
) &&
2120 (ctxt
->myDoc
->intSubset
->attributes
== NULL
) &&
2121 (ctxt
->myDoc
->intSubset
->entities
== NULL
)))) {
2122 xmlErrValid(ctxt
, XML_ERR_NO_DTD
,
2123 "Validation failed: no DTD found !", NULL
, NULL
);
2130 if (ctxt
->freeElems
!= NULL
) {
2131 ret
= ctxt
->freeElems
;
2132 ctxt
->freeElems
= ret
->next
;
2133 ctxt
->freeElemsNr
--;
2134 memset(ret
, 0, sizeof(xmlNode
));
2135 ret
->type
= XML_ELEMENT_NODE
;
2137 if (ctxt
->dictNames
)
2138 ret
->name
= localname
;
2140 ret
->name
= xmlStrdup(localname
);
2141 if (ret
->name
== NULL
) {
2142 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2146 if ((__xmlRegisterCallbacks
) && (xmlRegisterNodeDefaultValue
))
2147 xmlRegisterNodeDefaultValue(ret
);
2149 if (ctxt
->dictNames
)
2150 ret
= xmlNewDocNodeEatName(ctxt
->myDoc
, NULL
,
2151 (xmlChar
*) localname
, NULL
);
2153 ret
= xmlNewDocNode(ctxt
->myDoc
, NULL
, localname
, NULL
);
2155 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2159 if (ctxt
->linenumbers
) {
2160 if (ctxt
->input
!= NULL
) {
2161 if (ctxt
->input
->line
< 65535)
2162 ret
->line
= (short) ctxt
->input
->line
;
2168 if ((ctxt
->myDoc
->children
== NULL
) || (parent
== NULL
)) {
2169 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
2172 * Build the namespace list
2174 for (i
= 0,j
= 0;j
< nb_namespaces
;j
++) {
2175 pref
= namespaces
[i
++];
2176 uri
= namespaces
[i
++];
2177 ns
= xmlNewNs(NULL
, uri
, pref
);
2180 ret
->nsDef
= last
= ns
;
2185 if ((URI
!= NULL
) && (prefix
== pref
))
2188 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2191 #ifdef LIBXML_VALID_ENABLED
2192 if ((!ctxt
->html
) && ctxt
->validate
&& ctxt
->wellFormed
&&
2193 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
) {
2194 ctxt
->valid
&= xmlValidateOneNamespace(&ctxt
->vctxt
, ctxt
->myDoc
,
2195 ret
, prefix
, ns
, uri
);
2197 #endif /* LIBXML_VALID_ENABLED */
2202 * We are parsing a new node.
2204 nodePush(ctxt
, ret
);
2207 * Link the child element
2209 if (parent
!= NULL
) {
2210 if (parent
->type
== XML_ELEMENT_NODE
) {
2211 xmlAddChild(parent
, ret
);
2213 xmlAddSibling(parent
, ret
);
2218 * Insert the defaulted attributes from the DTD only if requested:
2220 if ((nb_defaulted
!= 0) &&
2221 ((ctxt
->loadsubset
& XML_COMPLETE_ATTRS
) == 0))
2222 nb_attributes
-= nb_defaulted
;
2225 * Search the namespace if it wasn't already found
2226 * Note that, if prefix is NULL, this searches for the default Ns
2228 if ((URI
!= NULL
) && (ret
->ns
== NULL
)) {
2229 ret
->ns
= xmlSearchNs(ctxt
->myDoc
, parent
, prefix
);
2230 if (ret
->ns
== NULL
) {
2231 ns
= xmlNewNs(ret
, NULL
, prefix
);
2233 xmlSAX2ErrMemory(ctxt
, "xmlSAX2StartElementNs");
2236 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
2237 ctxt
->sax
->warning(ctxt
->userData
,
2238 "Namespace prefix %s was not found\n", prefix
);
2243 * process all the other attributes
2245 if (nb_attributes
> 0) {
2246 for (j
= 0,i
= 0;i
< nb_attributes
;i
++,j
+=5) {
2247 xmlSAX2AttributeNs(ctxt
, attributes
[j
], attributes
[j
+1],
2248 attributes
[j
+3], attributes
[j
+4]);
2252 #ifdef LIBXML_VALID_ENABLED
2254 * If it's the Document root, finish the DTD validation and
2255 * check the document root element for validity
2257 if ((ctxt
->validate
) && (ctxt
->vctxt
.finishDtd
== XML_CTXT_FINISH_DTD_0
)) {
2260 chk
= xmlValidateDtdFinal(&ctxt
->vctxt
, ctxt
->myDoc
);
2264 ctxt
->wellFormed
= 0;
2265 ctxt
->valid
&= xmlValidateRoot(&ctxt
->vctxt
, ctxt
->myDoc
);
2266 ctxt
->vctxt
.finishDtd
= XML_CTXT_FINISH_DTD_1
;
2268 #endif /* LIBXML_VALID_ENABLED */
2272 * xmlSAX2EndElementNs:
2273 * @ctx: the user data (XML parser context)
2274 * @localname: the local name of the element
2275 * @prefix: the element namespace prefix if available
2276 * @URI: the element namespace name if available
2278 * SAX2 callback when an element end has been detected by the parser.
2279 * It provides the namespace informations for the element.
2282 xmlSAX2EndElementNs(void *ctx
,
2283 const xmlChar
* localname ATTRIBUTE_UNUSED
,
2284 const xmlChar
* prefix ATTRIBUTE_UNUSED
,
2285 const xmlChar
* URI ATTRIBUTE_UNUSED
)
2287 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2288 xmlParserNodeInfo node_info
;
2291 if (ctx
== NULL
) return;
2293 /* Capture end position and add node */
2294 if ((ctxt
->record_info
) && (cur
!= NULL
)) {
2295 node_info
.end_pos
= ctxt
->input
->cur
- ctxt
->input
->base
;
2296 node_info
.end_line
= ctxt
->input
->line
;
2297 node_info
.node
= cur
;
2298 xmlParserAddNodeInfo(ctxt
, &node_info
);
2302 #ifdef LIBXML_VALID_ENABLED
2303 if (ctxt
->validate
&& ctxt
->wellFormed
&&
2304 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
2305 ctxt
->valid
&= xmlValidateOneElement(&ctxt
->vctxt
, ctxt
->myDoc
, cur
);
2306 #endif /* LIBXML_VALID_ENABLED */
2309 * end of parsing of this node.
2316 * @ctx: the user data (XML parser context)
2317 * @name: The entity name
2319 * called when an entity xmlSAX2Reference is detected.
2322 xmlSAX2Reference(void *ctx
, const xmlChar
*name
)
2324 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2327 if (ctx
== NULL
) return;
2329 xmlGenericError(xmlGenericErrorContext
,
2330 "SAX.xmlSAX2Reference(%s)\n", name
);
2333 ret
= xmlNewCharRef(ctxt
->myDoc
, name
);
2335 ret
= xmlNewReference(ctxt
->myDoc
, name
);
2336 #ifdef DEBUG_SAX_TREE
2337 xmlGenericError(xmlGenericErrorContext
,
2338 "add xmlSAX2Reference %s to %s \n", name
, ctxt
->node
->name
);
2340 xmlAddChild(ctxt
->node
, ret
);
2344 * xmlSAX2Characters:
2345 * @ctx: the user data (XML parser context)
2346 * @ch: a xmlChar string
2347 * @len: the number of xmlChar
2349 * receiving some chars from the parser.
2352 xmlSAX2Characters(void *ctx
, const xmlChar
*ch
, int len
)
2354 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2355 xmlNodePtr lastChild
;
2357 if (ctx
== NULL
) return;
2359 xmlGenericError(xmlGenericErrorContext
,
2360 "SAX.xmlSAX2Characters(%.30s, %d)\n", ch
, len
);
2363 * Handle the data if any. If there is no child
2364 * add it as content, otherwise if the last child is text,
2365 * concatenate it, else create a new node of type text.
2368 if (ctxt
->node
== NULL
) {
2369 #ifdef DEBUG_SAX_TREE
2370 xmlGenericError(xmlGenericErrorContext
,
2371 "add chars: ctxt->node == NULL !\n");
2375 lastChild
= ctxt
->node
->last
;
2376 #ifdef DEBUG_SAX_TREE
2377 xmlGenericError(xmlGenericErrorContext
,
2378 "add chars to %s \n", ctxt
->node
->name
);
2382 * Here we needed an accelerator mechanism in case of very large
2383 * elements. Use an attribute in the structure !!!
2385 if (lastChild
== NULL
) {
2386 lastChild
= xmlSAX2TextNode(ctxt
, ch
, len
);
2387 if (lastChild
!= NULL
) {
2388 ctxt
->node
->children
= lastChild
;
2389 ctxt
->node
->last
= lastChild
;
2390 lastChild
->parent
= ctxt
->node
;
2391 lastChild
->doc
= ctxt
->node
->doc
;
2392 ctxt
->nodelen
= len
;
2393 ctxt
->nodemem
= len
+ 1;
2395 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters");
2399 int coalesceText
= (lastChild
!= NULL
) &&
2400 (lastChild
->type
== XML_TEXT_NODE
) &&
2401 (lastChild
->name
== xmlStringText
);
2402 if ((coalesceText
) && (ctxt
->nodemem
!= 0)) {
2404 * The whole point of maintaining nodelen and nodemem,
2405 * xmlTextConcat is too costly, i.e. compute length,
2406 * reallocate a new buffer, move data, append ch. Here
2407 * We try to minimaze realloc() uses and avoid copying
2408 * and recomputing length over and over.
2410 if ((ctxt
->nodemem
== ctxt
->nodelen
+ 1) &&
2411 (xmlDictOwns(ctxt
->dict
, lastChild
->content
))) {
2412 lastChild
->content
= xmlStrdup(lastChild
->content
);
2414 if (ctxt
->nodelen
+ len
>= ctxt
->nodemem
) {
2418 size
= ctxt
->nodemem
+ len
;
2420 newbuf
= (xmlChar
*) xmlRealloc(lastChild
->content
,size
);
2421 if (newbuf
== NULL
) {
2422 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters");
2425 ctxt
->nodemem
= size
;
2426 lastChild
->content
= newbuf
;
2428 memcpy(&lastChild
->content
[ctxt
->nodelen
], ch
, len
);
2429 ctxt
->nodelen
+= len
;
2430 lastChild
->content
[ctxt
->nodelen
] = 0;
2431 } else if (coalesceText
) {
2432 if (xmlTextConcat(lastChild
, ch
, len
)) {
2433 xmlSAX2ErrMemory(ctxt
, "xmlSAX2Characters");
2435 if (ctxt
->node
->children
!= NULL
) {
2436 ctxt
->nodelen
= xmlStrlen(lastChild
->content
);
2437 ctxt
->nodemem
= ctxt
->nodelen
+ 1;
2440 /* Mixed content, first time */
2441 lastChild
= xmlSAX2TextNode(ctxt
, ch
, len
);
2442 if (lastChild
!= NULL
) {
2443 xmlAddChild(ctxt
->node
, lastChild
);
2444 if (ctxt
->node
->children
!= NULL
) {
2445 ctxt
->nodelen
= len
;
2446 ctxt
->nodemem
= len
+ 1;
2454 * xmlSAX2IgnorableWhitespace:
2455 * @ctx: the user data (XML parser context)
2456 * @ch: a xmlChar string
2457 * @len: the number of xmlChar
2459 * receiving some ignorable whitespaces from the parser.
2460 * UNUSED: by default the DOM building will use xmlSAX2Characters
2463 xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED
, const xmlChar
*ch ATTRIBUTE_UNUSED
, int len ATTRIBUTE_UNUSED
)
2465 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
2467 xmlGenericError(xmlGenericErrorContext
,
2468 "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch
, len
);
2473 * xmlSAX2ProcessingInstruction:
2474 * @ctx: the user data (XML parser context)
2475 * @target: the target name
2476 * @data: the PI data's
2478 * A processing instruction has been parsed.
2481 xmlSAX2ProcessingInstruction(void *ctx
, const xmlChar
*target
,
2482 const xmlChar
*data
)
2484 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2488 if (ctx
== NULL
) return;
2489 parent
= ctxt
->node
;
2491 xmlGenericError(xmlGenericErrorContext
,
2492 "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target
, data
);
2495 ret
= xmlNewDocPI(ctxt
->myDoc
, target
, data
);
2496 if (ret
== NULL
) return;
2497 parent
= ctxt
->node
;
2499 if (ctxt
->inSubset
== 1) {
2500 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->intSubset
, ret
);
2502 } else if (ctxt
->inSubset
== 2) {
2503 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->extSubset
, ret
);
2506 if ((ctxt
->myDoc
->children
== NULL
) || (parent
== NULL
)) {
2507 #ifdef DEBUG_SAX_TREE
2508 xmlGenericError(xmlGenericErrorContext
,
2509 "Setting PI %s as root\n", target
);
2511 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
2514 if (parent
->type
== XML_ELEMENT_NODE
) {
2515 #ifdef DEBUG_SAX_TREE
2516 xmlGenericError(xmlGenericErrorContext
,
2517 "adding PI %s child to %s\n", target
, parent
->name
);
2519 xmlAddChild(parent
, ret
);
2521 #ifdef DEBUG_SAX_TREE
2522 xmlGenericError(xmlGenericErrorContext
,
2523 "adding PI %s sibling to ", target
);
2524 xmlDebugDumpOneNode(stderr
, parent
, 0);
2526 xmlAddSibling(parent
, ret
);
2532 * @ctx: the user data (XML parser context)
2533 * @value: the xmlSAX2Comment content
2535 * A xmlSAX2Comment has been parsed.
2538 xmlSAX2Comment(void *ctx
, const xmlChar
*value
)
2540 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2544 if (ctx
== NULL
) return;
2545 parent
= ctxt
->node
;
2547 xmlGenericError(xmlGenericErrorContext
, "SAX.xmlSAX2Comment(%s)\n", value
);
2549 ret
= xmlNewDocComment(ctxt
->myDoc
, value
);
2550 if (ret
== NULL
) return;
2552 if (ctxt
->inSubset
== 1) {
2553 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->intSubset
, ret
);
2555 } else if (ctxt
->inSubset
== 2) {
2556 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->extSubset
, ret
);
2559 if ((ctxt
->myDoc
->children
== NULL
) || (parent
== NULL
)) {
2560 #ifdef DEBUG_SAX_TREE
2561 xmlGenericError(xmlGenericErrorContext
,
2562 "Setting xmlSAX2Comment as root\n");
2564 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
2567 if (parent
->type
== XML_ELEMENT_NODE
) {
2568 #ifdef DEBUG_SAX_TREE
2569 xmlGenericError(xmlGenericErrorContext
,
2570 "adding xmlSAX2Comment child to %s\n", parent
->name
);
2572 xmlAddChild(parent
, ret
);
2574 #ifdef DEBUG_SAX_TREE
2575 xmlGenericError(xmlGenericErrorContext
,
2576 "adding xmlSAX2Comment sibling to ");
2577 xmlDebugDumpOneNode(stderr
, parent
, 0);
2579 xmlAddSibling(parent
, ret
);
2584 * xmlSAX2CDataBlock:
2585 * @ctx: the user data (XML parser context)
2586 * @value: The pcdata content
2587 * @len: the block length
2589 * called when a pcdata block has been parsed
2592 xmlSAX2CDataBlock(void *ctx
, const xmlChar
*value
, int len
)
2594 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
2595 xmlNodePtr ret
, lastChild
;
2597 if (ctx
== NULL
) return;
2599 xmlGenericError(xmlGenericErrorContext
,
2600 "SAX.pcdata(%.10s, %d)\n", value
, len
);
2602 lastChild
= xmlGetLastChild(ctxt
->node
);
2603 #ifdef DEBUG_SAX_TREE
2604 xmlGenericError(xmlGenericErrorContext
,
2605 "add chars to %s \n", ctxt
->node
->name
);
2607 if ((lastChild
!= NULL
) &&
2608 (lastChild
->type
== XML_CDATA_SECTION_NODE
)) {
2609 xmlTextConcat(lastChild
, value
, len
);
2611 ret
= xmlNewCDataBlock(ctxt
->myDoc
, value
, len
);
2612 xmlAddChild(ctxt
->node
, ret
);
2616 static int xmlSAX2DefaultVersionValue
= 2;
2618 #ifdef LIBXML_SAX1_ENABLED
2620 * xmlSAXDefaultVersion:
2621 * @version: the version, 1 or 2
2623 * Set the default version of SAX used globally by the library.
2624 * By default, during initialization the default is set to 2.
2625 * Note that it is generally a better coding style to use
2626 * xmlSAXVersion() to set up the version explicitly for a given
2629 * Returns the previous value in case of success and -1 in case of error.
2632 xmlSAXDefaultVersion(int version
)
2634 int ret
= xmlSAX2DefaultVersionValue
;
2636 if ((version
!= 1) && (version
!= 2))
2638 xmlSAX2DefaultVersionValue
= version
;
2641 #endif /* LIBXML_SAX1_ENABLED */
2645 * @hdlr: the SAX handler
2646 * @version: the version, 1 or 2
2648 * Initialize the default XML SAX handler according to the version
2650 * Returns 0 in case of success and -1 in case of error.
2653 xmlSAXVersion(xmlSAXHandler
*hdlr
, int version
)
2655 if (hdlr
== NULL
) return(-1);
2657 hdlr
->startElement
= NULL
;
2658 hdlr
->endElement
= NULL
;
2659 hdlr
->startElementNs
= xmlSAX2StartElementNs
;
2660 hdlr
->endElementNs
= xmlSAX2EndElementNs
;
2661 hdlr
->serror
= NULL
;
2662 hdlr
->initialized
= XML_SAX2_MAGIC
;
2663 #ifdef LIBXML_SAX1_ENABLED
2664 } else if (version
== 1) {
2665 hdlr
->startElement
= xmlSAX2StartElement
;
2666 hdlr
->endElement
= xmlSAX2EndElement
;
2667 hdlr
->initialized
= 1;
2668 #endif /* LIBXML_SAX1_ENABLED */
2671 hdlr
->internalSubset
= xmlSAX2InternalSubset
;
2672 hdlr
->externalSubset
= xmlSAX2ExternalSubset
;
2673 hdlr
->isStandalone
= xmlSAX2IsStandalone
;
2674 hdlr
->hasInternalSubset
= xmlSAX2HasInternalSubset
;
2675 hdlr
->hasExternalSubset
= xmlSAX2HasExternalSubset
;
2676 hdlr
->resolveEntity
= xmlSAX2ResolveEntity
;
2677 hdlr
->getEntity
= xmlSAX2GetEntity
;
2678 hdlr
->getParameterEntity
= xmlSAX2GetParameterEntity
;
2679 hdlr
->entityDecl
= xmlSAX2EntityDecl
;
2680 hdlr
->attributeDecl
= xmlSAX2AttributeDecl
;
2681 hdlr
->elementDecl
= xmlSAX2ElementDecl
;
2682 hdlr
->notationDecl
= xmlSAX2NotationDecl
;
2683 hdlr
->unparsedEntityDecl
= xmlSAX2UnparsedEntityDecl
;
2684 hdlr
->setDocumentLocator
= xmlSAX2SetDocumentLocator
;
2685 hdlr
->startDocument
= xmlSAX2StartDocument
;
2686 hdlr
->endDocument
= xmlSAX2EndDocument
;
2687 hdlr
->reference
= xmlSAX2Reference
;
2688 hdlr
->characters
= xmlSAX2Characters
;
2689 hdlr
->cdataBlock
= xmlSAX2CDataBlock
;
2690 hdlr
->ignorableWhitespace
= xmlSAX2Characters
;
2691 hdlr
->processingInstruction
= xmlSAX2ProcessingInstruction
;
2692 hdlr
->comment
= xmlSAX2Comment
;
2693 hdlr
->warning
= xmlParserWarning
;
2694 hdlr
->error
= xmlParserError
;
2695 hdlr
->fatalError
= xmlParserError
;
2701 * xmlSAX2InitDefaultSAXHandler:
2702 * @hdlr: the SAX handler
2703 * @warning: flag if non-zero sets the handler warning procedure
2705 * Initialize the default XML SAX2 handler
2708 xmlSAX2InitDefaultSAXHandler(xmlSAXHandler
*hdlr
, int warning
)
2710 if ((hdlr
== NULL
) || (hdlr
->initialized
!= 0))
2713 xmlSAXVersion(hdlr
, xmlSAX2DefaultVersionValue
);
2715 hdlr
->warning
= NULL
;
2717 hdlr
->warning
= xmlParserWarning
;
2721 * xmlDefaultSAXHandlerInit:
2723 * Initialize the default SAX2 handler
2726 xmlDefaultSAXHandlerInit(void)
2728 #ifdef LIBXML_SAX1_ENABLED
2729 xmlSAXVersion((xmlSAXHandlerPtr
) &xmlDefaultSAXHandler
, 1);
2730 #endif /* LIBXML_SAX1_ENABLED */
2733 #ifdef LIBXML_HTML_ENABLED
2736 * xmlSAX2InitHtmlDefaultSAXHandler:
2737 * @hdlr: the SAX handler
2739 * Initialize the default HTML SAX2 handler
2742 xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler
*hdlr
)
2744 if ((hdlr
== NULL
) || (hdlr
->initialized
!= 0))
2747 hdlr
->internalSubset
= xmlSAX2InternalSubset
;
2748 hdlr
->externalSubset
= NULL
;
2749 hdlr
->isStandalone
= NULL
;
2750 hdlr
->hasInternalSubset
= NULL
;
2751 hdlr
->hasExternalSubset
= NULL
;
2752 hdlr
->resolveEntity
= NULL
;
2753 hdlr
->getEntity
= xmlSAX2GetEntity
;
2754 hdlr
->getParameterEntity
= NULL
;
2755 hdlr
->entityDecl
= NULL
;
2756 hdlr
->attributeDecl
= NULL
;
2757 hdlr
->elementDecl
= NULL
;
2758 hdlr
->notationDecl
= NULL
;
2759 hdlr
->unparsedEntityDecl
= NULL
;
2760 hdlr
->setDocumentLocator
= xmlSAX2SetDocumentLocator
;
2761 hdlr
->startDocument
= xmlSAX2StartDocument
;
2762 hdlr
->endDocument
= xmlSAX2EndDocument
;
2763 hdlr
->startElement
= xmlSAX2StartElement
;
2764 hdlr
->endElement
= xmlSAX2EndElement
;
2765 hdlr
->reference
= NULL
;
2766 hdlr
->characters
= xmlSAX2Characters
;
2767 hdlr
->cdataBlock
= xmlSAX2CDataBlock
;
2768 hdlr
->ignorableWhitespace
= xmlSAX2IgnorableWhitespace
;
2769 hdlr
->processingInstruction
= xmlSAX2ProcessingInstruction
;
2770 hdlr
->comment
= xmlSAX2Comment
;
2771 hdlr
->warning
= xmlParserWarning
;
2772 hdlr
->error
= xmlParserError
;
2773 hdlr
->fatalError
= xmlParserError
;
2775 hdlr
->initialized
= 1;
2779 * htmlDefaultSAXHandlerInit:
2781 * Initialize the default SAX handler
2784 htmlDefaultSAXHandlerInit(void)
2786 xmlSAX2InitHtmlDefaultSAXHandler((xmlSAXHandlerPtr
) &htmlDefaultSAXHandler
);
2789 #endif /* LIBXML_HTML_ENABLED */
2791 #ifdef LIBXML_DOCB_ENABLED
2794 * xmlSAX2InitDocbDefaultSAXHandler:
2795 * @hdlr: the SAX handler
2797 * Initialize the default DocBook SAX2 handler
2800 xmlSAX2InitDocbDefaultSAXHandler(xmlSAXHandler
*hdlr
)
2802 if ((hdlr
== NULL
) || (hdlr
->initialized
!= 0))
2805 hdlr
->internalSubset
= xmlSAX2InternalSubset
;
2806 hdlr
->externalSubset
= NULL
;
2807 hdlr
->isStandalone
= xmlSAX2IsStandalone
;
2808 hdlr
->hasInternalSubset
= xmlSAX2HasInternalSubset
;
2809 hdlr
->hasExternalSubset
= xmlSAX2HasExternalSubset
;
2810 hdlr
->resolveEntity
= xmlSAX2ResolveEntity
;
2811 hdlr
->getEntity
= xmlSAX2GetEntity
;
2812 hdlr
->getParameterEntity
= NULL
;
2813 hdlr
->entityDecl
= xmlSAX2EntityDecl
;
2814 hdlr
->attributeDecl
= NULL
;
2815 hdlr
->elementDecl
= NULL
;
2816 hdlr
->notationDecl
= NULL
;
2817 hdlr
->unparsedEntityDecl
= NULL
;
2818 hdlr
->setDocumentLocator
= xmlSAX2SetDocumentLocator
;
2819 hdlr
->startDocument
= xmlSAX2StartDocument
;
2820 hdlr
->endDocument
= xmlSAX2EndDocument
;
2821 hdlr
->startElement
= xmlSAX2StartElement
;
2822 hdlr
->endElement
= xmlSAX2EndElement
;
2823 hdlr
->reference
= xmlSAX2Reference
;
2824 hdlr
->characters
= xmlSAX2Characters
;
2825 hdlr
->cdataBlock
= NULL
;
2826 hdlr
->ignorableWhitespace
= xmlSAX2IgnorableWhitespace
;
2827 hdlr
->processingInstruction
= NULL
;
2828 hdlr
->comment
= xmlSAX2Comment
;
2829 hdlr
->warning
= xmlParserWarning
;
2830 hdlr
->error
= xmlParserError
;
2831 hdlr
->fatalError
= xmlParserError
;
2833 hdlr
->initialized
= 1;
2837 * docbDefaultSAXHandlerInit:
2839 * Initialize the default SAX handler
2842 docbDefaultSAXHandlerInit(void)
2844 xmlSAX2InitDocbDefaultSAXHandler((xmlSAXHandlerPtr
) &docbDefaultSAXHandler
);
2847 #endif /* LIBXML_DOCB_ENABLED */
2849 #include "elfgcchack.h"