2 * SAX.c : Default SAX 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_SAX */
30 /* #define DEBUG_SAX_TREE */
34 * @ctx: the user data (XML parser context)
36 * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
41 getPublicId(void *ctx ATTRIBUTE_UNUSED
)
43 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
49 * @ctx: the user data (XML parser context)
51 * Return the system ID, basically URL or filename e.g.
52 * http://www.sgmlsource.com/dtds/memo.dtd
57 getSystemId(void *ctx
)
59 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
60 return((const xmlChar
*) ctxt
->input
->filename
);
65 * @ctx: the user data (XML parser context)
67 * Return the line number of the current parsing point.
72 getLineNumber(void *ctx
)
74 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
75 return(ctxt
->input
->line
);
80 * @ctx: the user data (XML parser context)
82 * Return the column number of the current parsing point.
87 getColumnNumber(void *ctx
)
89 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
90 return(ctxt
->input
->col
);
95 * @ctx: the user data (XML parser context)
97 * Is this document tagged standalone ?
102 isStandalone(void *ctx
)
104 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
105 return(ctxt
->myDoc
->standalone
== 1);
110 * @ctx: the user data (XML parser context)
112 * Does this document has an internal subset
117 hasInternalSubset(void *ctx
)
119 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
120 return(ctxt
->myDoc
->intSubset
!= NULL
);
125 * @ctx: the user data (XML parser context)
127 * Does this document has an external subset
132 hasExternalSubset(void *ctx
)
134 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
135 return(ctxt
->myDoc
->extSubset
!= NULL
);
140 * @ctx: the user data (XML parser context)
141 * @name: the root element name
142 * @ExternalID: the external ID
143 * @SystemID: the SYSTEM ID (e.g. filename or URL)
145 * Callback on internal subset declaration.
148 internalSubset(void *ctx
, const xmlChar
*name
,
149 const xmlChar
*ExternalID
, const xmlChar
*SystemID
)
151 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
154 xmlGenericError(xmlGenericErrorContext
,
155 "SAX.internalSubset(%s, %s, %s)\n",
156 name
, ExternalID
, SystemID
);
159 if (ctxt
->myDoc
== NULL
)
161 dtd
= xmlGetIntSubset(ctxt
->myDoc
);
165 xmlUnlinkNode((xmlNodePtr
) dtd
);
167 ctxt
->myDoc
->intSubset
= NULL
;
169 ctxt
->myDoc
->intSubset
=
170 xmlCreateIntSubset(ctxt
->myDoc
, name
, ExternalID
, SystemID
);
175 * @ctx: the user data (XML parser context)
176 * @name: the root element name
177 * @ExternalID: the external ID
178 * @SystemID: the SYSTEM ID (e.g. filename or URL)
180 * Callback on external subset declaration.
183 externalSubset(void *ctx
, const xmlChar
*name
,
184 const xmlChar
*ExternalID
, const xmlChar
*SystemID
)
186 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
188 xmlGenericError(xmlGenericErrorContext
,
189 "SAX.externalSubset(%s, %s, %s)\n",
190 name
, ExternalID
, SystemID
);
192 if (((ExternalID
!= NULL
) || (SystemID
!= NULL
)) &&
193 (((ctxt
->validate
) || (ctxt
->loadsubset
!= 0)) &&
194 (ctxt
->wellFormed
&& ctxt
->myDoc
))) {
196 * Try to fetch and parse the external subset.
198 xmlParserInputPtr oldinput
;
201 xmlParserInputPtr
*oldinputTab
;
202 xmlParserInputPtr input
= NULL
;
207 * Ask the Entity resolver to load the damn thing
209 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->resolveEntity
!= NULL
))
210 input
= ctxt
->sax
->resolveEntity(ctxt
->userData
, ExternalID
,
216 xmlNewDtd(ctxt
->myDoc
, name
, ExternalID
, SystemID
);
219 * make sure we won't destroy the main document context
221 oldinput
= ctxt
->input
;
222 oldinputNr
= ctxt
->inputNr
;
223 oldinputMax
= ctxt
->inputMax
;
224 oldinputTab
= ctxt
->inputTab
;
225 oldcharset
= ctxt
->charset
;
227 ctxt
->inputTab
= (xmlParserInputPtr
*)
228 xmlMalloc(5 * sizeof(xmlParserInputPtr
));
229 if (ctxt
->inputTab
== NULL
) {
230 ctxt
->errNo
= XML_ERR_NO_MEMORY
;
231 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->error
!= NULL
))
232 ctxt
->sax
->error(ctxt
->userData
,
233 "externalSubset: out of memory\n");
234 ctxt
->errNo
= XML_ERR_NO_MEMORY
;
235 ctxt
->input
= oldinput
;
236 ctxt
->inputNr
= oldinputNr
;
237 ctxt
->inputMax
= oldinputMax
;
238 ctxt
->inputTab
= oldinputTab
;
239 ctxt
->charset
= oldcharset
;
245 xmlPushInput(ctxt
, input
);
248 * On the fly encoding conversion if needed
250 enc
= xmlDetectCharEncoding(ctxt
->input
->cur
, 4);
251 xmlSwitchEncoding(ctxt
, enc
);
253 if (input
->filename
== NULL
)
254 input
->filename
= (char *) xmlStrdup(SystemID
);
257 input
->base
= ctxt
->input
->cur
;
258 input
->cur
= ctxt
->input
->cur
;
262 * let's parse that entity knowing it's an external subset.
264 xmlParseExternalSubset(ctxt
, ExternalID
, SystemID
);
267 * Free up the external entities
270 while (ctxt
->inputNr
> 1)
272 xmlFreeInputStream(ctxt
->input
);
273 xmlFree(ctxt
->inputTab
);
276 * Restore the parsing context of the main entity
278 ctxt
->input
= oldinput
;
279 ctxt
->inputNr
= oldinputNr
;
280 ctxt
->inputMax
= oldinputMax
;
281 ctxt
->inputTab
= oldinputTab
;
282 ctxt
->charset
= oldcharset
;
283 /* ctxt->wellFormed = oldwellFormed; */
289 * @ctx: the user data (XML parser context)
290 * @publicId: The public ID of the entity
291 * @systemId: The system ID of the entity
293 * The entity loader, to control the loading of external entities,
294 * the application can either:
295 * - override this resolveEntity() callback in the SAX block
296 * - or better use the xmlSetExternalEntityLoader() function to
297 * set up it's own entity resolution routine
299 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
302 resolveEntity(void *ctx
, const xmlChar
*publicId
, const xmlChar
*systemId
)
304 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
305 xmlParserInputPtr ret
;
307 const char *base
= NULL
;
309 if (ctxt
->input
!= NULL
)
310 base
= ctxt
->input
->filename
;
312 base
= ctxt
->directory
;
314 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
317 xmlGenericError(xmlGenericErrorContext
,
318 "SAX.resolveEntity(%s, %s)\n", publicId
, systemId
);
321 ret
= xmlLoadExternalEntity((const char *) URI
,
322 (const char *) publicId
, ctxt
);
330 * @ctx: the user data (XML parser context)
331 * @name: The entity name
333 * Get an entity by name
335 * Returns the xmlEntityPtr if found.
338 getEntity(void *ctx
, const xmlChar
*name
)
340 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
344 xmlGenericError(xmlGenericErrorContext
,
345 "SAX.getEntity(%s)\n", name
);
348 if ((ctxt
->myDoc
!= NULL
) && (ctxt
->myDoc
->standalone
== 1)) {
349 if (ctxt
->inSubset
== 2) {
350 ctxt
->myDoc
->standalone
= 0;
351 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
352 ctxt
->myDoc
->standalone
= 1;
354 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
356 ctxt
->myDoc
->standalone
= 0;
357 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
359 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->error
!= NULL
))
360 ctxt
->sax
->error(ctxt
,
361 "Entity(%s) document marked standalone but require external subset\n",
364 ctxt
->wellFormed
= 0;
366 ctxt
->myDoc
->standalone
= 1;
370 ret
= xmlGetDocEntity(ctxt
->myDoc
, name
);
372 if ((ret
!= NULL
) && (ctxt
->validate
) && (ret
->children
== NULL
) &&
373 (ret
->etype
== XML_EXTERNAL_GENERAL_PARSED_ENTITY
)) {
375 * for validation purposes we really need to fetch and
376 * parse the external entity
380 xmlParseCtxtExternalEntity(ctxt
, ret
->URI
, ret
->ExternalID
, &children
);
381 xmlAddChildList((xmlNodePtr
) ret
, children
);
387 * getParameterEntity:
388 * @ctx: the user data (XML parser context)
389 * @name: The entity name
391 * Get a parameter entity by name
393 * Returns the xmlEntityPtr if found.
396 getParameterEntity(void *ctx
, const xmlChar
*name
)
398 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
402 xmlGenericError(xmlGenericErrorContext
,
403 "SAX.getParameterEntity(%s)\n", name
);
406 ret
= xmlGetParameterEntity(ctxt
->myDoc
, name
);
413 * @ctx: the user data (XML parser context)
414 * @name: the entity name
415 * @type: the entity type
416 * @publicId: The public ID of the entity
417 * @systemId: The system ID of the entity
418 * @content: the entity value (without processing).
420 * An entity definition has been parsed
423 entityDecl(void *ctx
, const xmlChar
*name
, int type
,
424 const xmlChar
*publicId
, const xmlChar
*systemId
, xmlChar
*content
)
427 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
430 xmlGenericError(xmlGenericErrorContext
,
431 "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
432 name
, type
, publicId
, systemId
, content
);
434 if (ctxt
->inSubset
== 1) {
435 ent
= xmlAddDocEntity(ctxt
->myDoc
, name
, type
, publicId
,
437 if ((ent
== NULL
) && (ctxt
->pedantic
) &&
438 (ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
439 ctxt
->sax
->warning(ctxt
,
440 "Entity(%s) already defined in the internal subset\n", name
);
441 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
443 const char *base
= NULL
;
445 if (ctxt
->input
!= NULL
)
446 base
= ctxt
->input
->filename
;
448 base
= ctxt
->directory
;
450 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
453 } else if (ctxt
->inSubset
== 2) {
454 ent
= xmlAddDtdEntity(ctxt
->myDoc
, name
, type
, publicId
,
456 if ((ent
== NULL
) && (ctxt
->pedantic
) &&
457 (ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
458 ctxt
->sax
->warning(ctxt
,
459 "Entity(%s) already defined in the external subset\n", name
);
460 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
462 const char *base
= NULL
;
464 if (ctxt
->input
!= NULL
)
465 base
= ctxt
->input
->filename
;
467 base
= ctxt
->directory
;
469 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
473 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->error
!= NULL
))
474 ctxt
->sax
->error(ctxt
,
475 "SAX.entityDecl(%s) called while not in subset\n", name
);
481 * @ctx: the user data (XML parser context)
482 * @elem: the name of the element
483 * @fullname: the attribute name
484 * @type: the attribute type
485 * @def: the type of default value
486 * @defaultValue: the attribute default value
487 * @tree: the tree of enumerated value set
489 * An attribute definition has been parsed
492 attributeDecl(void *ctx
, const xmlChar
*elem
, const xmlChar
*fullname
,
493 int type
, int def
, const xmlChar
*defaultValue
,
494 xmlEnumerationPtr tree
)
496 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
497 xmlAttributePtr attr
;
498 xmlChar
*name
= NULL
, *prefix
= NULL
;
501 xmlGenericError(xmlGenericErrorContext
,
502 "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
503 elem
, fullname
, type
, def
, defaultValue
);
505 name
= xmlSplitQName(ctxt
, fullname
, &prefix
);
506 ctxt
->vctxt
.valid
= 1;
507 if (ctxt
->inSubset
== 1)
508 attr
= xmlAddAttributeDecl(&ctxt
->vctxt
, ctxt
->myDoc
->intSubset
, elem
,
509 name
, prefix
, (xmlAttributeType
) type
,
510 (xmlAttributeDefault
) def
, defaultValue
, tree
);
511 else if (ctxt
->inSubset
== 2)
512 attr
= xmlAddAttributeDecl(&ctxt
->vctxt
, ctxt
->myDoc
->extSubset
, elem
,
513 name
, prefix
, (xmlAttributeType
) type
,
514 (xmlAttributeDefault
) def
, defaultValue
, tree
);
516 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->error
!= NULL
))
517 ctxt
->sax
->error(ctxt
,
518 "SAX.attributeDecl(%s) called while not in subset\n", name
);
521 if (ctxt
->vctxt
.valid
== 0)
523 if ((attr
!= NULL
) && (ctxt
->validate
) && (ctxt
->wellFormed
) &&
524 (ctxt
->myDoc
!= NULL
) && (ctxt
->myDoc
->intSubset
!= NULL
))
525 ctxt
->valid
&= xmlValidateAttributeDecl(&ctxt
->vctxt
, ctxt
->myDoc
,
535 * @ctx: the user data (XML parser context)
536 * @name: the element name
537 * @type: the element type
538 * @content: the element value tree
540 * An element definition has been parsed
543 elementDecl(void *ctx
, const xmlChar
* name
, int type
,
544 xmlElementContentPtr content
)
546 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
547 xmlElementPtr elem
= NULL
;
550 xmlGenericError(xmlGenericErrorContext
,
551 "SAX.elementDecl(%s, %d, ...)\n", name
, type
);
554 if (ctxt
->inSubset
== 1)
555 elem
= xmlAddElementDecl(&ctxt
->vctxt
, ctxt
->myDoc
->intSubset
,
556 name
, (xmlElementTypeVal
) type
, content
);
557 else if (ctxt
->inSubset
== 2)
558 elem
= xmlAddElementDecl(&ctxt
->vctxt
, ctxt
->myDoc
->extSubset
,
559 name
, (xmlElementTypeVal
) type
, content
);
561 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->error
!= NULL
))
562 ctxt
->sax
->error(ctxt
,
563 "SAX.elementDecl(%s) called while not in subset\n",
569 if (ctxt
->validate
&& ctxt
->wellFormed
&&
570 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
572 xmlValidateElementDecl(&ctxt
->vctxt
, ctxt
->myDoc
, elem
);
577 * @ctx: the user data (XML parser context)
578 * @name: The name of the notation
579 * @publicId: The public ID of the entity
580 * @systemId: The system ID of the entity
582 * What to do when a notation declaration has been parsed.
585 notationDecl(void *ctx
, const xmlChar
*name
,
586 const xmlChar
*publicId
, const xmlChar
*systemId
)
588 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
589 xmlNotationPtr nota
= NULL
;
592 xmlGenericError(xmlGenericErrorContext
,
593 "SAX.notationDecl(%s, %s, %s)\n", name
, publicId
, systemId
);
596 if ((publicId
== NULL
) && (systemId
== NULL
)) {
597 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->error
!= NULL
))
598 ctxt
->sax
->error(ctxt
,
599 "SAX.notationDecl(%s) externalID or PublicID missing\n", name
);
601 ctxt
->wellFormed
= 0;
603 } else if (ctxt
->inSubset
== 1)
604 nota
= xmlAddNotationDecl(&ctxt
->vctxt
, ctxt
->myDoc
->intSubset
, name
,
606 else if (ctxt
->inSubset
== 2)
607 nota
= xmlAddNotationDecl(&ctxt
->vctxt
, ctxt
->myDoc
->extSubset
, name
,
610 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->error
!= NULL
))
611 ctxt
->sax
->error(ctxt
,
612 "SAX.notationDecl(%s) called while not in subset\n", name
);
615 if (nota
== NULL
) ctxt
->valid
= 0;
616 if (ctxt
->validate
&& ctxt
->wellFormed
&&
617 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
618 ctxt
->valid
&= xmlValidateNotationDecl(&ctxt
->vctxt
, ctxt
->myDoc
,
623 * unparsedEntityDecl:
624 * @ctx: the user data (XML parser context)
625 * @name: The name of the entity
626 * @publicId: The public ID of the entity
627 * @systemId: The system ID of the entity
628 * @notationName: the name of the notation
630 * What to do when an unparsed entity declaration is parsed
633 unparsedEntityDecl(void *ctx
, const xmlChar
*name
,
634 const xmlChar
*publicId
, const xmlChar
*systemId
,
635 const xmlChar
*notationName
)
638 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
640 xmlGenericError(xmlGenericErrorContext
,
641 "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
642 name
, publicId
, systemId
, notationName
);
645 Done in xmlValidateDtdFinal now
.
646 if (ctxt
->validate
&& ctxt
->wellFormed
&& ctxt
->myDoc
) {
648 ret
= xmlValidateNotationUse(&ctxt
->vctxt
, ctxt
->myDoc
,
651 ctxt
->wellFormed
= 0;
656 if (ctxt
->inSubset
== 1) {
657 ent
= xmlAddDocEntity(ctxt
->myDoc
, name
,
658 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY
,
659 publicId
, systemId
, notationName
);
660 if ((ent
== NULL
) && (ctxt
->pedantic
) &&
661 (ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
662 ctxt
->sax
->warning(ctxt
,
663 "Entity(%s) already defined in the internal subset\n", name
);
664 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
666 const char *base
= NULL
;
668 if (ctxt
->input
!= NULL
)
669 base
= ctxt
->input
->filename
;
671 base
= ctxt
->directory
;
673 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
676 } else if (ctxt
->inSubset
== 2) {
677 ent
= xmlAddDtdEntity(ctxt
->myDoc
, name
,
678 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY
,
679 publicId
, systemId
, notationName
);
680 if ((ent
== NULL
) && (ctxt
->pedantic
) &&
681 (ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
682 ctxt
->sax
->warning(ctxt
,
683 "Entity(%s) already defined in the external subset\n", name
);
684 if ((ent
!= NULL
) && (ent
->URI
== NULL
) && (systemId
!= NULL
)) {
686 const char *base
= NULL
;
688 if (ctxt
->input
!= NULL
)
689 base
= ctxt
->input
->filename
;
691 base
= ctxt
->directory
;
693 URI
= xmlBuildURI(systemId
, (const xmlChar
*) base
);
697 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->error
!= NULL
))
698 ctxt
->sax
->error(ctxt
,
699 "SAX.unparsedEntityDecl(%s) called while not in subset\n", name
);
704 * setDocumentLocator:
705 * @ctx: the user data (XML parser context)
706 * @loc: A SAX Locator
708 * Receive the document locator at startup, actually xmlDefaultSAXLocator
709 * Everything is available on the context, so this is useless in our case.
712 setDocumentLocator(void *ctx ATTRIBUTE_UNUSED
, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED
)
714 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
716 xmlGenericError(xmlGenericErrorContext
,
717 "SAX.setDocumentLocator()\n");
723 * @ctx: the user data (XML parser context)
725 * called when the document start being processed.
728 startDocument(void *ctx
)
730 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
734 xmlGenericError(xmlGenericErrorContext
,
735 "SAX.startDocument()\n");
738 if (ctxt
->myDoc
== NULL
)
739 #ifdef LIBXML_HTML_ENABLED
740 ctxt
->myDoc
= htmlNewDocNoDtD(NULL
, NULL
);
742 xmlGenericError(xmlGenericErrorContext
,
743 "libxml2 built without HTML support\n");
746 doc
= ctxt
->myDoc
= xmlNewDoc(ctxt
->version
);
748 if (ctxt
->encoding
!= NULL
)
749 doc
->encoding
= xmlStrdup(ctxt
->encoding
);
751 doc
->encoding
= NULL
;
752 doc
->standalone
= ctxt
->standalone
;
755 if ((ctxt
->myDoc
!= NULL
) && (ctxt
->myDoc
->URL
== NULL
) &&
756 (ctxt
->input
!= NULL
) && (ctxt
->input
->filename
!= NULL
)) {
757 ctxt
->myDoc
->URL
= xmlStrdup((const xmlChar
*) ctxt
->input
->filename
);
763 * @ctx: the user data (XML parser context)
765 * called when the document end has been detected.
768 endDocument(void *ctx
)
770 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
772 xmlGenericError(xmlGenericErrorContext
,
773 "SAX.endDocument()\n");
775 if (ctxt
->validate
&& ctxt
->wellFormed
&&
776 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
777 ctxt
->valid
&= xmlValidateDocumentFinal(&ctxt
->vctxt
, ctxt
->myDoc
);
780 * Grab the encoding if it was added on-the-fly
782 if ((ctxt
->encoding
!= NULL
) && (ctxt
->myDoc
!= NULL
) &&
783 (ctxt
->myDoc
->encoding
== NULL
)) {
784 ctxt
->myDoc
->encoding
= ctxt
->encoding
;
785 ctxt
->encoding
= NULL
;
787 if ((ctxt
->inputTab
[0]->encoding
!= NULL
) && (ctxt
->myDoc
!= NULL
) &&
788 (ctxt
->myDoc
->encoding
== NULL
)) {
789 ctxt
->myDoc
->encoding
= xmlStrdup(ctxt
->inputTab
[0]->encoding
);
791 if ((ctxt
->charset
!= XML_CHAR_ENCODING_NONE
) && (ctxt
->myDoc
!= NULL
) &&
792 (ctxt
->myDoc
->charset
== XML_CHAR_ENCODING_NONE
)) {
793 ctxt
->myDoc
->charset
= ctxt
->charset
;
799 * @ctx: the user data (XML parser context)
800 * @fullname: The attribute name, including namespace prefix
801 * @value: The attribute value
802 * @prefix: the prefix on the element node
804 * Handle an attribute that has been read by the parser.
805 * The default handling is to convert the attribute into an
806 * DOM subtree and past it in a new xmlAttr element added to
810 my_attribute(void *ctx
, const xmlChar
*fullname
, const xmlChar
*value
,
811 const xmlChar
*prefix
)
813 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
822 xmlGenericError(xmlGenericErrorContext,
823 "SAX.attribute(%s, %s)\n", fullname, value);
827 * Split the full name into a namespace prefix and the tag name
829 name
= xmlSplitQName(ctxt
, fullname
, &ns
);
832 * Do the last stage of the attribute normalization
833 * Needed for HTML too:
834 * http://www.w3.org/TR/html4/types.html#h-6.2
836 ctxt
->vctxt
.valid
= 1;
837 nval
= xmlValidCtxtNormalizeAttributeValue(&ctxt
->vctxt
,
838 ctxt
->myDoc
, ctxt
->node
,
840 if (ctxt
->vctxt
.valid
!= 1) {
847 * Check whether it's a namespace definition
849 if ((!ctxt
->html
) && (ns
== NULL
) &&
850 (name
[0] == 'x') && (name
[1] == 'm') && (name
[2] == 'l') &&
851 (name
[3] == 'n') && (name
[4] == 's') && (name
[5] == 0)) {
857 uri
= xmlParseURI((const char *)value
);
859 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
860 ctxt
->sax
->warning(ctxt
->userData
,
861 "nmlns: %s not a valid URI\n", value
);
863 if (uri
->scheme
== NULL
) {
864 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
865 ctxt
->sax
->warning(ctxt
->userData
,
866 "nmlns: URI %s is not absolute\n", value
);
872 /* a default namespace definition */
873 nsret
= xmlNewNs(ctxt
->node
, value
, NULL
);
876 * Validate also for namespace decls, they are attributes from
877 * an XML-1.0 perspective
879 if (nsret
!= NULL
&& ctxt
->validate
&& ctxt
->wellFormed
&&
880 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
881 ctxt
->valid
&= xmlValidateOneNamespace(&ctxt
->vctxt
, ctxt
->myDoc
,
882 ctxt
->node
, prefix
, nsret
, value
);
890 (ns
!= NULL
) && (ns
[0] == 'x') && (ns
[1] == 'm') && (ns
[2] == 'l') &&
891 (ns
[3] == 'n') && (ns
[4] == 's') && (ns
[5] == 0)) {
895 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->error
!= NULL
))
896 ctxt
->sax
->error(ctxt
->userData
,
897 "Empty namespace name for prefix %s\n", name
);
899 /* a standard namespace definition */
900 nsret
= xmlNewNs(ctxt
->node
, value
, name
);
903 * Validate also for namespace decls, they are attributes from
904 * an XML-1.0 perspective
906 if (nsret
!= NULL
&& ctxt
->validate
&& ctxt
->wellFormed
&&
907 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
908 ctxt
->valid
&= xmlValidateOneNamespace(&ctxt
->vctxt
, ctxt
->myDoc
,
909 ctxt
->node
, prefix
, nsret
, value
);
918 namespace = xmlSearchNs(ctxt
->myDoc
, ctxt
->node
, ns
);
923 /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
924 ret
= xmlNewNsPropEatName(ctxt
->node
, namespace, name
, NULL
);
927 if ((ctxt
->replaceEntities
== 0) && (!ctxt
->html
)) {
930 ret
->children
= xmlStringGetNodeList(ctxt
->myDoc
, value
);
932 while (tmp
!= NULL
) {
933 tmp
->parent
= (xmlNodePtr
) ret
;
934 if (tmp
->next
== NULL
)
938 } else if (value
!= NULL
) {
939 ret
->children
= xmlNewDocText(ctxt
->myDoc
, value
);
940 ret
->last
= ret
->children
;
941 if (ret
->children
!= NULL
)
942 ret
->children
->parent
= (xmlNodePtr
) ret
;
946 if ((!ctxt
->html
) && ctxt
->validate
&& ctxt
->wellFormed
&&
947 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
) {
950 * If we don't substitute entities, the validation should be
951 * done on a value with replaced entities anyway.
953 if (!ctxt
->replaceEntities
) {
957 val
= xmlStringDecodeEntities(ctxt
, value
, XML_SUBSTITUTE_REF
,
962 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
963 ctxt
->myDoc
, ctxt
->node
, ret
, value
);
968 * Do the last stage of the attribute normalization
969 * It need to be done twice ... it's an extra burden related
970 * to the ability to keep references in attributes
972 nvalnorm
= xmlValidNormalizeAttributeValue(ctxt
->myDoc
,
973 ctxt
->node
, fullname
, val
);
974 if (nvalnorm
!= NULL
) {
979 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
,
980 ctxt
->myDoc
, ctxt
->node
, ret
, val
);
984 ctxt
->valid
&= xmlValidateOneAttribute(&ctxt
->vctxt
, ctxt
->myDoc
,
985 ctxt
->node
, ret
, value
);
987 } else if (((ctxt
->replaceEntities
== 0) && (ctxt
->external
!= 2)) ||
988 ((ctxt
->replaceEntities
!= 0) && (ctxt
->inSubset
== 0))) {
990 * when validating, the ID registration is done at the attribute
991 * validation level. Otherwise we have to do specific handling here.
993 if (xmlIsID(ctxt
->myDoc
, ctxt
->node
, ret
))
994 xmlAddID(&ctxt
->vctxt
, ctxt
->myDoc
, value
, ret
);
995 else if (xmlIsRef(ctxt
->myDoc
, ctxt
->node
, ret
))
996 xmlAddRef(&ctxt
->vctxt
, ctxt
->myDoc
, value
, ret
);
1007 * @ctx: the user data (XML parser context)
1008 * @fullname: The attribute name, including namespace prefix
1009 * @value: The attribute value
1011 * Handle an attribute that has been read by the parser.
1012 * The default handling is to convert the attribute into an
1013 * DOM subtree and past it in a new xmlAttr element added to
1017 attribute(void *ctx
, const xmlChar
*fullname
, const xmlChar
*value
)
1019 my_attribute(ctx
, fullname
, value
, NULL
);
1023 * xmlCheckDefaultedAttributes:
1025 * Check defaulted attributes from the DTD
1028 xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt
, const xmlChar
*name
,
1029 const xmlChar
*prefix
, const xmlChar
**atts
) {
1030 xmlElementPtr elemDecl
;
1035 elemDecl
= xmlGetDtdQElementDesc(ctxt
->myDoc
->intSubset
, name
, prefix
);
1036 if (elemDecl
== NULL
) {
1037 elemDecl
= xmlGetDtdQElementDesc(ctxt
->myDoc
->extSubset
, name
, prefix
);
1041 process_external_subset
:
1043 if (elemDecl
!= NULL
) {
1044 xmlAttributePtr attr
= elemDecl
->attributes
;
1046 * Check against defaulted attributes from the external subset
1047 * if the document is stamped as standalone
1049 if ((ctxt
->myDoc
->standalone
== 1) &&
1050 (ctxt
->myDoc
->extSubset
!= NULL
) &&
1052 while (attr
!= NULL
) {
1053 if ((attr
->defaultValue
!= NULL
) &&
1054 (xmlGetDtdQAttrDesc(ctxt
->myDoc
->extSubset
,
1055 attr
->elem
, attr
->name
,
1056 attr
->prefix
) == attr
) &&
1057 (xmlGetDtdQAttrDesc(ctxt
->myDoc
->intSubset
,
1058 attr
->elem
, attr
->name
,
1059 attr
->prefix
) == NULL
)) {
1062 if (attr
->prefix
!= NULL
) {
1063 fulln
= xmlStrdup(attr
->prefix
);
1064 fulln
= xmlStrcat(fulln
, BAD_CAST
":");
1065 fulln
= xmlStrcat(fulln
, attr
->name
);
1067 fulln
= xmlStrdup(attr
->name
);
1071 * Check that the attribute is not declared in the
1078 while (att
!= NULL
) {
1079 if (xmlStrEqual(att
, fulln
))
1086 if (ctxt
->vctxt
.error
!= NULL
)
1087 ctxt
->vctxt
.error(ctxt
->vctxt
.userData
,
1088 "standalone: attribute %s on %s defaulted from external subset\n",
1098 * Actually insert defaulted values when needed
1100 attr
= elemDecl
->attributes
;
1101 while (attr
!= NULL
) {
1103 * Make sure that attributes redefinition occuring in the
1104 * internal subset are not overriden by definitions in the
1107 if (attr
->defaultValue
!= NULL
) {
1109 * the element should be instantiated in the tree if:
1110 * - this is a namespace prefix
1111 * - the user required for completion in the tree
1113 * - there isn't already an attribute definition
1114 * in the internal subset overriding it.
1116 if (((attr
->prefix
!= NULL
) &&
1117 (xmlStrEqual(attr
->prefix
, BAD_CAST
"xmlns"))) ||
1118 ((attr
->prefix
== NULL
) &&
1119 (xmlStrEqual(attr
->name
, BAD_CAST
"xmlns"))) ||
1120 (ctxt
->loadsubset
& XML_COMPLETE_ATTRS
)) {
1121 xmlAttributePtr tst
;
1123 tst
= xmlGetDtdQAttrDesc(ctxt
->myDoc
->intSubset
,
1124 attr
->elem
, attr
->name
,
1126 if ((tst
== attr
) || (tst
== NULL
)) {
1129 if (attr
->prefix
!= NULL
) {
1130 fulln
= xmlStrdup(attr
->prefix
);
1131 fulln
= xmlStrcat(fulln
, BAD_CAST
":");
1132 fulln
= xmlStrcat(fulln
, attr
->name
);
1134 fulln
= xmlStrdup(attr
->name
);
1138 * Check that the attribute is not declared in the
1145 while (att
!= NULL
) {
1146 if (xmlStrEqual(att
, fulln
))
1153 attribute(ctxt
, fulln
, attr
->defaultValue
);
1161 if (internal
== 1) {
1162 elemDecl
= xmlGetDtdQElementDesc(ctxt
->myDoc
->extSubset
,
1165 goto process_external_subset
;
1172 * @ctx: the user data (XML parser context)
1173 * @fullname: The element name, including namespace prefix
1174 * @atts: An array of name/value attributes pairs, NULL terminated
1176 * called when an opening tag has been processed.
1179 startElement(void *ctx
, const xmlChar
*fullname
, const xmlChar
**atts
)
1181 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1183 xmlNodePtr parent
= ctxt
->node
;
1188 const xmlChar
*value
;
1192 xmlGenericError(xmlGenericErrorContext
,
1193 "SAX.startElement(%s)\n", fullname
);
1197 * First check on validity:
1199 if (ctxt
->validate
&& (ctxt
->myDoc
->extSubset
== NULL
) &&
1200 ((ctxt
->myDoc
->intSubset
== NULL
) ||
1201 ((ctxt
->myDoc
->intSubset
->notations
== NULL
) &&
1202 (ctxt
->myDoc
->intSubset
->elements
== NULL
) &&
1203 (ctxt
->myDoc
->intSubset
->attributes
== NULL
) &&
1204 (ctxt
->myDoc
->intSubset
->entities
== NULL
)))) {
1205 if (ctxt
->vctxt
.error
!= NULL
) {
1206 ctxt
->vctxt
.error(ctxt
->vctxt
.userData
,
1207 "Validation failed: no DTD found !\n");
1211 ctxt
->errNo
= XML_ERR_NO_DTD
;
1216 * Split the full name into a namespace prefix and the tag name
1218 name
= xmlSplitQName(ctxt
, fullname
, &prefix
);
1222 * Note : the namespace resolution is deferred until the end of the
1223 * attributes parsing, since local namespace can be defined as
1224 * an attribute at this level.
1226 ret
= xmlNewDocNodeEatName(ctxt
->myDoc
, NULL
, name
, NULL
);
1227 if (ret
== NULL
) return;
1228 if (ctxt
->myDoc
->children
== NULL
) {
1229 #ifdef DEBUG_SAX_TREE
1230 xmlGenericError(xmlGenericErrorContext
, "Setting %s as root\n", name
);
1232 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
1233 } else if (parent
== NULL
) {
1234 parent
= ctxt
->myDoc
->children
;
1237 if (ctxt
->linenumbers
) {
1238 if (ctxt
->input
!= NULL
)
1239 ret
->content
= (void *) (long) ctxt
->input
->line
;
1243 * We are parsing a new node.
1245 #ifdef DEBUG_SAX_TREE
1246 xmlGenericError(xmlGenericErrorContext
, "pushing(%s)\n", name
);
1248 nodePush(ctxt
, ret
);
1251 * Link the child element
1253 if (parent
!= NULL
) {
1254 if (parent
->type
== XML_ELEMENT_NODE
) {
1255 #ifdef DEBUG_SAX_TREE
1256 xmlGenericError(xmlGenericErrorContext
,
1257 "adding child %s to %s\n", name
, parent
->name
);
1259 xmlAddChild(parent
, ret
);
1261 #ifdef DEBUG_SAX_TREE
1262 xmlGenericError(xmlGenericErrorContext
,
1263 "adding sibling %s to ", name
);
1264 xmlDebugDumpOneNode(stderr
, parent
, 0);
1266 xmlAddSibling(parent
, ret
);
1271 * Insert all the defaulted attributes from the DTD especially namespaces
1273 if ((!ctxt
->html
) &&
1274 ((ctxt
->myDoc
->intSubset
!= NULL
) ||
1275 (ctxt
->myDoc
->extSubset
!= NULL
))) {
1276 xmlCheckDefaultedAttributes(ctxt
, name
, prefix
, atts
);
1280 * process all the attributes whose name start with "xmlns"
1287 while ((att
!= NULL
) && (value
!= NULL
)) {
1288 if ((att
[0] == 'x') && (att
[1] == 'm') && (att
[2] == 'l') &&
1289 (att
[3] == 'n') && (att
[4] == 's'))
1290 my_attribute(ctxt
, att
, value
, prefix
);
1299 * Search the namespace, note that since the attributes have been
1300 * processed, the local namespaces are available.
1302 ns
= xmlSearchNs(ctxt
->myDoc
, ret
, prefix
);
1303 if ((ns
== NULL
) && (parent
!= NULL
))
1304 ns
= xmlSearchNs(ctxt
->myDoc
, parent
, prefix
);
1305 if ((prefix
!= NULL
) && (ns
== NULL
)) {
1306 ns
= xmlNewNs(ret
, NULL
, prefix
);
1307 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->warning
!= NULL
))
1308 ctxt
->sax
->warning(ctxt
->userData
,
1309 "Namespace prefix %s is not defined\n", prefix
);
1313 * set the namespace node, making sure that if the default namspace
1314 * is unbound on a parent we simply kee it NULL
1316 if ((ns
!= NULL
) && (ns
->href
!= NULL
) &&
1317 ((ns
->href
[0] != 0) || (ns
->prefix
!= NULL
)))
1321 * process all the other attributes
1328 while (att
!= NULL
) {
1329 attribute(ctxt
, att
, value
);
1334 while ((att
!= NULL
) && (value
!= NULL
)) {
1335 if ((att
[0] != 'x') || (att
[1] != 'm') || (att
[2] != 'l') ||
1336 (att
[3] != 'n') || (att
[4] != 's'))
1337 attribute(ctxt
, att
, value
);
1349 * If it's the Document root, finish the DTD validation and
1350 * check the document root element for validity
1352 if ((ctxt
->validate
) && (ctxt
->vctxt
.finishDtd
== 0)) {
1355 chk
= xmlValidateDtdFinal(&ctxt
->vctxt
, ctxt
->myDoc
);
1359 ctxt
->wellFormed
= 0;
1360 ctxt
->valid
&= xmlValidateRoot(&ctxt
->vctxt
, ctxt
->myDoc
);
1361 ctxt
->vctxt
.finishDtd
= 1;
1371 * @ctx: the user data (XML parser context)
1372 * @name: The element name
1374 * called when the end of an element has been detected.
1377 endElement(void *ctx
, const xmlChar
*name ATTRIBUTE_UNUSED
)
1379 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1380 xmlParserNodeInfo node_info
;
1381 xmlNodePtr cur
= ctxt
->node
;
1385 xmlGenericError(xmlGenericErrorContext
, "SAX.endElement(NULL)\n");
1387 xmlGenericError(xmlGenericErrorContext
, "SAX.endElement(%s)\n", name
);
1390 /* Capture end position and add node */
1391 if (cur
!= NULL
&& ctxt
->record_info
) {
1392 node_info
.end_pos
= ctxt
->input
->cur
- ctxt
->input
->base
;
1393 node_info
.end_line
= ctxt
->input
->line
;
1394 node_info
.node
= cur
;
1395 xmlParserAddNodeInfo(ctxt
, &node_info
);
1399 if (ctxt
->validate
&& ctxt
->wellFormed
&&
1400 ctxt
->myDoc
&& ctxt
->myDoc
->intSubset
)
1401 ctxt
->valid
&= xmlValidateOneElement(&ctxt
->vctxt
, ctxt
->myDoc
,
1406 * end of parsing of this node.
1408 #ifdef DEBUG_SAX_TREE
1409 xmlGenericError(xmlGenericErrorContext
, "popping(%s)\n", cur
->name
);
1416 * @ctx: the user data (XML parser context)
1417 * @name: The entity name
1419 * called when an entity reference is detected.
1422 reference(void *ctx
, const xmlChar
*name
)
1424 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1428 xmlGenericError(xmlGenericErrorContext
,
1429 "SAX.reference(%s)\n", name
);
1432 ret
= xmlNewCharRef(ctxt
->myDoc
, name
);
1434 ret
= xmlNewReference(ctxt
->myDoc
, name
);
1435 #ifdef DEBUG_SAX_TREE
1436 xmlGenericError(xmlGenericErrorContext
,
1437 "add reference %s to %s \n", name
, ctxt
->node
->name
);
1439 xmlAddChild(ctxt
->node
, ret
);
1444 * @ctx: the user data (XML parser context)
1445 * @ch: a xmlChar string
1446 * @len: the number of xmlChar
1448 * receiving some chars from the parser.
1451 characters(void *ctx
, const xmlChar
*ch
, int len
)
1453 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1454 xmlNodePtr lastChild
;
1457 xmlGenericError(xmlGenericErrorContext
,
1458 "SAX.characters(%.30s, %d)\n", ch
, len
);
1461 * Handle the data if any. If there is no child
1462 * add it as content, otherwise if the last child is text,
1463 * concatenate it, else create a new node of type text.
1466 if (ctxt
->node
== NULL
) {
1467 #ifdef DEBUG_SAX_TREE
1468 xmlGenericError(xmlGenericErrorContext
,
1469 "add chars: ctxt->node == NULL !\n");
1473 lastChild
= xmlGetLastChild(ctxt
->node
);
1474 #ifdef DEBUG_SAX_TREE
1475 xmlGenericError(xmlGenericErrorContext
,
1476 "add chars to %s \n", ctxt
->node
->name
);
1480 * Here we needed an accelerator mechanism in case of very large
1481 * elements. Use an attribute in the structure !!!
1483 if (lastChild
== NULL
) {
1484 /* first node, first time */
1485 xmlNodeAddContentLen(ctxt
->node
, ch
, len
);
1486 if (ctxt
->node
->children
!= NULL
) {
1487 ctxt
->nodelen
= len
;
1488 ctxt
->nodemem
= len
+ 1;
1491 int coalesceText
= (lastChild
!= NULL
) &&
1492 (lastChild
->type
== XML_TEXT_NODE
) &&
1493 (lastChild
->name
== xmlStringText
);
1494 if ((coalesceText
) && (ctxt
->nodemem
!= 0)) {
1496 * The whole point of maintaining nodelen and nodemem,
1497 * xmlTextConcat is too costly, i.e. compute length,
1498 * reallocate a new buffer, move data, append ch. Here
1499 * We try to minimaze realloc() uses and avoid copying
1500 * and recomputing length over and over.
1502 if (ctxt
->nodelen
+ len
>= ctxt
->nodemem
) {
1506 size
= ctxt
->nodemem
+ len
;
1508 newbuf
= (xmlChar
*) xmlRealloc(lastChild
->content
,size
);
1509 if (newbuf
== NULL
) {
1510 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->error
!= NULL
))
1511 ctxt
->sax
->error(ctxt
->userData
,
1512 "SAX.characters(): out of memory\n");
1515 ctxt
->nodemem
= size
;
1516 lastChild
->content
= newbuf
;
1518 memcpy(&lastChild
->content
[ctxt
->nodelen
], ch
, len
);
1519 ctxt
->nodelen
+= len
;
1520 lastChild
->content
[ctxt
->nodelen
] = 0;
1521 } else if (coalesceText
) {
1522 xmlTextConcat(lastChild
, ch
, len
);
1523 if (ctxt
->node
->children
!= NULL
) {
1524 ctxt
->nodelen
= xmlStrlen(lastChild
->content
);
1525 ctxt
->nodemem
= ctxt
->nodelen
+ 1;
1528 /* Mixed content, first time */
1529 lastChild
= xmlNewTextLen(ch
, len
);
1530 xmlAddChild(ctxt
->node
, lastChild
);
1531 if (ctxt
->node
->children
!= NULL
) {
1532 ctxt
->nodelen
= len
;
1533 ctxt
->nodemem
= len
+ 1;
1540 * ignorableWhitespace:
1541 * @ctx: the user data (XML parser context)
1542 * @ch: a xmlChar string
1543 * @len: the number of xmlChar
1545 * receiving some ignorable whitespaces from the parser.
1546 * UNUSED: by default the DOM building will use characters
1549 ignorableWhitespace(void *ctx ATTRIBUTE_UNUSED
, const xmlChar
*ch ATTRIBUTE_UNUSED
, int len ATTRIBUTE_UNUSED
)
1551 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1553 xmlGenericError(xmlGenericErrorContext
,
1554 "SAX.ignorableWhitespace(%.30s, %d)\n", ch
, len
);
1559 * processingInstruction:
1560 * @ctx: the user data (XML parser context)
1561 * @target: the target name
1562 * @data: the PI data's
1564 * A processing instruction has been parsed.
1567 processingInstruction(void *ctx
, const xmlChar
*target
,
1568 const xmlChar
*data
)
1570 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1572 xmlNodePtr parent
= ctxt
->node
;
1575 xmlGenericError(xmlGenericErrorContext
,
1576 "SAX.processingInstruction(%s, %s)\n", target
, data
);
1579 ret
= xmlNewPI(target
, data
);
1580 if (ret
== NULL
) return;
1581 parent
= ctxt
->node
;
1583 if (ctxt
->inSubset
== 1) {
1584 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->intSubset
, ret
);
1586 } else if (ctxt
->inSubset
== 2) {
1587 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->extSubset
, ret
);
1590 if ((ctxt
->myDoc
->children
== NULL
) || (parent
== NULL
)) {
1591 #ifdef DEBUG_SAX_TREE
1592 xmlGenericError(xmlGenericErrorContext
,
1593 "Setting PI %s as root\n", target
);
1595 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
1598 if (parent
->type
== XML_ELEMENT_NODE
) {
1599 #ifdef DEBUG_SAX_TREE
1600 xmlGenericError(xmlGenericErrorContext
,
1601 "adding PI %s child to %s\n", target
, parent
->name
);
1603 xmlAddChild(parent
, ret
);
1605 #ifdef DEBUG_SAX_TREE
1606 xmlGenericError(xmlGenericErrorContext
,
1607 "adding PI %s sibling to ", target
);
1608 xmlDebugDumpOneNode(stderr
, parent
, 0);
1610 xmlAddSibling(parent
, ret
);
1616 * @ctx: the user data (XML parser context)
1617 * @href: the namespace associated URN
1618 * @prefix: the namespace prefix
1620 * An old global namespace has been parsed.
1623 globalNamespace(void *ctx
, const xmlChar
*href
, const xmlChar
*prefix
)
1625 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1627 xmlGenericError(xmlGenericErrorContext
,
1628 "SAX.globalNamespace(%s, %s)\n", href
, prefix
);
1630 xmlNewGlobalNs(ctxt
->myDoc
, href
, prefix
);
1635 * @ctx: the user data (XML parser context)
1636 * @name: the namespace prefix
1638 * Set the current element namespace.
1642 setNamespace(void *ctx
, const xmlChar
*name
)
1644 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1649 xmlGenericError(xmlGenericErrorContext
, "SAX.setNamespace(%s)\n", name
);
1651 ns
= xmlSearchNs(ctxt
->myDoc
, ctxt
->node
, name
);
1652 if (ns
== NULL
) { /* ctxt->node may not have a parent yet ! */
1653 if (ctxt
->nodeNr
>= 2) {
1654 parent
= ctxt
->nodeTab
[ctxt
->nodeNr
- 2];
1656 ns
= xmlSearchNs(ctxt
->myDoc
, parent
, name
);
1659 xmlSetNs(ctxt
->node
, ns
);
1664 * @ctx: the user data (XML parser context)
1666 * Get the current element namespace.
1668 * Returns the xmlNsPtr or NULL if none
1672 getNamespace(void *ctx
)
1674 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1678 xmlGenericError(xmlGenericErrorContext
, "SAX.getNamespace()\n");
1680 ret
= ctxt
->node
->ns
;
1686 * @ctx: the user data (XML parser context)
1687 * @namespace: the namespace to check against
1689 * Check that the current element namespace is the same as the
1690 * one read upon parsing.
1692 * Returns 1 if true 0 otherwise
1696 checkNamespace(void *ctx
, xmlChar
*namespace)
1698 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1699 xmlNodePtr cur
= ctxt
->node
;
1702 xmlGenericError(xmlGenericErrorContext
,
1703 "SAX.checkNamespace(%s)\n", namespace);
1707 * Check that the Name in the ETag is the same as in the STag.
1709 if (namespace == NULL
) {
1710 if ((cur
->ns
!= NULL
) && (cur
->ns
->prefix
!= NULL
)) {
1711 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->error
!= NULL
))
1712 ctxt
->sax
->error(ctxt
,
1713 "End tags for %s don't hold the namespace %s\n",
1714 cur
->name
, cur
->ns
->prefix
);
1715 ctxt
->wellFormed
= 0;
1718 if ((cur
->ns
== NULL
) || (cur
->ns
->prefix
== NULL
)) {
1719 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->error
!= NULL
))
1720 ctxt
->sax
->error(ctxt
,
1721 "End tags %s holds a prefix %s not used by the open tag\n",
1722 cur
->name
, namespace);
1723 ctxt
->wellFormed
= 0;
1724 } else if (!xmlStrEqual(namespace, cur
->ns
->prefix
)) {
1725 if ((ctxt
->sax
!= NULL
) && (ctxt
->sax
->error
!= NULL
))
1726 ctxt
->sax
->error(ctxt
,
1727 "Start and End tags for %s don't use the same namespaces: %s and %s\n",
1728 cur
->name
, cur
->ns
->prefix
, namespace);
1729 ctxt
->wellFormed
= 0;
1738 * @ctx: the user data (XML parser context)
1739 * @href: the namespace associated URN
1740 * @prefix: the namespace prefix
1742 * A namespace has been parsed.
1745 namespaceDecl(void *ctx
, const xmlChar
*href
, const xmlChar
*prefix
)
1747 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1750 xmlGenericError(xmlGenericErrorContext
,
1751 "SAX.namespaceDecl(%s, NULL)\n", href
);
1753 xmlGenericError(xmlGenericErrorContext
,
1754 "SAX.namespaceDecl(%s, %s)\n", href
, prefix
);
1756 xmlNewNs(ctxt
->node
, href
, prefix
);
1761 * @ctx: the user data (XML parser context)
1762 * @value: the comment content
1764 * A comment has been parsed.
1767 comment(void *ctx
, const xmlChar
*value
)
1769 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1771 xmlNodePtr parent
= ctxt
->node
;
1774 xmlGenericError(xmlGenericErrorContext
, "SAX.comment(%s)\n", value
);
1776 ret
= xmlNewDocComment(ctxt
->myDoc
, value
);
1777 if (ret
== NULL
) return;
1779 if (ctxt
->inSubset
== 1) {
1780 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->intSubset
, ret
);
1782 } else if (ctxt
->inSubset
== 2) {
1783 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
->extSubset
, ret
);
1786 if ((ctxt
->myDoc
->children
== NULL
) || (parent
== NULL
)) {
1787 #ifdef DEBUG_SAX_TREE
1788 xmlGenericError(xmlGenericErrorContext
,
1789 "Setting comment as root\n");
1791 xmlAddChild((xmlNodePtr
) ctxt
->myDoc
, (xmlNodePtr
) ret
);
1794 if (parent
->type
== XML_ELEMENT_NODE
) {
1795 #ifdef DEBUG_SAX_TREE
1796 xmlGenericError(xmlGenericErrorContext
,
1797 "adding comment child to %s\n", parent
->name
);
1799 xmlAddChild(parent
, ret
);
1801 #ifdef DEBUG_SAX_TREE
1802 xmlGenericError(xmlGenericErrorContext
,
1803 "adding comment sibling to ");
1804 xmlDebugDumpOneNode(stderr
, parent
, 0);
1806 xmlAddSibling(parent
, ret
);
1812 * @ctx: the user data (XML parser context)
1813 * @value: The pcdata content
1814 * @len: the block length
1816 * called when a pcdata block has been parsed
1819 cdataBlock(void *ctx
, const xmlChar
*value
, int len
)
1821 xmlParserCtxtPtr ctxt
= (xmlParserCtxtPtr
) ctx
;
1822 xmlNodePtr ret
, lastChild
;
1825 xmlGenericError(xmlGenericErrorContext
,
1826 "SAX.pcdata(%.10s, %d)\n", value
, len
);
1828 lastChild
= xmlGetLastChild(ctxt
->node
);
1829 #ifdef DEBUG_SAX_TREE
1830 xmlGenericError(xmlGenericErrorContext
,
1831 "add chars to %s \n", ctxt
->node
->name
);
1833 if ((lastChild
!= NULL
) &&
1834 (lastChild
->type
== XML_CDATA_SECTION_NODE
)) {
1835 xmlTextConcat(lastChild
, value
, len
);
1837 ret
= xmlNewCDataBlock(ctxt
->myDoc
, value
, len
);
1838 xmlAddChild(ctxt
->node
, ret
);
1843 * initxmlDefaultSAXHandler:
1844 * @hdlr: the SAX handler
1845 * @warning: flag if non-zero sets the handler warning procedure
1847 * Initialize the default XML SAX handler
1850 initxmlDefaultSAXHandler(xmlSAXHandler
*hdlr
, int warning
)
1852 if(hdlr
->initialized
== 1)
1855 hdlr
->internalSubset
= internalSubset
;
1856 hdlr
->externalSubset
= externalSubset
;
1857 hdlr
->isStandalone
= isStandalone
;
1858 hdlr
->hasInternalSubset
= hasInternalSubset
;
1859 hdlr
->hasExternalSubset
= hasExternalSubset
;
1860 hdlr
->resolveEntity
= resolveEntity
;
1861 hdlr
->getEntity
= getEntity
;
1862 hdlr
->getParameterEntity
= getParameterEntity
;
1863 hdlr
->entityDecl
= entityDecl
;
1864 hdlr
->attributeDecl
= attributeDecl
;
1865 hdlr
->elementDecl
= elementDecl
;
1866 hdlr
->notationDecl
= notationDecl
;
1867 hdlr
->unparsedEntityDecl
= unparsedEntityDecl
;
1868 hdlr
->setDocumentLocator
= setDocumentLocator
;
1869 hdlr
->startDocument
= startDocument
;
1870 hdlr
->endDocument
= endDocument
;
1871 hdlr
->startElement
= startElement
;
1872 hdlr
->endElement
= endElement
;
1873 hdlr
->reference
= reference
;
1874 hdlr
->characters
= characters
;
1875 hdlr
->cdataBlock
= cdataBlock
;
1876 hdlr
->ignorableWhitespace
= characters
;
1877 hdlr
->processingInstruction
= processingInstruction
;
1878 hdlr
->comment
= comment
;
1879 /* if (xmlGetWarningsDefaultValue == 0) */
1881 hdlr
->warning
= NULL
;
1883 hdlr
->warning
= xmlParserWarning
;
1884 hdlr
->error
= xmlParserError
;
1885 hdlr
->fatalError
= xmlParserError
;
1887 hdlr
->initialized
= 1;
1891 * xmlDefaultSAXHandlerInit:
1893 * Initialize the default SAX handler
1896 xmlDefaultSAXHandlerInit(void)
1898 initxmlDefaultSAXHandler(&xmlDefaultSAXHandler
, xmlGetWarningsDefaultValue
);
1901 #ifdef LIBXML_HTML_ENABLED
1904 * inithtmlDefaultSAXHandler:
1905 * @hdlr: the SAX handler
1907 * Initialize the default HTML SAX handler
1910 inithtmlDefaultSAXHandler(xmlSAXHandler
*hdlr
)
1912 if(hdlr
->initialized
== 1)
1915 hdlr
->internalSubset
= internalSubset
;
1916 hdlr
->externalSubset
= NULL
;
1917 hdlr
->isStandalone
= NULL
;
1918 hdlr
->hasInternalSubset
= NULL
;
1919 hdlr
->hasExternalSubset
= NULL
;
1920 hdlr
->resolveEntity
= NULL
;
1921 hdlr
->getEntity
= getEntity
;
1922 hdlr
->getParameterEntity
= NULL
;
1923 hdlr
->entityDecl
= NULL
;
1924 hdlr
->attributeDecl
= NULL
;
1925 hdlr
->elementDecl
= NULL
;
1926 hdlr
->notationDecl
= NULL
;
1927 hdlr
->unparsedEntityDecl
= NULL
;
1928 hdlr
->setDocumentLocator
= setDocumentLocator
;
1929 hdlr
->startDocument
= startDocument
;
1930 hdlr
->endDocument
= endDocument
;
1931 hdlr
->startElement
= startElement
;
1932 hdlr
->endElement
= endElement
;
1933 hdlr
->reference
= NULL
;
1934 hdlr
->characters
= characters
;
1935 hdlr
->cdataBlock
= cdataBlock
;
1936 hdlr
->ignorableWhitespace
= ignorableWhitespace
;
1937 hdlr
->processingInstruction
= NULL
;
1938 hdlr
->comment
= comment
;
1939 hdlr
->warning
= xmlParserWarning
;
1940 hdlr
->error
= xmlParserError
;
1941 hdlr
->fatalError
= xmlParserError
;
1943 hdlr
->initialized
= 1;
1947 * htmlDefaultSAXHandlerInit:
1949 * Initialize the default SAX handler
1952 htmlDefaultSAXHandlerInit(void)
1954 inithtmlDefaultSAXHandler(&htmlDefaultSAXHandler
);
1957 #endif /* LIBXML_HTML_ENABLED */
1959 #ifdef LIBXML_DOCB_ENABLED
1962 * initdocbDefaultSAXHandler:
1963 * @hdlr: the SAX handler
1965 * Initialize the default DocBook SAX handler
1968 initdocbDefaultSAXHandler(xmlSAXHandler
*hdlr
)
1970 if(hdlr
->initialized
== 1)
1973 hdlr
->internalSubset
= internalSubset
;
1974 hdlr
->externalSubset
= NULL
;
1975 hdlr
->isStandalone
= isStandalone
;
1976 hdlr
->hasInternalSubset
= hasInternalSubset
;
1977 hdlr
->hasExternalSubset
= hasExternalSubset
;
1978 hdlr
->resolveEntity
= resolveEntity
;
1979 hdlr
->getEntity
= getEntity
;
1980 hdlr
->getParameterEntity
= NULL
;
1981 hdlr
->entityDecl
= entityDecl
;
1982 hdlr
->attributeDecl
= NULL
;
1983 hdlr
->elementDecl
= NULL
;
1984 hdlr
->notationDecl
= NULL
;
1985 hdlr
->unparsedEntityDecl
= NULL
;
1986 hdlr
->setDocumentLocator
= setDocumentLocator
;
1987 hdlr
->startDocument
= startDocument
;
1988 hdlr
->endDocument
= endDocument
;
1989 hdlr
->startElement
= startElement
;
1990 hdlr
->endElement
= endElement
;
1991 hdlr
->reference
= reference
;
1992 hdlr
->characters
= characters
;
1993 hdlr
->cdataBlock
= NULL
;
1994 hdlr
->ignorableWhitespace
= ignorableWhitespace
;
1995 hdlr
->processingInstruction
= NULL
;
1996 hdlr
->comment
= comment
;
1997 hdlr
->warning
= xmlParserWarning
;
1998 hdlr
->error
= xmlParserError
;
1999 hdlr
->fatalError
= xmlParserError
;
2001 hdlr
->initialized
= 1;
2005 * docbDefaultSAXHandlerInit:
2007 * Initialize the default SAX handler
2010 docbDefaultSAXHandlerInit(void)
2012 initdocbDefaultSAXHandler(&docbDefaultSAXHandler
);
2015 #endif /* LIBXML_DOCB_ENABLED */