Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > DoxygenSAX2.c
Go to the documentation of this file.
00001 /* 00002 * SAX2.c : Default SAX2 handler to build a tree. 00003 * 00004 * See Copyright for the status of this software. 00005 * 00006 * Daniel Veillard <daniel@veillard.com> 00007 */ 00008 00009 00010 #define IN_LIBXML 00011 #include "libxml.h" 00012 #include <stdlib.h> 00013 #include <string.h> 00014 #include <limits.h> 00015 #include <libxml/xmlmemory.h> 00016 #include <libxml/tree.h> 00017 #include <libxml/parser.h> 00018 #include <libxml/parserInternals.h> 00019 #include <libxml/valid.h> 00020 #include <libxml/entities.h> 00021 #include <libxml/xmlerror.h> 00022 #include <libxml/debugXML.h> 00023 #include <libxml/xmlIO.h> 00024 #include <libxml/SAX.h> 00025 #include <libxml/uri.h> 00026 #include <libxml/valid.h> 00027 #include <libxml/HTMLtree.h> 00028 #include <libxml/globals.h> 00029 00030 /* Define SIZE_T_MAX unless defined through <limits.h>. */ 00031 #ifndef SIZE_T_MAX 00032 # define SIZE_T_MAX ((size_t)-1) 00033 #endif /* !SIZE_T_MAX */ 00034 00035 /* #define DEBUG_SAX2 */ 00036 /* #define DEBUG_SAX2_TREE */ 00037 00048 #define TODO \ 00049 xmlGenericError(xmlGenericErrorContext, \ 00050 "Unimplemented block at %s:%d\n", \ 00051 __FILE__, __LINE__); 00052 00053 /* 00054 * xmlSAX2ErrMemory: 00055 * @ctxt: an XML validation parser context 00056 * @msg: a string to accompany the error message 00057 */ 00058 static void 00059 xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) { 00060 if (ctxt != NULL) { 00061 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 00062 ctxt->sax->error(ctxt->userData, "%s: out of memory\n", msg); 00063 ctxt->errNo = XML_ERR_NO_MEMORY; 00064 ctxt->instate = XML_PARSER_EOF; 00065 ctxt->disableSAX = 1; 00066 } 00067 } 00068 00079 static void 00080 xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error, 00081 const char *msg, const char *str1, const char *str2) 00082 { 00083 xmlStructuredErrorFunc schannel = NULL; 00084 00085 if ((ctxt != NULL) && (ctxt->disableSAX != 0) && 00086 (ctxt->instate == XML_PARSER_EOF)) 00087 return; 00088 if (ctxt != NULL) { 00089 ctxt->errNo = error; 00090 if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC)) 00091 schannel = ctxt->sax->serror; 00092 __xmlRaiseError(schannel, 00093 ctxt->vctxt.error, ctxt->vctxt.userData, 00094 ctxt, NULL, XML_FROM_DTD, error, 00095 XML_ERR_ERROR, NULL, 0, (const char *) str1, 00096 (const char *) str2, NULL, 0, 0, 00097 msg, (const char *) str1, (const char *) str2); 00098 ctxt->valid = 0; 00099 } else { 00100 __xmlRaiseError(schannel, 00101 NULL, NULL, 00102 ctxt, NULL, XML_FROM_DTD, error, 00103 XML_ERR_ERROR, NULL, 0, (const char *) str1, 00104 (const char *) str2, NULL, 0, 0, 00105 msg, (const char *) str1, (const char *) str2); 00106 } 00107 } 00108 00119 static void 00120 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, 00121 const char *msg, const xmlChar *str1, const xmlChar *str2) 00122 { 00123 if ((ctxt != NULL) && (ctxt->disableSAX != 0) && 00124 (ctxt->instate == XML_PARSER_EOF)) 00125 return; 00126 if (ctxt != NULL) 00127 ctxt->errNo = error; 00128 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error, 00129 XML_ERR_FATAL, NULL, 0, 00130 (const char *) str1, (const char *) str2, 00131 NULL, 0, 0, msg, str1, str2); 00132 if (ctxt != NULL) { 00133 ctxt->wellFormed = 0; 00134 ctxt->valid = 0; 00135 if (ctxt->recovery == 0) 00136 ctxt->disableSAX = 1; 00137 } 00138 } 00139 00150 static void 00151 xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, 00152 const char *msg, const xmlChar *str1) 00153 { 00154 if ((ctxt != NULL) && (ctxt->disableSAX != 0) && 00155 (ctxt->instate == XML_PARSER_EOF)) 00156 return; 00157 if (ctxt != NULL) 00158 ctxt->errNo = error; 00159 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error, 00160 XML_ERR_WARNING, NULL, 0, 00161 (const char *) str1, NULL, 00162 NULL, 0, 0, msg, str1); 00163 } 00164 00175 static void 00176 xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, 00177 const char *msg, const xmlChar *str1, const xmlChar *str2) 00178 { 00179 if ((ctxt != NULL) && (ctxt->disableSAX != 0) && 00180 (ctxt->instate == XML_PARSER_EOF)) 00181 return; 00182 if (ctxt != NULL) 00183 ctxt->errNo = error; 00184 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error, 00185 XML_ERR_ERROR, NULL, 0, 00186 (const char *) str1, (const char *) str2, 00187 NULL, 0, 0, msg, str1, str2); 00188 } 00189 00199 static void 00200 xmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, 00201 const char *msg, const xmlChar *str1, const xmlChar *str2) 00202 { 00203 if ((ctxt != NULL) && (ctxt->disableSAX != 0) && 00204 (ctxt->instate == XML_PARSER_EOF)) 00205 return; 00206 if (ctxt != NULL) 00207 ctxt->errNo = error; 00208 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error, 00209 XML_ERR_WARNING, NULL, 0, 00210 (const char *) str1, (const char *) str2, 00211 NULL, 0, 0, msg, str1, str2); 00212 } 00213 00222 const xmlChar * 00223 xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED) 00224 { 00225 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ 00226 return(NULL); 00227 } 00228 00238 const xmlChar * 00239 xmlSAX2GetSystemId(void *ctx) 00240 { 00241 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00242 if ((ctx == NULL) || (ctxt->input == NULL)) return(NULL); 00243 return((const xmlChar *) ctxt->input->filename); 00244 } 00245 00254 int 00255 xmlSAX2GetLineNumber(void *ctx) 00256 { 00257 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00258 if ((ctx == NULL) || (ctxt->input == NULL)) return(0); 00259 return(ctxt->input->line); 00260 } 00261 00270 int 00271 xmlSAX2GetColumnNumber(void *ctx) 00272 { 00273 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00274 if ((ctx == NULL) || (ctxt->input == NULL)) return(0); 00275 return(ctxt->input->col); 00276 } 00277 00286 int 00287 xmlSAX2IsStandalone(void *ctx) 00288 { 00289 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00290 if ((ctx == NULL) || (ctxt->myDoc == NULL)) return(0); 00291 return(ctxt->myDoc->standalone == 1); 00292 } 00293 00302 int 00303 xmlSAX2HasInternalSubset(void *ctx) 00304 { 00305 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00306 if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0); 00307 return(ctxt->myDoc->intSubset != NULL); 00308 } 00309 00318 int 00319 xmlSAX2HasExternalSubset(void *ctx) 00320 { 00321 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00322 if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0); 00323 return(ctxt->myDoc->extSubset != NULL); 00324 } 00325 00335 void 00336 xmlSAX2InternalSubset(void *ctx, const xmlChar *name, 00337 const xmlChar *ExternalID, const xmlChar *SystemID) 00338 { 00339 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00340 xmlDtdPtr dtd; 00341 if (ctx == NULL) return; 00342 #ifdef DEBUG_SAX 00343 xmlGenericError(xmlGenericErrorContext, 00344 "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n", 00345 name, ExternalID, SystemID); 00346 #endif 00347 00348 if (ctxt->myDoc == NULL) 00349 return; 00350 dtd = xmlGetIntSubset(ctxt->myDoc); 00351 if (dtd != NULL) { 00352 if (ctxt->html) 00353 return; 00354 xmlUnlinkNode((xmlNodePtr) dtd); 00355 xmlFreeDtd(dtd); 00356 ctxt->myDoc->intSubset = NULL; 00357 } 00358 ctxt->myDoc->intSubset = 00359 xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID); 00360 if (ctxt->myDoc->intSubset == NULL) 00361 xmlSAX2ErrMemory(ctxt, "xmlSAX2InternalSubset"); 00362 } 00363 00373 void 00374 xmlSAX2ExternalSubset(void *ctx, const xmlChar *name, 00375 const xmlChar *ExternalID, const xmlChar *SystemID) 00376 { 00377 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00378 if (ctx == NULL) return; 00379 #ifdef DEBUG_SAX 00380 xmlGenericError(xmlGenericErrorContext, 00381 "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n", 00382 name, ExternalID, SystemID); 00383 #endif 00384 if (((ExternalID != NULL) || (SystemID != NULL)) && 00385 (((ctxt->validate) || (ctxt->loadsubset != 0)) && 00386 (ctxt->wellFormed && ctxt->myDoc))) { 00387 /* 00388 * Try to fetch and parse the external subset. 00389 */ 00390 xmlParserInputPtr oldinput; 00391 int oldinputNr; 00392 int oldinputMax; 00393 xmlParserInputPtr *oldinputTab; 00394 xmlParserInputPtr input = NULL; 00395 xmlCharEncoding enc; 00396 int oldcharset; 00397 00398 /* 00399 * Ask the Entity resolver to load the damn thing 00400 */ 00401 if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL)) 00402 input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID, 00403 SystemID); 00404 if (input == NULL) { 00405 return; 00406 } 00407 00408 xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID); 00409 00410 /* 00411 * make sure we won't destroy the main document context 00412 */ 00413 oldinput = ctxt->input; 00414 oldinputNr = ctxt->inputNr; 00415 oldinputMax = ctxt->inputMax; 00416 oldinputTab = ctxt->inputTab; 00417 oldcharset = ctxt->charset; 00418 00419 ctxt->inputTab = (xmlParserInputPtr *) 00420 xmlMalloc(5 * sizeof(xmlParserInputPtr)); 00421 if (ctxt->inputTab == NULL) { 00422 xmlSAX2ErrMemory(ctxt, "xmlSAX2ExternalSubset"); 00423 ctxt->input = oldinput; 00424 ctxt->inputNr = oldinputNr; 00425 ctxt->inputMax = oldinputMax; 00426 ctxt->inputTab = oldinputTab; 00427 ctxt->charset = oldcharset; 00428 return; 00429 } 00430 ctxt->inputNr = 0; 00431 ctxt->inputMax = 5; 00432 ctxt->input = NULL; 00433 xmlPushInput(ctxt, input); 00434 00435 /* 00436 * On the fly encoding conversion if needed 00437 */ 00438 if (ctxt->input->length >= 4) { 00439 enc = xmlDetectCharEncoding(ctxt->input->cur, 4); 00440 xmlSwitchEncoding(ctxt, enc); 00441 } 00442 00443 if (input->filename == NULL) 00444 input->filename = (char *) xmlCanonicPath(SystemID); 00445 input->line = 1; 00446 input->col = 1; 00447 input->base = ctxt->input->cur; 00448 input->cur = ctxt->input->cur; 00449 input->free = NULL; 00450 00451 /* 00452 * let's parse that entity knowing it's an external subset. 00453 */ 00454 xmlParseExternalSubset(ctxt, ExternalID, SystemID); 00455 00456 /* 00457 * Free up the external entities 00458 */ 00459 00460 while (ctxt->inputNr > 1) 00461 xmlPopInput(ctxt); 00462 xmlFreeInputStream(ctxt->input); 00463 xmlFree(ctxt->inputTab); 00464 00465 /* 00466 * Restore the parsing context of the main entity 00467 */ 00468 ctxt->input = oldinput; 00469 ctxt->inputNr = oldinputNr; 00470 ctxt->inputMax = oldinputMax; 00471 ctxt->inputTab = oldinputTab; 00472 ctxt->charset = oldcharset; 00473 /* ctxt->wellFormed = oldwellFormed; */ 00474 } 00475 } 00476 00491 xmlParserInputPtr 00492 xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId) 00493 { 00494 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00495 xmlParserInputPtr ret; 00496 xmlChar *URI; 00497 const char *base = NULL; 00498 00499 if (ctx == NULL) return(NULL); 00500 if (ctxt->input != NULL) 00501 base = ctxt->input->filename; 00502 if (base == NULL) 00503 base = ctxt->directory; 00504 00505 URI = xmlBuildURI(systemId, (const xmlChar *) base); 00506 00507 #ifdef DEBUG_SAX 00508 xmlGenericError(xmlGenericErrorContext, 00509 "SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId, systemId); 00510 #endif 00511 00512 ret = xmlLoadExternalEntity((const char *) URI, 00513 (const char *) publicId, ctxt); 00514 if (URI != NULL) 00515 xmlFree(URI); 00516 return(ret); 00517 } 00518 00528 xmlEntityPtr 00529 xmlSAX2GetEntity(void *ctx, const xmlChar *name) 00530 { 00531 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00532 xmlEntityPtr ret = NULL; 00533 00534 if (ctx == NULL) return(NULL); 00535 #ifdef DEBUG_SAX 00536 xmlGenericError(xmlGenericErrorContext, 00537 "SAX.xmlSAX2GetEntity(%s)\n", name); 00538 #endif 00539 00540 if (ctxt->inSubset == 0) { 00541 ret = xmlGetPredefinedEntity(name); 00542 if (ret != NULL) 00543 return(ret); 00544 } 00545 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1)) { 00546 if (ctxt->inSubset == 2) { 00547 ctxt->myDoc->standalone = 0; 00548 ret = xmlGetDocEntity(ctxt->myDoc, name); 00549 ctxt->myDoc->standalone = 1; 00550 } else { 00551 ret = xmlGetDocEntity(ctxt->myDoc, name); 00552 if (ret == NULL) { 00553 ctxt->myDoc->standalone = 0; 00554 ret = xmlGetDocEntity(ctxt->myDoc, name); 00555 if (ret != NULL) { 00556 xmlFatalErrMsg(ctxt, XML_ERR_NOT_STANDALONE, 00557 "Entity(%s) document marked standalone but requires external subset\n", 00558 name, NULL); 00559 } 00560 ctxt->myDoc->standalone = 1; 00561 } 00562 } 00563 } else { 00564 ret = xmlGetDocEntity(ctxt->myDoc, name); 00565 } 00566 if ((ret != NULL) && 00567 ((ctxt->validate) || (ctxt->replaceEntities)) && 00568 (ret->children == NULL) && 00569 (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) { 00570 int val; 00571 00572 /* 00573 * for validation purposes we really need to fetch and 00574 * parse the external entity 00575 */ 00576 xmlNodePtr children; 00577 00578 val = xmlParseCtxtExternalEntity(ctxt, ret->URI, 00579 ret->ExternalID, &children); 00580 if (val == 0) { 00581 xmlAddChildList((xmlNodePtr) ret, children); 00582 } else { 00583 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING, 00584 "Failure to process entity %s\n", name, NULL); 00585 ctxt->validate = 0; 00586 return(NULL); 00587 } 00588 ret->owner = 1; 00589 if (ret->checked == 0) 00590 ret->checked = 1; 00591 } 00592 return(ret); 00593 } 00594 00604 xmlEntityPtr 00605 xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name) 00606 { 00607 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00608 xmlEntityPtr ret; 00609 00610 if (ctx == NULL) return(NULL); 00611 #ifdef DEBUG_SAX 00612 xmlGenericError(xmlGenericErrorContext, 00613 "SAX.xmlSAX2GetParameterEntity(%s)\n", name); 00614 #endif 00615 00616 ret = xmlGetParameterEntity(ctxt->myDoc, name); 00617 return(ret); 00618 } 00619 00620 00632 void 00633 xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type, 00634 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) 00635 { 00636 xmlEntityPtr ent; 00637 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00638 00639 if (ctx == NULL) return; 00640 #ifdef DEBUG_SAX 00641 xmlGenericError(xmlGenericErrorContext, 00642 "SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n", 00643 name, type, publicId, systemId, content); 00644 #endif 00645 if (ctxt->inSubset == 1) { 00646 ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId, 00647 systemId, content); 00648 if ((ent == NULL) && (ctxt->pedantic)) 00649 xmlWarnMsg(ctxt, XML_WAR_ENTITY_REDEFINED, 00650 "Entity(%s) already defined in the internal subset\n", 00651 name); 00652 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 00653 xmlChar *URI; 00654 const char *base = NULL; 00655 00656 if (ctxt->input != NULL) 00657 base = ctxt->input->filename; 00658 if (base == NULL) 00659 base = ctxt->directory; 00660 00661 URI = xmlBuildURI(systemId, (const xmlChar *) base); 00662 ent->URI = URI; 00663 } 00664 } else if (ctxt->inSubset == 2) { 00665 ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId, 00666 systemId, content); 00667 if ((ent == NULL) && (ctxt->pedantic) && 00668 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 00669 ctxt->sax->warning(ctxt->userData, 00670 "Entity(%s) already defined in the external subset\n", name); 00671 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 00672 xmlChar *URI; 00673 const char *base = NULL; 00674 00675 if (ctxt->input != NULL) 00676 base = ctxt->input->filename; 00677 if (base == NULL) 00678 base = ctxt->directory; 00679 00680 URI = xmlBuildURI(systemId, (const xmlChar *) base); 00681 ent->URI = URI; 00682 } 00683 } else { 00684 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING, 00685 "SAX.xmlSAX2EntityDecl(%s) called while not in subset\n", 00686 name, NULL); 00687 } 00688 } 00689 00702 void 00703 xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname, 00704 int type, int def, const xmlChar *defaultValue, 00705 xmlEnumerationPtr tree) 00706 { 00707 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00708 xmlAttributePtr attr; 00709 xmlChar *name = NULL, *prefix = NULL; 00710 00711 if ((ctxt == NULL) || (ctxt->myDoc == NULL)) 00712 return; 00713 00714 #ifdef DEBUG_SAX 00715 xmlGenericError(xmlGenericErrorContext, 00716 "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n", 00717 elem, fullname, type, def, defaultValue); 00718 #endif 00719 if ((xmlStrEqual(fullname, BAD_CAST "xml:id")) && 00720 (type != XML_ATTRIBUTE_ID)) { 00721 /* 00722 * Raise the error but keep the validity flag 00723 */ 00724 int tmp = ctxt->valid; 00725 xmlErrValid(ctxt, XML_DTD_XMLID_TYPE, 00726 "xml:id : attribute type should be ID\n", NULL, NULL); 00727 ctxt->valid = tmp; 00728 } 00729 /* TODO: optimize name/prefix allocation */ 00730 name = xmlSplitQName(ctxt, fullname, &prefix); 00731 ctxt->vctxt.valid = 1; 00732 if (ctxt->inSubset == 1) 00733 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem, 00734 name, prefix, (xmlAttributeType) type, 00735 (xmlAttributeDefault) def, defaultValue, tree); 00736 else if (ctxt->inSubset == 2) 00737 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem, 00738 name, prefix, (xmlAttributeType) type, 00739 (xmlAttributeDefault) def, defaultValue, tree); 00740 else { 00741 xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR, 00742 "SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n", 00743 name, NULL); 00744 xmlFreeEnumeration(tree); 00745 return; 00746 } 00747 #ifdef LIBXML_VALID_ENABLED 00748 if (ctxt->vctxt.valid == 0) 00749 ctxt->valid = 0; 00750 if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) && 00751 (ctxt->myDoc->intSubset != NULL)) 00752 ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc, 00753 attr); 00754 #endif /* LIBXML_VALID_ENABLED */ 00755 if (prefix != NULL) 00756 xmlFree(prefix); 00757 if (name != NULL) 00758 xmlFree(name); 00759 } 00760 00770 void 00771 xmlSAX2ElementDecl(void *ctx, const xmlChar * name, int type, 00772 xmlElementContentPtr content) 00773 { 00774 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00775 xmlElementPtr elem = NULL; 00776 00777 if ((ctxt == NULL) || (ctxt->myDoc == NULL)) 00778 return; 00779 00780 #ifdef DEBUG_SAX 00781 xmlGenericError(xmlGenericErrorContext, 00782 "SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name, type); 00783 #endif 00784 00785 if (ctxt->inSubset == 1) 00786 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, 00787 name, (xmlElementTypeVal) type, content); 00788 else if (ctxt->inSubset == 2) 00789 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, 00790 name, (xmlElementTypeVal) type, content); 00791 else { 00792 xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR, 00793 "SAX.xmlSAX2ElementDecl(%s) called while not in subset\n", 00794 name, NULL); 00795 return; 00796 } 00797 #ifdef LIBXML_VALID_ENABLED 00798 if (elem == NULL) 00799 ctxt->valid = 0; 00800 if (ctxt->validate && ctxt->wellFormed && 00801 ctxt->myDoc && ctxt->myDoc->intSubset) 00802 ctxt->valid &= 00803 xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem); 00804 #endif /* LIBXML_VALID_ENABLED */ 00805 } 00806 00816 void 00817 xmlSAX2NotationDecl(void *ctx, const xmlChar *name, 00818 const xmlChar *publicId, const xmlChar *systemId) 00819 { 00820 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00821 xmlNotationPtr nota = NULL; 00822 00823 if ((ctxt == NULL) || (ctxt->myDoc == NULL)) 00824 return; 00825 00826 #ifdef DEBUG_SAX 00827 xmlGenericError(xmlGenericErrorContext, 00828 "SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name, publicId, systemId); 00829 #endif 00830 00831 if ((publicId == NULL) && (systemId == NULL)) { 00832 xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING, 00833 "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n", 00834 name, NULL); 00835 return; 00836 } else if (ctxt->inSubset == 1) 00837 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name, 00838 publicId, systemId); 00839 else if (ctxt->inSubset == 2) 00840 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name, 00841 publicId, systemId); 00842 else { 00843 xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING, 00844 "SAX.xmlSAX2NotationDecl(%s) called while not in subset\n", 00845 name, NULL); 00846 return; 00847 } 00848 #ifdef LIBXML_VALID_ENABLED 00849 if (nota == NULL) ctxt->valid = 0; 00850 if ((ctxt->validate) && (ctxt->wellFormed) && 00851 (ctxt->myDoc->intSubset != NULL)) 00852 ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc, 00853 nota); 00854 #endif /* LIBXML_VALID_ENABLED */ 00855 } 00856 00867 void 00868 xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name, 00869 const xmlChar *publicId, const xmlChar *systemId, 00870 const xmlChar *notationName) 00871 { 00872 xmlEntityPtr ent; 00873 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00874 if (ctx == NULL) return; 00875 #ifdef DEBUG_SAX 00876 xmlGenericError(xmlGenericErrorContext, 00877 "SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n", 00878 name, publicId, systemId, notationName); 00879 #endif 00880 if (ctxt->inSubset == 1) { 00881 ent = xmlAddDocEntity(ctxt->myDoc, name, 00882 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY, 00883 publicId, systemId, notationName); 00884 if ((ent == NULL) && (ctxt->pedantic) && 00885 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 00886 ctxt->sax->warning(ctxt->userData, 00887 "Entity(%s) already defined in the internal subset\n", name); 00888 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 00889 xmlChar *URI; 00890 const char *base = NULL; 00891 00892 if (ctxt->input != NULL) 00893 base = ctxt->input->filename; 00894 if (base == NULL) 00895 base = ctxt->directory; 00896 00897 URI = xmlBuildURI(systemId, (const xmlChar *) base); 00898 ent->URI = URI; 00899 } 00900 } else if (ctxt->inSubset == 2) { 00901 ent = xmlAddDtdEntity(ctxt->myDoc, name, 00902 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY, 00903 publicId, systemId, notationName); 00904 if ((ent == NULL) && (ctxt->pedantic) && 00905 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 00906 ctxt->sax->warning(ctxt->userData, 00907 "Entity(%s) already defined in the external subset\n", name); 00908 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 00909 xmlChar *URI; 00910 const char *base = NULL; 00911 00912 if (ctxt->input != NULL) 00913 base = ctxt->input->filename; 00914 if (base == NULL) 00915 base = ctxt->directory; 00916 00917 URI = xmlBuildURI(systemId, (const xmlChar *) base); 00918 ent->URI = URI; 00919 } 00920 } else { 00921 xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR, 00922 "SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n", 00923 name, NULL); 00924 } 00925 } 00926 00935 void 00936 xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED) 00937 { 00938 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ 00939 #ifdef DEBUG_SAX 00940 xmlGenericError(xmlGenericErrorContext, 00941 "SAX.xmlSAX2SetDocumentLocator()\n"); 00942 #endif 00943 } 00944 00951 void 00952 xmlSAX2StartDocument(void *ctx) 00953 { 00954 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 00955 xmlDocPtr doc; 00956 00957 if (ctx == NULL) return; 00958 00959 #ifdef DEBUG_SAX 00960 xmlGenericError(xmlGenericErrorContext, 00961 "SAX.xmlSAX2StartDocument()\n"); 00962 #endif 00963 if (ctxt->html) { 00964 #ifdef LIBXML_HTML_ENABLED 00965 if (ctxt->myDoc == NULL) 00966 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL); 00967 ctxt->myDoc->properties = XML_DOC_HTML; 00968 ctxt->myDoc->parseFlags = ctxt->options; 00969 if (ctxt->myDoc == NULL) { 00970 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument"); 00971 return; 00972 } 00973 #else 00974 xmlGenericError(xmlGenericErrorContext, 00975 "libxml2 built without HTML support\n"); 00976 ctxt->errNo = XML_ERR_INTERNAL_ERROR; 00977 ctxt->instate = XML_PARSER_EOF; 00978 ctxt->disableSAX = 1; 00979 return; 00980 #endif 00981 } else { 00982 doc = ctxt->myDoc = xmlNewDoc(ctxt->version); 00983 if (doc != NULL) { 00984 doc->properties = 0; 00985 if (ctxt->options & XML_PARSE_OLD10) 00986 doc->properties |= XML_DOC_OLD10; 00987 doc->parseFlags = ctxt->options; 00988 if (ctxt->encoding != NULL) 00989 doc->encoding = xmlStrdup(ctxt->encoding); 00990 else 00991 doc->encoding = NULL; 00992 doc->standalone = ctxt->standalone; 00993 } else { 00994 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument"); 00995 return; 00996 } 00997 if ((ctxt->dictNames) && (doc != NULL)) { 00998 doc->dict = ctxt->dict; 00999 xmlDictReference(doc->dict); 01000 } 01001 } 01002 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) && 01003 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) { 01004 ctxt->myDoc->URL = xmlPathToURI((const xmlChar *)ctxt->input->filename); 01005 if (ctxt->myDoc->URL == NULL) 01006 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument"); 01007 } 01008 } 01009 01016 void 01017 xmlSAX2EndDocument(void *ctx) 01018 { 01019 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 01020 #ifdef DEBUG_SAX 01021 xmlGenericError(xmlGenericErrorContext, 01022 "SAX.xmlSAX2EndDocument()\n"); 01023 #endif 01024 if (ctx == NULL) return; 01025 #ifdef LIBXML_VALID_ENABLED 01026 if (ctxt->validate && ctxt->wellFormed && 01027 ctxt->myDoc && ctxt->myDoc->intSubset) 01028 ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc); 01029 #endif /* LIBXML_VALID_ENABLED */ 01030 01031 /* 01032 * Grab the encoding if it was added on-the-fly 01033 */ 01034 if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) && 01035 (ctxt->myDoc->encoding == NULL)) { 01036 ctxt->myDoc->encoding = ctxt->encoding; 01037 ctxt->encoding = NULL; 01038 } 01039 if ((ctxt->inputTab != NULL) && 01040 (ctxt->inputNr > 0) && (ctxt->inputTab[0] != NULL) && 01041 (ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) && 01042 (ctxt->myDoc->encoding == NULL)) { 01043 ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding); 01044 } 01045 if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) && 01046 (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) { 01047 ctxt->myDoc->charset = ctxt->charset; 01048 } 01049 } 01050 01051 #if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) 01052 01064 static void 01065 xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname, 01066 const xmlChar *value, const xmlChar *prefix ATTRIBUTE_UNUSED) 01067 { 01068 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 01069 xmlAttrPtr ret; 01070 xmlChar *name; 01071 xmlChar *ns; 01072 xmlChar *nval; 01073 xmlNsPtr namespace; 01074 01075 if (ctxt->html) { 01076 name = xmlStrdup(fullname); 01077 ns = NULL; 01078 namespace = NULL; 01079 } else { 01080 /* 01081 * Split the full name into a namespace prefix and the tag name 01082 */ 01083 name = xmlSplitQName(ctxt, fullname, &ns); 01084 if ((name != NULL) && (name[0] == 0)) { 01085 if (xmlStrEqual(ns, BAD_CAST "xmlns")) { 01086 xmlNsErrMsg(ctxt, XML_ERR_NS_DECL_ERROR, 01087 "invalid namespace declaration '%s'\n", 01088 fullname, NULL); 01089 } else { 01090 xmlNsWarnMsg(ctxt, XML_WAR_NS_COLUMN, 01091 "Avoid attribute ending with ':' like '%s'\n", 01092 fullname, NULL); 01093 } 01094 if (ns != NULL) 01095 xmlFree(ns); 01096 ns = NULL; 01097 xmlFree(name); 01098 name = xmlStrdup(fullname); 01099 } 01100 } 01101 if (name == NULL) { 01102 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement"); 01103 if (ns != NULL) 01104 xmlFree(ns); 01105 return; 01106 } 01107 01108 #ifdef LIBXML_HTML_ENABLED 01109 if ((ctxt->html) && 01110 (value == NULL) && (htmlIsBooleanAttr(fullname))) { 01111 nval = xmlStrdup(fullname); 01112 value = (const xmlChar *) nval; 01113 } else 01114 #endif 01115 { 01116 #ifdef LIBXML_VALID_ENABLED 01117 /* 01118 * Do the last stage of the attribute normalization 01119 * Needed for HTML too: 01120 * http://www.w3.org/TR/html4/types.html#h-6.2 01121 */ 01122 ctxt->vctxt.valid = 1; 01123 nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt, 01124 ctxt->myDoc, ctxt->node, 01125 fullname, value); 01126 if (ctxt->vctxt.valid != 1) { 01127 ctxt->valid = 0; 01128 } 01129 if (nval != NULL) 01130 value = nval; 01131 #else 01132 nval = NULL; 01133 #endif /* LIBXML_VALID_ENABLED */ 01134 } 01135 01136 /* 01137 * Check whether it's a namespace definition 01138 */ 01139 if ((!ctxt->html) && (ns == NULL) && 01140 (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') && 01141 (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) { 01142 xmlNsPtr nsret; 01143 xmlChar *val; 01144 01145 if (!ctxt->replaceEntities) { 01146 ctxt->depth++; 01147 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF, 01148 0,0,0); 01149 ctxt->depth--; 01150 } else { 01151 val = (xmlChar *) value; 01152 } 01153 01154 if (val[0] != 0) { 01155 xmlURIPtr uri; 01156 01157 uri = xmlParseURI((const char *)val); 01158 if (uri == NULL) { 01159 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 01160 ctxt->sax->warning(ctxt->userData, 01161 "xmlns: %s not a valid URI\n", val); 01162 } else { 01163 if (uri->scheme == NULL) { 01164 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 01165 ctxt->sax->warning(ctxt->userData, 01166 "xmlns: URI %s is not absolute\n", val); 01167 } 01168 xmlFreeURI(uri); 01169 } 01170 } 01171 01172 /* a default namespace definition */ 01173 nsret = xmlNewNs(ctxt->node, val, NULL); 01174 01175 #ifdef LIBXML_VALID_ENABLED 01176 /* 01177 * Validate also for namespace decls, they are attributes from 01178 * an XML-1.0 perspective 01179 */ 01180 if (nsret != NULL && ctxt->validate && ctxt->wellFormed && 01181 ctxt->myDoc && ctxt->myDoc->intSubset) 01182 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc, 01183 ctxt->node, prefix, nsret, val); 01184 #endif /* LIBXML_VALID_ENABLED */ 01185 if (name != NULL) 01186 xmlFree(name); 01187 if (nval != NULL) 01188 xmlFree(nval); 01189 if (val != value) 01190 xmlFree(val); 01191 return; 01192 } 01193 if ((!ctxt->html) && 01194 (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') && 01195 (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) { 01196 xmlNsPtr nsret; 01197 xmlChar *val; 01198 01199 if (!ctxt->replaceEntities) { 01200 ctxt->depth++; 01201 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF, 01202 0,0,0); 01203 ctxt->depth--; 01204 if (val == NULL) { 01205 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement"); 01206 xmlFree(ns); 01207 if (name != NULL) 01208 xmlFree(name); 01209 return; 01210 } 01211 } else { 01212 val = (xmlChar *) value; 01213 } 01214 01215 if (val[0] == 0) { 01216 xmlNsErrMsg(ctxt, XML_NS_ERR_EMPTY, 01217 "Empty namespace name for prefix %s\n", name, NULL); 01218 } 01219 if ((ctxt->pedantic != 0) && (val[0] != 0)) { 01220 xmlURIPtr uri; 01221 01222 uri = xmlParseURI((const char *)val); 01223 if (uri == NULL) { 01224 xmlNsWarnMsg(ctxt, XML_WAR_NS_URI, 01225 "xmlns:%s: %s not a valid URI\n", name, value); 01226 } else { 01227 if (uri->scheme == NULL) { 01228 xmlNsWarnMsg(ctxt, XML_WAR_NS_URI_RELATIVE, 01229 "xmlns:%s: URI %s is not absolute\n", name, value); 01230 } 01231 xmlFreeURI(uri); 01232 } 01233 } 01234 01235 /* a standard namespace definition */ 01236 nsret = xmlNewNs(ctxt->node, val, name); 01237 xmlFree(ns); 01238 #ifdef LIBXML_VALID_ENABLED 01239 /* 01240 * Validate also for namespace decls, they are attributes from 01241 * an XML-1.0 perspective 01242 */ 01243 if (nsret != NULL && ctxt->validate && ctxt->wellFormed && 01244 ctxt->myDoc && ctxt->myDoc->intSubset) 01245 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc, 01246 ctxt->node, prefix, nsret, value); 01247 #endif /* LIBXML_VALID_ENABLED */ 01248 if (name != NULL) 01249 xmlFree(name); 01250 if (nval != NULL) 01251 xmlFree(nval); 01252 if (val != value) 01253 xmlFree(val); 01254 return; 01255 } 01256 01257 if (ns != NULL) { 01258 namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns); 01259 01260 if (namespace == NULL) { 01261 xmlNsErrMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE, 01262 "Namespace prefix %s of attribute %s is not defined\n", 01263 ns, name); 01264 } else { 01265 xmlAttrPtr prop; 01266 01267 prop = ctxt->node->properties; 01268 while (prop != NULL) { 01269 if (prop->ns != NULL) { 01270 if ((xmlStrEqual(name, prop->name)) && 01271 ((namespace == prop->ns) || 01272 (xmlStrEqual(namespace->href, prop->ns->href)))) { 01273 xmlNsErrMsg(ctxt, XML_ERR_ATTRIBUTE_REDEFINED, 01274 "Attribute %s in %s redefined\n", 01275 name, namespace->href); 01276 ctxt->wellFormed = 0; 01277 if (ctxt->recovery == 0) ctxt->disableSAX = 1; 01278 goto error; 01279 } 01280 } 01281 prop = prop->next; 01282 } 01283 } 01284 } else { 01285 namespace = NULL; 01286 } 01287 01288 /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */ 01289 ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL); 01290 01291 if (ret != NULL) { 01292 if ((ctxt->replaceEntities == 0) && (!ctxt->html)) { 01293 xmlNodePtr tmp; 01294 01295 ret->children = xmlStringGetNodeList(ctxt->myDoc, value); 01296 tmp = ret->children; 01297 while (tmp != NULL) { 01298 tmp->parent = (xmlNodePtr) ret; 01299 if (tmp->next == NULL) 01300 ret->last = tmp; 01301 tmp = tmp->next; 01302 } 01303 } else if (value != NULL) { 01304 ret->children = xmlNewDocText(ctxt->myDoc, value); 01305 ret->last = ret->children; 01306 if (ret->children != NULL) 01307 ret->children->parent = (xmlNodePtr) ret; 01308 } 01309 } 01310 01311 #ifdef LIBXML_VALID_ENABLED 01312 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed && 01313 ctxt->myDoc && ctxt->myDoc->intSubset) { 01314 01315 /* 01316 * If we don't substitute entities, the validation should be 01317 * done on a value with replaced entities anyway. 01318 */ 01319 if (!ctxt->replaceEntities) { 01320 xmlChar *val; 01321 01322 ctxt->depth++; 01323 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF, 01324 0,0,0); 01325 ctxt->depth--; 01326 01327 if (val == NULL) 01328 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 01329 ctxt->myDoc, ctxt->node, ret, value); 01330 else { 01331 xmlChar *nvalnorm; 01332 01333 /* 01334 * Do the last stage of the attribute normalization 01335 * It need to be done twice ... it's an extra burden related 01336 * to the ability to keep xmlSAX2References in attributes 01337 */ 01338 nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc, 01339 ctxt->node, fullname, val); 01340 if (nvalnorm != NULL) { 01341 xmlFree(val); 01342 val = nvalnorm; 01343 } 01344 01345 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 01346 ctxt->myDoc, ctxt->node, ret, val); 01347 xmlFree(val); 01348 } 01349 } else { 01350 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, 01351 ctxt->node, ret, value); 01352 } 01353 } else 01354 #endif /* LIBXML_VALID_ENABLED */ 01355 if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) && 01356 (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) || 01357 ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) { 01358 /* 01359 * when validating, the ID registration is done at the attribute 01360 * validation level. Otherwise we have to do specific handling here. 01361 */ 01362 if (xmlStrEqual(fullname, BAD_CAST "xml:id")) { 01363 /* 01364 * Add the xml:id value 01365 * 01366 * Open issue: normalization of the value. 01367 */ 01368 if (xmlValidateNCName(value, 1) != 0) { 01369 xmlErrValid(ctxt, XML_DTD_XMLID_VALUE, 01370 "xml:id : attribute value %s is not an NCName\n", 01371 (const char *) value, NULL); 01372 } 01373 xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret); 01374 } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) 01375 xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret); 01376 else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) 01377 xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret); 01378 } 01379 01380 error: 01381 if (nval != NULL) 01382 xmlFree(nval); 01383 if (ns != NULL) 01384 xmlFree(ns); 01385 } 01386 01387 /* 01388 * xmlCheckDefaultedAttributes: 01389 * 01390 * Check defaulted attributes from the DTD 01391 */ 01392 static void 01393 xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name, 01394 const xmlChar *prefix, const xmlChar **atts) { 01395 xmlElementPtr elemDecl; 01396 const xmlChar *att; 01397 int internal = 1; 01398 int i; 01399 01400 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix); 01401 if (elemDecl == NULL) { 01402 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix); 01403 internal = 0; 01404 } 01405 01406 process_external_subset: 01407 01408 if (elemDecl != NULL) { 01409 xmlAttributePtr attr = elemDecl->attributes; 01410 /* 01411 * Check against defaulted attributes from the external subset 01412 * if the document is stamped as standalone 01413 */ 01414 if ((ctxt->myDoc->standalone == 1) && 01415 (ctxt->myDoc->extSubset != NULL) && 01416 (ctxt->validate)) { 01417 while (attr != NULL) { 01418 if ((attr->defaultValue != NULL) && 01419 (xmlGetDtdQAttrDesc(ctxt->myDoc->extSubset, 01420 attr->elem, attr->name, 01421 attr->prefix) == attr) && 01422 (xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset, 01423 attr->elem, attr->name, 01424 attr->prefix) == NULL)) { 01425 xmlChar *fulln; 01426 01427 if (attr->prefix != NULL) { 01428 fulln = xmlStrdup(attr->prefix); 01429 fulln = xmlStrcat(fulln, BAD_CAST ":"); 01430 fulln = xmlStrcat(fulln, attr->name); 01431 } else { 01432 fulln = xmlStrdup(attr->name); 01433 } 01434 if (fulln == NULL) { 01435 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement"); 01436 break; 01437 } 01438 01439 /* 01440 * Check that the attribute is not declared in the 01441 * serialization 01442 */ 01443 att = NULL; 01444 if (atts != NULL) { 01445 i = 0; 01446 att = atts[i]; 01447 while (att != NULL) { 01448 if (xmlStrEqual(att, fulln)) 01449 break; 01450 i += 2; 01451 att = atts[i]; 01452 } 01453 } 01454 if (att == NULL) { 01455 xmlErrValid(ctxt, XML_DTD_STANDALONE_DEFAULTED, 01456 "standalone: attribute %s on %s defaulted from external subset\n", 01457 (const char *)fulln, 01458 (const char *)attr->elem); 01459 } 01460 xmlFree(fulln); 01461 } 01462 attr = attr->nexth; 01463 } 01464 } 01465 01466 /* 01467 * Actually insert defaulted values when needed 01468 */ 01469 attr = elemDecl->attributes; 01470 while (attr != NULL) { 01471 /* 01472 * Make sure that attributes redefinition occuring in the 01473 * internal subset are not overriden by definitions in the 01474 * external subset. 01475 */ 01476 if (attr->defaultValue != NULL) { 01477 /* 01478 * the element should be instantiated in the tree if: 01479 * - this is a namespace prefix 01480 * - the user required for completion in the tree 01481 * like XSLT 01482 * - there isn't already an attribute definition 01483 * in the internal subset overriding it. 01484 */ 01485 if (((attr->prefix != NULL) && 01486 (xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) || 01487 ((attr->prefix == NULL) && 01488 (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) || 01489 (ctxt->loadsubset & XML_COMPLETE_ATTRS)) { 01490 xmlAttributePtr tst; 01491 01492 tst = xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset, 01493 attr->elem, attr->name, 01494 attr->prefix); 01495 if ((tst == attr) || (tst == NULL)) { 01496 xmlChar fn[50]; 01497 xmlChar *fulln; 01498 01499 fulln = xmlBuildQName(attr->name, attr->prefix, fn, 50); 01500 if (fulln == NULL) { 01501 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement"); 01502 return; 01503 } 01504 01505 /* 01506 * Check that the attribute is not declared in the 01507 * serialization 01508 */ 01509 att = NULL; 01510 if (atts != NULL) { 01511 i = 0; 01512 att = atts[i]; 01513 while (att != NULL) { 01514 if (xmlStrEqual(att, fulln)) 01515 break; 01516 i += 2; 01517 att = atts[i]; 01518 } 01519 } 01520 if (att == NULL) { 01521 xmlSAX2AttributeInternal(ctxt, fulln, 01522 attr->defaultValue, prefix); 01523 } 01524 if ((fulln != fn) && (fulln != attr->name)) 01525 xmlFree(fulln); 01526 } 01527 } 01528 } 01529 attr = attr->nexth; 01530 } 01531 if (internal == 1) { 01532 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, 01533 name, prefix); 01534 internal = 0; 01535 goto process_external_subset; 01536 } 01537 } 01538 } 01539 01548 void 01549 xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts) 01550 { 01551 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 01552 xmlNodePtr ret; 01553 xmlNodePtr parent; 01554 xmlNsPtr ns; 01555 xmlChar *name; 01556 xmlChar *prefix; 01557 const xmlChar *att; 01558 const xmlChar *value; 01559 int i; 01560 01561 if ((ctx == NULL) || (fullname == NULL) || (ctxt->myDoc == NULL)) return; 01562 parent = ctxt->node; 01563 #ifdef DEBUG_SAX 01564 xmlGenericError(xmlGenericErrorContext, 01565 "SAX.xmlSAX2StartElement(%s)\n", fullname); 01566 #endif 01567 01568 /* 01569 * First check on validity: 01570 */ 01571 if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) && 01572 ((ctxt->myDoc->intSubset == NULL) || 01573 ((ctxt->myDoc->intSubset->notations == NULL) && 01574 (ctxt->myDoc->intSubset->elements == NULL) && 01575 (ctxt->myDoc->intSubset->attributes == NULL) && 01576 (ctxt->myDoc->intSubset->entities == NULL)))) { 01577 xmlErrValid(ctxt, XML_ERR_NO_DTD, 01578 "Validation failed: no DTD found !", NULL, NULL); 01579 ctxt->validate = 0; 01580 } 01581 01582 01583 /* 01584 * Split the full name into a namespace prefix and the tag name 01585 */ 01586 name = xmlSplitQName(ctxt, fullname, &prefix); 01587 01588 01589 /* 01590 * Note : the namespace resolution is deferred until the end of the 01591 * attributes parsing, since local namespace can be defined as 01592 * an attribute at this level. 01593 */ 01594 ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL); 01595 if (ret == NULL) { 01596 if (prefix != NULL) 01597 xmlFree(prefix); 01598 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement"); 01599 return; 01600 } 01601 if (ctxt->myDoc->children == NULL) { 01602 #ifdef DEBUG_SAX_TREE 01603 xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name); 01604 #endif 01605 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); 01606 } else if (parent == NULL) { 01607 parent = ctxt->myDoc->children; 01608 } 01609 ctxt->nodemem = -1; 01610 if (ctxt->linenumbers) { 01611 if (ctxt->input != NULL) { 01612 if (ctxt->input->line < 65535) 01613 ret->line = (short) ctxt->input->line; 01614 else 01615 ret->line = 65535; 01616 } 01617 } 01618 01619 /* 01620 * We are parsing a new node. 01621 */ 01622 #ifdef DEBUG_SAX_TREE 01623 xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name); 01624 #endif 01625 nodePush(ctxt, ret); 01626 01627 /* 01628 * Link the child element 01629 */ 01630 if (parent != NULL) { 01631 if (parent->type == XML_ELEMENT_NODE) { 01632 #ifdef DEBUG_SAX_TREE 01633 xmlGenericError(xmlGenericErrorContext, 01634 "adding child %s to %s\n", name, parent->name); 01635 #endif 01636 xmlAddChild(parent, ret); 01637 } else { 01638 #ifdef DEBUG_SAX_TREE 01639 xmlGenericError(xmlGenericErrorContext, 01640 "adding sibling %s to ", name); 01641 xmlDebugDumpOneNode(stderr, parent, 0); 01642 #endif 01643 xmlAddSibling(parent, ret); 01644 } 01645 } 01646 01647 /* 01648 * Insert all the defaulted attributes from the DTD especially namespaces 01649 */ 01650 if ((!ctxt->html) && 01651 ((ctxt->myDoc->intSubset != NULL) || 01652 (ctxt->myDoc->extSubset != NULL))) { 01653 xmlCheckDefaultedAttributes(ctxt, name, prefix, atts); 01654 } 01655 01656 /* 01657 * process all the attributes whose name start with "xmlns" 01658 */ 01659 if (atts != NULL) { 01660 i = 0; 01661 att = atts[i++]; 01662 value = atts[i++]; 01663 if (!ctxt->html) { 01664 while ((att != NULL) && (value != NULL)) { 01665 if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') && 01666 (att[3] == 'n') && (att[4] == 's')) 01667 xmlSAX2AttributeInternal(ctxt, att, value, prefix); 01668 01669 att = atts[i++]; 01670 value = atts[i++]; 01671 } 01672 } 01673 } 01674 01675 /* 01676 * Search the namespace, note that since the attributes have been 01677 * processed, the local namespaces are available. 01678 */ 01679 ns = xmlSearchNs(ctxt->myDoc, ret, prefix); 01680 if ((ns == NULL) && (parent != NULL)) 01681 ns = xmlSearchNs(ctxt->myDoc, parent, prefix); 01682 if ((prefix != NULL) && (ns == NULL)) { 01683 ns = xmlNewNs(ret, NULL, prefix); 01684 xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE, 01685 "Namespace prefix %s is not defined\n", 01686 prefix, NULL); 01687 } 01688 01689 /* 01690 * set the namespace node, making sure that if the default namspace 01691 * is unbound on a parent we simply kee it NULL 01692 */ 01693 if ((ns != NULL) && (ns->href != NULL) && 01694 ((ns->href[0] != 0) || (ns->prefix != NULL))) 01695 xmlSetNs(ret, ns); 01696 01697 /* 01698 * process all the other attributes 01699 */ 01700 if (atts != NULL) { 01701 i = 0; 01702 att = atts[i++]; 01703 value = atts[i++]; 01704 if (ctxt->html) { 01705 while (att != NULL) { 01706 xmlSAX2AttributeInternal(ctxt, att, value, NULL); 01707 att = atts[i++]; 01708 value = atts[i++]; 01709 } 01710 } else { 01711 while ((att != NULL) && (value != NULL)) { 01712 if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l') || 01713 (att[3] != 'n') || (att[4] != 's')) 01714 xmlSAX2AttributeInternal(ctxt, att, value, NULL); 01715 01716 /* 01717 * Next ones 01718 */ 01719 att = atts[i++]; 01720 value = atts[i++]; 01721 } 01722 } 01723 } 01724 01725 #ifdef LIBXML_VALID_ENABLED 01726 /* 01727 * If it's the Document root, finish the DTD validation and 01728 * check the document root element for validity 01729 */ 01730 if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) { 01731 int chk; 01732 01733 chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc); 01734 if (chk <= 0) 01735 ctxt->valid = 0; 01736 if (chk < 0) 01737 ctxt->wellFormed = 0; 01738 ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc); 01739 ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1; 01740 } 01741 #endif /* LIBXML_VALID_ENABLED */ 01742 01743 if (prefix != NULL) 01744 xmlFree(prefix); 01745 01746 } 01747 01755 void 01756 xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED) 01757 { 01758 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 01759 xmlParserNodeInfo node_info; 01760 xmlNodePtr cur; 01761 01762 if (ctx == NULL) return; 01763 cur = ctxt->node; 01764 #ifdef DEBUG_SAX 01765 if (name == NULL) 01766 xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(NULL)\n"); 01767 else 01768 xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(%s)\n", name); 01769 #endif 01770 01771 /* Capture end position and add node */ 01772 if (cur != NULL && ctxt->record_info) { 01773 node_info.end_pos = ctxt->input->cur - ctxt->input->base; 01774 node_info.end_line = ctxt->input->line; 01775 node_info.node = cur; 01776 xmlParserAddNodeInfo(ctxt, &node_info); 01777 } 01778 ctxt->nodemem = -1; 01779 01780 #ifdef LIBXML_VALID_ENABLED 01781 if (ctxt->validate && ctxt->wellFormed && 01782 ctxt->myDoc && ctxt->myDoc->intSubset) 01783 ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, 01784 cur); 01785 #endif /* LIBXML_VALID_ENABLED */ 01786 01787 01788 /* 01789 * end of parsing of this node. 01790 */ 01791 #ifdef DEBUG_SAX_TREE 01792 xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name); 01793 #endif 01794 nodePop(ctxt); 01795 } 01796 #endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLE */ 01797 01798 /* 01799 * xmlSAX2TextNode: 01800 * @ctxt: the parser context 01801 * @str: the input string 01802 * @len: the string length 01803 * 01804 * Remove the entities from an attribute value 01805 * 01806 * Returns the newly allocated string or NULL if not needed or error 01807 */ 01808 static xmlNodePtr 01809 xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) { 01810 xmlNodePtr ret; 01811 const xmlChar *intern = NULL; 01812 01813 /* 01814 * Allocate 01815 */ 01816 if (ctxt->freeElems != NULL) { 01817 ret = ctxt->freeElems; 01818 ctxt->freeElems = ret->next; 01819 ctxt->freeElemsNr--; 01820 } else { 01821 ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode)); 01822 } 01823 if (ret == NULL) { 01824 xmlErrMemory(ctxt, "xmlSAX2Characters"); 01825 return(NULL); 01826 } 01827 memset(ret, 0, sizeof(xmlNode)); 01828 /* 01829 * intern the formatting blanks found between tags, or the 01830 * very short strings 01831 */ 01832 if (ctxt->dictNames) { 01833 xmlChar cur = str[len]; 01834 01835 if ((len < (int) (2 * sizeof(void *))) && 01836 (ctxt->options & XML_PARSE_COMPACT)) { 01837 /* store the string in the node overrithing properties and nsDef */ 01838 xmlChar *tmp = (xmlChar *) &(ret->properties); 01839 memcpy(tmp, str, len); 01840 tmp[len] = 0; 01841 intern = tmp; 01842 } else if ((len <= 3) && ((cur == '"') || (cur == '\'') || 01843 ((cur == '<') && (str[len + 1] != '!')))) { 01844 intern = xmlDictLookup(ctxt->dict, str, len); 01845 } else if (IS_BLANK_CH(*str) && (len < 60) && (cur == '<') && 01846 (str[len + 1] != '!')) { 01847 int i; 01848 01849 for (i = 1;i < len;i++) { 01850 if (!IS_BLANK_CH(str[i])) goto skip; 01851 } 01852 intern = xmlDictLookup(ctxt->dict, str, len); 01853 } 01854 } 01855 skip: 01856 ret->type = XML_TEXT_NODE; 01857 01858 ret->name = xmlStringText; 01859 if (intern == NULL) { 01860 ret->content = xmlStrndup(str, len); 01861 if (ret->content == NULL) { 01862 xmlSAX2ErrMemory(ctxt, "xmlSAX2TextNode"); 01863 xmlFree(ret); 01864 return(NULL); 01865 } 01866 } else 01867 ret->content = (xmlChar *) intern; 01868 01869 if (ctxt->input != NULL) 01870 ret->line = ctxt->input->line; 01871 01872 if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) 01873 xmlRegisterNodeDefaultValue(ret); 01874 return(ret); 01875 } 01876 01877 #ifdef LIBXML_VALID_ENABLED 01878 /* 01879 * xmlSAX2DecodeAttrEntities: 01880 * @ctxt: the parser context 01881 * @str: the input string 01882 * @len: the string length 01883 * 01884 * Remove the entities from an attribute value 01885 * 01886 * Returns the newly allocated string or NULL if not needed or error 01887 */ 01888 static xmlChar * 01889 xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, 01890 const xmlChar *end) { 01891 const xmlChar *in; 01892 xmlChar *ret; 01893 01894 in = str; 01895 while (in < end) 01896 if (*in++ == '&') 01897 goto decode; 01898 return(NULL); 01899 decode: 01900 ctxt->depth++; 01901 ret = xmlStringLenDecodeEntities(ctxt, str, end - str, 01902 XML_SUBSTITUTE_REF, 0,0,0); 01903 ctxt->depth--; 01904 return(ret); 01905 } 01906 #endif /* LIBXML_VALID_ENABLED */ 01907 01922 static void 01923 xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt, 01924 const xmlChar * localname, 01925 const xmlChar * prefix, 01926 const xmlChar * value, 01927 const xmlChar * valueend) 01928 { 01929 xmlAttrPtr ret; 01930 xmlNsPtr namespace = NULL; 01931 xmlChar *dup = NULL; 01932 01933 /* 01934 * Note: if prefix == NULL, the attribute is not in the default namespace 01935 */ 01936 if (prefix != NULL) 01937 namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, prefix); 01938 01939 /* 01940 * allocate the node 01941 */ 01942 if (ctxt->freeAttrs != NULL) { 01943 ret = ctxt->freeAttrs; 01944 ctxt->freeAttrs = ret->next; 01945 ctxt->freeAttrsNr--; 01946 memset(ret, 0, sizeof(xmlAttr)); 01947 ret->type = XML_ATTRIBUTE_NODE; 01948 01949 ret->parent = ctxt->node; 01950 ret->doc = ctxt->myDoc; 01951 ret->ns = namespace; 01952 01953 if (ctxt->dictNames) 01954 ret->name = localname; 01955 else 01956 ret->name = xmlStrdup(localname); 01957 01958 /* link at the end to preserv order, TODO speed up with a last */ 01959 if (ctxt->node->properties == NULL) { 01960 ctxt->node->properties = ret; 01961 } else { 01962 xmlAttrPtr prev = ctxt->node->properties; 01963 01964 while (prev->next != NULL) prev = prev->next; 01965 prev->next = ret; 01966 ret->prev = prev; 01967 } 01968 01969 if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) 01970 xmlRegisterNodeDefaultValue((xmlNodePtr)ret); 01971 } else { 01972 if (ctxt->dictNames) 01973 ret = xmlNewNsPropEatName(ctxt->node, namespace, 01974 (xmlChar *) localname, NULL); 01975 else 01976 ret = xmlNewNsProp(ctxt->node, namespace, localname, NULL); 01977 if (ret == NULL) { 01978 xmlErrMemory(ctxt, "xmlSAX2AttributeNs"); 01979 return; 01980 } 01981 } 01982 01983 if ((ctxt->replaceEntities == 0) && (!ctxt->html)) { 01984 xmlNodePtr tmp; 01985 01986 /* 01987 * We know that if there is an entity reference, then 01988 * the string has been dup'ed and terminates with 0 01989 * otherwise with ' or " 01990 */ 01991 if (*valueend != 0) { 01992 tmp = xmlSAX2TextNode(ctxt, value, valueend - value); 01993 ret->children = tmp; 01994 ret->last = tmp; 01995 if (tmp != NULL) { 01996 tmp->doc = ret->doc; 01997 tmp->parent = (xmlNodePtr) ret; 01998 } 01999 } else { 02000 ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value, 02001 valueend - value); 02002 tmp = ret->children; 02003 while (tmp != NULL) { 02004 tmp->doc = ret->doc; 02005 tmp->parent = (xmlNodePtr) ret; 02006 if (tmp->next == NULL) 02007 ret->last = tmp; 02008 tmp = tmp->next; 02009 } 02010 } 02011 } else if (value != NULL) { 02012 xmlNodePtr tmp; 02013 02014 tmp = xmlSAX2TextNode(ctxt, value, valueend - value); 02015 ret->children = tmp; 02016 ret->last = tmp; 02017 if (tmp != NULL) { 02018 tmp->doc = ret->doc; 02019 tmp->parent = (xmlNodePtr) ret; 02020 } 02021 } 02022 02023 #ifdef LIBXML_VALID_ENABLED 02024 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed && 02025 ctxt->myDoc && ctxt->myDoc->intSubset) { 02026 /* 02027 * If we don't substitute entities, the validation should be 02028 * done on a value with replaced entities anyway. 02029 */ 02030 if (!ctxt->replaceEntities) { 02031 dup = xmlSAX2DecodeAttrEntities(ctxt, value, valueend); 02032 if (dup == NULL) { 02033 if (*valueend == 0) { 02034 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 02035 ctxt->myDoc, ctxt->node, ret, value); 02036 } else { 02037 /* 02038 * That should already be normalized. 02039 * cheaper to finally allocate here than duplicate 02040 * entry points in the full validation code 02041 */ 02042 dup = xmlStrndup(value, valueend - value); 02043 02044 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 02045 ctxt->myDoc, ctxt->node, ret, dup); 02046 } 02047 } else { 02048 /* 02049 * dup now contains a string of the flattened attribute 02050 * content with entities substitued. Check if we need to 02051 * apply an extra layer of normalization. 02052 * It need to be done twice ... it's an extra burden related 02053 * to the ability to keep references in attributes 02054 */ 02055 if (ctxt->attsSpecial != NULL) { 02056 xmlChar *nvalnorm; 02057 xmlChar fn[50]; 02058 xmlChar *fullname; 02059 02060 fullname = xmlBuildQName(localname, prefix, fn, 50); 02061 if (fullname != NULL) { 02062 ctxt->vctxt.valid = 1; 02063 nvalnorm = xmlValidCtxtNormalizeAttributeValue( 02064 &ctxt->vctxt, ctxt->myDoc, 02065 ctxt->node, fullname, dup); 02066 if (ctxt->vctxt.valid != 1) 02067 ctxt->valid = 0; 02068 02069 if ((fullname != fn) && (fullname != localname)) 02070 xmlFree(fullname); 02071 if (nvalnorm != NULL) { 02072 xmlFree(dup); 02073 dup = nvalnorm; 02074 } 02075 } 02076 } 02077 02078 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 02079 ctxt->myDoc, ctxt->node, ret, dup); 02080 } 02081 } else { 02082 /* 02083 * if entities already have been substitued, then 02084 * the attribute as passed is already normalized 02085 */ 02086 dup = xmlStrndup(value, valueend - value); 02087 02088 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 02089 ctxt->myDoc, ctxt->node, ret, dup); 02090 } 02091 } else 02092 #endif /* LIBXML_VALID_ENABLED */ 02093 if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) && 02094 (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) || 02095 ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) { 02096 /* 02097 * when validating, the ID registration is done at the attribute 02098 * validation level. Otherwise we have to do specific handling here. 02099 */ 02100 if ((prefix == ctxt->str_xml) && 02101 (localname[0] == 'i') && (localname[1] == 'd') && 02102 (localname[2] == 0)) { 02103 /* 02104 * Add the xml:id value 02105 * 02106 * Open issue: normalization of the value. 02107 */ 02108 if (dup == NULL) 02109 dup = xmlStrndup(value, valueend - value); 02110 #ifdef LIBXML_VALID_ENABLED 02111 if (xmlValidateNCName(dup, 1) != 0) { 02112 xmlErrValid(ctxt, XML_DTD_XMLID_VALUE, 02113 "xml:id : attribute value %s is not an NCName\n", 02114 (const char *) dup, NULL); 02115 } 02116 #endif 02117 xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret); 02118 } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) { 02119 /* might be worth duplicate entry points and not copy */ 02120 if (dup == NULL) 02121 dup = xmlStrndup(value, valueend - value); 02122 xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret); 02123 } else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) { 02124 if (dup == NULL) 02125 dup = xmlStrndup(value, valueend - value); 02126 xmlAddRef(&ctxt->vctxt, ctxt->myDoc, dup, ret); 02127 } 02128 } 02129 if (dup != NULL) 02130 xmlFree(dup); 02131 } 02132 02150 void 02151 xmlSAX2StartElementNs(void *ctx, 02152 const xmlChar *localname, 02153 const xmlChar *prefix, 02154 const xmlChar *URI, 02155 int nb_namespaces, 02156 const xmlChar **namespaces, 02157 int nb_attributes, 02158 int nb_defaulted, 02159 const xmlChar **attributes) 02160 { 02161 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 02162 xmlNodePtr ret; 02163 xmlNodePtr parent; 02164 xmlNsPtr last = NULL, ns; 02165 const xmlChar *uri, *pref; 02166 int i, j; 02167 02168 if (ctx == NULL) return; 02169 parent = ctxt->node; 02170 /* 02171 * First check on validity: 02172 */ 02173 if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) && 02174 ((ctxt->myDoc->intSubset == NULL) || 02175 ((ctxt->myDoc->intSubset->notations == NULL) && 02176 (ctxt->myDoc->intSubset->elements == NULL) && 02177 (ctxt->myDoc->intSubset->attributes == NULL) && 02178 (ctxt->myDoc->intSubset->entities == NULL)))) { 02179 xmlErrValid(ctxt, XML_ERR_NO_DTD, 02180 "Validation failed: no DTD found !", NULL, NULL); 02181 ctxt->validate = 0; 02182 } 02183 02184 /* 02185 * allocate the node 02186 */ 02187 if (ctxt->freeElems != NULL) { 02188 ret = ctxt->freeElems; 02189 ctxt->freeElems = ret->next; 02190 ctxt->freeElemsNr--; 02191 memset(ret, 0, sizeof(xmlNode)); 02192 ret->type = XML_ELEMENT_NODE; 02193 02194 if (ctxt->dictNames) 02195 ret->name = localname; 02196 else { 02197 ret->name = xmlStrdup(localname); 02198 if (ret->name == NULL) { 02199 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs"); 02200 return; 02201 } 02202 } 02203 if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) 02204 xmlRegisterNodeDefaultValue(ret); 02205 } else { 02206 if (ctxt->dictNames) 02207 ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, 02208 (xmlChar *) localname, NULL); 02209 else 02210 ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL); 02211 if (ret == NULL) { 02212 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs"); 02213 return; 02214 } 02215 } 02216 if (ctxt->linenumbers) { 02217 if (ctxt->input != NULL) { 02218 if (ctxt->input->line < 65535) 02219 ret->line = (short) ctxt->input->line; 02220 else 02221 ret->line = 65535; 02222 } 02223 } 02224 02225 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) { 02226 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); 02227 } 02228 /* 02229 * Build the namespace list 02230 */ 02231 for (i = 0,j = 0;j < nb_namespaces;j++) { 02232 pref = namespaces[i++]; 02233 uri = namespaces[i++]; 02234 ns = xmlNewNs(NULL, uri, pref); 02235 if (ns != NULL) { 02236 if (last == NULL) { 02237 ret->nsDef = last = ns; 02238 } else { 02239 last->next = ns; 02240 last = ns; 02241 } 02242 if ((URI != NULL) && (prefix == pref)) 02243 ret->ns = ns; 02244 } else { 02245 /* 02246 * any out of memory error would already have been raised 02247 * but we can't be garanteed it's the actual error due to the 02248 * API, best is to skip in this case 02249 */ 02250 continue; 02251 } 02252 #ifdef LIBXML_VALID_ENABLED 02253 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed && 02254 ctxt->myDoc && ctxt->myDoc->intSubset) { 02255 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc, 02256 ret, prefix, ns, uri); 02257 } 02258 #endif /* LIBXML_VALID_ENABLED */ 02259 } 02260 ctxt->nodemem = -1; 02261 02262 /* 02263 * We are parsing a new node. 02264 */ 02265 nodePush(ctxt, ret); 02266 02267 /* 02268 * Link the child element 02269 */ 02270 if (parent != NULL) { 02271 if (parent->type == XML_ELEMENT_NODE) { 02272 xmlAddChild(parent, ret); 02273 } else { 02274 xmlAddSibling(parent, ret); 02275 } 02276 } 02277 02278 /* 02279 * Insert the defaulted attributes from the DTD only if requested: 02280 */ 02281 if ((nb_defaulted != 0) && 02282 ((ctxt->loadsubset & XML_COMPLETE_ATTRS) == 0)) 02283 nb_attributes -= nb_defaulted; 02284 02285 /* 02286 * Search the namespace if it wasn't already found 02287 * Note that, if prefix is NULL, this searches for the default Ns 02288 */ 02289 if ((URI != NULL) && (ret->ns == NULL)) { 02290 ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix); 02291 if ((ret->ns == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) { 02292 ret->ns = xmlSearchNs(ctxt->myDoc, ret, prefix); 02293 } 02294 if (ret->ns == NULL) { 02295 ns = xmlNewNs(ret, NULL, prefix); 02296 if (ns == NULL) { 02297 02298 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs"); 02299 return; 02300 } 02301 if (prefix != NULL) 02302 xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE, 02303 "Namespace prefix %s was not found\n", 02304 prefix, NULL); 02305 else 02306 xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE, 02307 "Namespace default prefix was not found\n", 02308 NULL, NULL); 02309 } 02310 } 02311 02312 /* 02313 * process all the other attributes 02314 */ 02315 if (nb_attributes > 0) { 02316 for (j = 0,i = 0;i < nb_attributes;i++,j+=5) { 02317 xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1], 02318 attributes[j+3], attributes[j+4]); 02319 } 02320 } 02321 02322 #ifdef LIBXML_VALID_ENABLED 02323 /* 02324 * If it's the Document root, finish the DTD validation and 02325 * check the document root element for validity 02326 */ 02327 if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) { 02328 int chk; 02329 02330 chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc); 02331 if (chk <= 0) 02332 ctxt->valid = 0; 02333 if (chk < 0) 02334 ctxt->wellFormed = 0; 02335 ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc); 02336 ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1; 02337 } 02338 #endif /* LIBXML_VALID_ENABLED */ 02339 } 02340 02351 void 02352 xmlSAX2EndElementNs(void *ctx, 02353 const xmlChar * localname ATTRIBUTE_UNUSED, 02354 const xmlChar * prefix ATTRIBUTE_UNUSED, 02355 const xmlChar * URI ATTRIBUTE_UNUSED) 02356 { 02357 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 02358 xmlParserNodeInfo node_info; 02359 xmlNodePtr cur; 02360 02361 if (ctx == NULL) return; 02362 cur = ctxt->node; 02363 /* Capture end position and add node */ 02364 if ((ctxt->record_info) && (cur != NULL)) { 02365 node_info.end_pos = ctxt->input->cur - ctxt->input->base; 02366 node_info.end_line = ctxt->input->line; 02367 node_info.node = cur; 02368 xmlParserAddNodeInfo(ctxt, &node_info); 02369 } 02370 ctxt->nodemem = -1; 02371 02372 #ifdef LIBXML_VALID_ENABLED 02373 if (ctxt->validate && ctxt->wellFormed && 02374 ctxt->myDoc && ctxt->myDoc->intSubset) 02375 ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, cur); 02376 #endif /* LIBXML_VALID_ENABLED */ 02377 02378 /* 02379 * end of parsing of this node. 02380 */ 02381 nodePop(ctxt); 02382 } 02383 02391 void 02392 xmlSAX2Reference(void *ctx, const xmlChar *name) 02393 { 02394 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 02395 xmlNodePtr ret; 02396 02397 if (ctx == NULL) return; 02398 #ifdef DEBUG_SAX 02399 xmlGenericError(xmlGenericErrorContext, 02400 "SAX.xmlSAX2Reference(%s)\n", name); 02401 #endif 02402 if (name[0] == '#') 02403 ret = xmlNewCharRef(ctxt->myDoc, name); 02404 else 02405 ret = xmlNewReference(ctxt->myDoc, name); 02406 #ifdef DEBUG_SAX_TREE 02407 xmlGenericError(xmlGenericErrorContext, 02408 "add xmlSAX2Reference %s to %s \n", name, ctxt->node->name); 02409 #endif 02410 if (xmlAddChild(ctxt->node, ret) == NULL) { 02411 xmlFreeNode(ret); 02412 } 02413 } 02414 02423 void 02424 xmlSAX2Characters(void *ctx, const xmlChar *ch, int len) 02425 { 02426 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 02427 xmlNodePtr lastChild; 02428 02429 if (ctx == NULL) return; 02430 #ifdef DEBUG_SAX 02431 xmlGenericError(xmlGenericErrorContext, 02432 "SAX.xmlSAX2Characters(%.30s, %d)\n", ch, len); 02433 #endif 02434 /* 02435 * Handle the data if any. If there is no child 02436 * add it as content, otherwise if the last child is text, 02437 * concatenate it, else create a new node of type text. 02438 */ 02439 02440 if (ctxt->node == NULL) { 02441 #ifdef DEBUG_SAX_TREE 02442 xmlGenericError(xmlGenericErrorContext, 02443 "add chars: ctxt->node == NULL !\n"); 02444 #endif 02445 return; 02446 } 02447 lastChild = ctxt->node->last; 02448 #ifdef DEBUG_SAX_TREE 02449 xmlGenericError(xmlGenericErrorContext, 02450 "add chars to %s \n", ctxt->node->name); 02451 #endif 02452 02453 /* 02454 * Here we needed an accelerator mechanism in case of very large 02455 * elements. Use an attribute in the structure !!! 02456 */ 02457 if (lastChild == NULL) { 02458 lastChild = xmlSAX2TextNode(ctxt, ch, len); 02459 if (lastChild != NULL) { 02460 ctxt->node->children = lastChild; 02461 ctxt->node->last = lastChild; 02462 lastChild->parent = ctxt->node; 02463 lastChild->doc = ctxt->node->doc; 02464 ctxt->nodelen = len; 02465 ctxt->nodemem = len + 1; 02466 } else { 02467 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters"); 02468 return; 02469 } 02470 } else { 02471 int coalesceText = (lastChild != NULL) && 02472 (lastChild->type == XML_TEXT_NODE) && 02473 (lastChild->name == xmlStringText); 02474 if ((coalesceText) && (ctxt->nodemem != 0)) { 02475 /* 02476 * The whole point of maintaining nodelen and nodemem, 02477 * xmlTextConcat is too costly, i.e. compute length, 02478 * reallocate a new buffer, move data, append ch. Here 02479 * We try to minimaze realloc() uses and avoid copying 02480 * and recomputing length over and over. 02481 */ 02482 if (lastChild->content == (xmlChar *)&(lastChild->properties)) { 02483 lastChild->content = xmlStrdup(lastChild->content); 02484 lastChild->properties = NULL; 02485 } else if ((ctxt->nodemem == ctxt->nodelen + 1) && 02486 (xmlDictOwns(ctxt->dict, lastChild->content))) { 02487 lastChild->content = xmlStrdup(lastChild->content); 02488 } 02489 if (((size_t)ctxt->nodelen + (size_t)len > XML_MAX_TEXT_LENGTH) && 02490 ((ctxt->options & XML_PARSE_HUGE) == 0)) { 02491 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: huge text node"); 02492 return; 02493 } 02494 if ((size_t)ctxt->nodelen > SIZE_T_MAX - (size_t)len || 02495 (size_t)ctxt->nodemem + (size_t)len > SIZE_T_MAX / 2) { 02496 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters overflow prevented"); 02497 return; 02498 } 02499 if (ctxt->nodelen + len >= ctxt->nodemem) { 02500 xmlChar *newbuf; 02501 size_t size; 02502 02503 size = ctxt->nodemem + len; 02504 size *= 2; 02505 newbuf = (xmlChar *) xmlRealloc(lastChild->content,size); 02506 if (newbuf == NULL) { 02507 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters"); 02508 return; 02509 } 02510 ctxt->nodemem = size; 02511 lastChild->content = newbuf; 02512 } 02513 memcpy(&lastChild->content[ctxt->nodelen], ch, len); 02514 ctxt->nodelen += len; 02515 lastChild->content[ctxt->nodelen] = 0; 02516 } else if (coalesceText) { 02517 if (xmlTextConcat(lastChild, ch, len)) { 02518 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters"); 02519 } 02520 if (ctxt->node->children != NULL) { 02521 ctxt->nodelen = xmlStrlen(lastChild->content); 02522 ctxt->nodemem = ctxt->nodelen + 1; 02523 } 02524 } else { 02525 /* Mixed content, first time */ 02526 lastChild = xmlSAX2TextNode(ctxt, ch, len); 02527 if (lastChild != NULL) { 02528 xmlAddChild(ctxt->node, lastChild); 02529 if (ctxt->node->children != NULL) { 02530 ctxt->nodelen = len; 02531 ctxt->nodemem = len + 1; 02532 } 02533 } 02534 } 02535 } 02536 } 02537 02547 void 02548 xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED) 02549 { 02550 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ 02551 #ifdef DEBUG_SAX 02552 xmlGenericError(xmlGenericErrorContext, 02553 "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch, len); 02554 #endif 02555 } 02556 02565 void 02566 xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target, 02567 const xmlChar *data) 02568 { 02569 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 02570 xmlNodePtr ret; 02571 xmlNodePtr parent; 02572 02573 if (ctx == NULL) return; 02574 parent = ctxt->node; 02575 #ifdef DEBUG_SAX 02576 xmlGenericError(xmlGenericErrorContext, 02577 "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target, data); 02578 #endif 02579 02580 ret = xmlNewDocPI(ctxt->myDoc, target, data); 02581 if (ret == NULL) return; 02582 02583 if (ctxt->linenumbers) { 02584 if (ctxt->input != NULL) { 02585 if (ctxt->input->line < 65535) 02586 ret->line = (short) ctxt->input->line; 02587 else 02588 ret->line = 65535; 02589 } 02590 } 02591 if (ctxt->inSubset == 1) { 02592 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret); 02593 return; 02594 } else if (ctxt->inSubset == 2) { 02595 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret); 02596 return; 02597 } 02598 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) { 02599 #ifdef DEBUG_SAX_TREE 02600 xmlGenericError(xmlGenericErrorContext, 02601 "Setting PI %s as root\n", target); 02602 #endif 02603 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); 02604 return; 02605 } 02606 if (parent->type == XML_ELEMENT_NODE) { 02607 #ifdef DEBUG_SAX_TREE 02608 xmlGenericError(xmlGenericErrorContext, 02609 "adding PI %s child to %s\n", target, parent->name); 02610 #endif 02611 xmlAddChild(parent, ret); 02612 } else { 02613 #ifdef DEBUG_SAX_TREE 02614 xmlGenericError(xmlGenericErrorContext, 02615 "adding PI %s sibling to ", target); 02616 xmlDebugDumpOneNode(stderr, parent, 0); 02617 #endif 02618 xmlAddSibling(parent, ret); 02619 } 02620 } 02621 02629 void 02630 xmlSAX2Comment(void *ctx, const xmlChar *value) 02631 { 02632 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 02633 xmlNodePtr ret; 02634 xmlNodePtr parent; 02635 02636 if (ctx == NULL) return; 02637 parent = ctxt->node; 02638 #ifdef DEBUG_SAX 02639 xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Comment(%s)\n", value); 02640 #endif 02641 ret = xmlNewDocComment(ctxt->myDoc, value); 02642 if (ret == NULL) return; 02643 if (ctxt->linenumbers) { 02644 if (ctxt->input != NULL) { 02645 if (ctxt->input->line < 65535) 02646 ret->line = (short) ctxt->input->line; 02647 else 02648 ret->line = 65535; 02649 } 02650 } 02651 02652 if (ctxt->inSubset == 1) { 02653 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret); 02654 return; 02655 } else if (ctxt->inSubset == 2) { 02656 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret); 02657 return; 02658 } 02659 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) { 02660 #ifdef DEBUG_SAX_TREE 02661 xmlGenericError(xmlGenericErrorContext, 02662 "Setting xmlSAX2Comment as root\n"); 02663 #endif 02664 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); 02665 return; 02666 } 02667 if (parent->type == XML_ELEMENT_NODE) { 02668 #ifdef DEBUG_SAX_TREE 02669 xmlGenericError(xmlGenericErrorContext, 02670 "adding xmlSAX2Comment child to %s\n", parent->name); 02671 #endif 02672 xmlAddChild(parent, ret); 02673 } else { 02674 #ifdef DEBUG_SAX_TREE 02675 xmlGenericError(xmlGenericErrorContext, 02676 "adding xmlSAX2Comment sibling to "); 02677 xmlDebugDumpOneNode(stderr, parent, 0); 02678 #endif 02679 xmlAddSibling(parent, ret); 02680 } 02681 } 02682 02691 void 02692 xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len) 02693 { 02694 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 02695 xmlNodePtr ret, lastChild; 02696 02697 if (ctx == NULL) return; 02698 #ifdef DEBUG_SAX 02699 xmlGenericError(xmlGenericErrorContext, 02700 "SAX.pcdata(%.10s, %d)\n", value, len); 02701 #endif 02702 lastChild = xmlGetLastChild(ctxt->node); 02703 #ifdef DEBUG_SAX_TREE 02704 xmlGenericError(xmlGenericErrorContext, 02705 "add chars to %s \n", ctxt->node->name); 02706 #endif 02707 if ((lastChild != NULL) && 02708 (lastChild->type == XML_CDATA_SECTION_NODE)) { 02709 xmlTextConcat(lastChild, value, len); 02710 } else { 02711 ret = xmlNewCDataBlock(ctxt->myDoc, value, len); 02712 xmlAddChild(ctxt->node, ret); 02713 } 02714 } 02715 02716 static int xmlSAX2DefaultVersionValue = 2; 02717 02718 #ifdef LIBXML_SAX1_ENABLED 02719 02731 int 02732 xmlSAXDefaultVersion(int version) 02733 { 02734 int ret = xmlSAX2DefaultVersionValue; 02735 02736 if ((version != 1) && (version != 2)) 02737 return(-1); 02738 xmlSAX2DefaultVersionValue = version; 02739 return(ret); 02740 } 02741 #endif /* LIBXML_SAX1_ENABLED */ 02742 02752 int 02753 xmlSAXVersion(xmlSAXHandler *hdlr, int version) 02754 { 02755 if (hdlr == NULL) return(-1); 02756 if (version == 2) { 02757 hdlr->startElement = NULL; 02758 hdlr->endElement = NULL; 02759 hdlr->startElementNs = xmlSAX2StartElementNs; 02760 hdlr->endElementNs = xmlSAX2EndElementNs; 02761 hdlr->serror = NULL; 02762 hdlr->initialized = XML_SAX2_MAGIC; 02763 #ifdef LIBXML_SAX1_ENABLED 02764 } else if (version == 1) { 02765 hdlr->startElement = xmlSAX2StartElement; 02766 hdlr->endElement = xmlSAX2EndElement; 02767 hdlr->initialized = 1; 02768 #endif /* LIBXML_SAX1_ENABLED */ 02769 } else 02770 return(-1); 02771 hdlr->internalSubset = xmlSAX2InternalSubset; 02772 hdlr->externalSubset = xmlSAX2ExternalSubset; 02773 hdlr->isStandalone = xmlSAX2IsStandalone; 02774 hdlr->hasInternalSubset = xmlSAX2HasInternalSubset; 02775 hdlr->hasExternalSubset = xmlSAX2HasExternalSubset; 02776 hdlr->resolveEntity = xmlSAX2ResolveEntity; 02777 hdlr->getEntity = xmlSAX2GetEntity; 02778 hdlr->getParameterEntity = xmlSAX2GetParameterEntity; 02779 hdlr->entityDecl = xmlSAX2EntityDecl; 02780 hdlr->attributeDecl = xmlSAX2AttributeDecl; 02781 hdlr->elementDecl = xmlSAX2ElementDecl; 02782 hdlr->notationDecl = xmlSAX2NotationDecl; 02783 hdlr->unparsedEntityDecl = xmlSAX2UnparsedEntityDecl; 02784 hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator; 02785 hdlr->startDocument = xmlSAX2StartDocument; 02786 hdlr->endDocument = xmlSAX2EndDocument; 02787 hdlr->reference = xmlSAX2Reference; 02788 hdlr->characters = xmlSAX2Characters; 02789 hdlr->cdataBlock = xmlSAX2CDataBlock; 02790 hdlr->ignorableWhitespace = xmlSAX2Characters; 02791 hdlr->processingInstruction = xmlSAX2ProcessingInstruction; 02792 hdlr->comment = xmlSAX2Comment; 02793 hdlr->warning = xmlParserWarning; 02794 hdlr->error = xmlParserError; 02795 hdlr->fatalError = xmlParserError; 02796 02797 return(0); 02798 } 02799 02807 void 02808 xmlSAX2InitDefaultSAXHandler(xmlSAXHandler *hdlr, int warning) 02809 { 02810 if ((hdlr == NULL) || (hdlr->initialized != 0)) 02811 return; 02812 02813 xmlSAXVersion(hdlr, xmlSAX2DefaultVersionValue); 02814 if (warning == 0) 02815 hdlr->warning = NULL; 02816 else 02817 hdlr->warning = xmlParserWarning; 02818 } 02819 02825 void 02826 xmlDefaultSAXHandlerInit(void) 02827 { 02828 #ifdef LIBXML_SAX1_ENABLED 02829 xmlSAXVersion((xmlSAXHandlerPtr) &xmlDefaultSAXHandler, 1); 02830 #endif /* LIBXML_SAX1_ENABLED */ 02831 } 02832 02833 #ifdef LIBXML_HTML_ENABLED 02834 02841 void 02842 xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr) 02843 { 02844 if ((hdlr == NULL) || (hdlr->initialized != 0)) 02845 return; 02846 02847 hdlr->internalSubset = xmlSAX2InternalSubset; 02848 hdlr->externalSubset = NULL; 02849 hdlr->isStandalone = NULL; 02850 hdlr->hasInternalSubset = NULL; 02851 hdlr->hasExternalSubset = NULL; 02852 hdlr->resolveEntity = NULL; 02853 hdlr->getEntity = xmlSAX2GetEntity; 02854 hdlr->getParameterEntity = NULL; 02855 hdlr->entityDecl = NULL; 02856 hdlr->attributeDecl = NULL; 02857 hdlr->elementDecl = NULL; 02858 hdlr->notationDecl = NULL; 02859 hdlr->unparsedEntityDecl = NULL; 02860 hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator; 02861 hdlr->startDocument = xmlSAX2StartDocument; 02862 hdlr->endDocument = xmlSAX2EndDocument; 02863 hdlr->startElement = xmlSAX2StartElement; 02864 hdlr->endElement = xmlSAX2EndElement; 02865 hdlr->reference = NULL; 02866 hdlr->characters = xmlSAX2Characters; 02867 hdlr->cdataBlock = xmlSAX2CDataBlock; 02868 hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace; 02869 hdlr->processingInstruction = xmlSAX2ProcessingInstruction; 02870 hdlr->comment = xmlSAX2Comment; 02871 hdlr->warning = xmlParserWarning; 02872 hdlr->error = xmlParserError; 02873 hdlr->fatalError = xmlParserError; 02874 02875 hdlr->initialized = 1; 02876 } 02877 02883 void 02884 htmlDefaultSAXHandlerInit(void) 02885 { 02886 xmlSAX2InitHtmlDefaultSAXHandler((xmlSAXHandlerPtr) &htmlDefaultSAXHandler); 02887 } 02888 02889 #endif /* LIBXML_HTML_ENABLED */ 02890 02891 #ifdef LIBXML_DOCB_ENABLED 02892 02899 void 02900 xmlSAX2InitDocbDefaultSAXHandler(xmlSAXHandler *hdlr) 02901 { 02902 if ((hdlr == NULL) || (hdlr->initialized != 0)) 02903 return; 02904 02905 hdlr->internalSubset = xmlSAX2InternalSubset; 02906 hdlr->externalSubset = NULL; 02907 hdlr->isStandalone = xmlSAX2IsStandalone; 02908 hdlr->hasInternalSubset = xmlSAX2HasInternalSubset; 02909 hdlr->hasExternalSubset = xmlSAX2HasExternalSubset; 02910 hdlr->resolveEntity = xmlSAX2ResolveEntity; 02911 hdlr->getEntity = xmlSAX2GetEntity; 02912 hdlr->getParameterEntity = NULL; 02913 hdlr->entityDecl = xmlSAX2EntityDecl; 02914 hdlr->attributeDecl = NULL; 02915 hdlr->elementDecl = NULL; 02916 hdlr->notationDecl = NULL; 02917 hdlr->unparsedEntityDecl = NULL; 02918 hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator; 02919 hdlr->startDocument = xmlSAX2StartDocument; 02920 hdlr->endDocument = xmlSAX2EndDocument; 02921 hdlr->startElement = xmlSAX2StartElement; 02922 hdlr->endElement = xmlSAX2EndElement; 02923 hdlr->reference = xmlSAX2Reference; 02924 hdlr->characters = xmlSAX2Characters; 02925 hdlr->cdataBlock = NULL; 02926 hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace; 02927 hdlr->processingInstruction = NULL; 02928 hdlr->comment = xmlSAX2Comment; 02929 hdlr->warning = xmlParserWarning; 02930 hdlr->error = xmlParserError; 02931 hdlr->fatalError = xmlParserError; 02932 02933 hdlr->initialized = 1; 02934 } 02935 02941 void 02942 docbDefaultSAXHandlerInit(void) 02943 { 02944 xmlSAX2InitDocbDefaultSAXHandler((xmlSAXHandlerPtr) &docbDefaultSAXHandler); 02945 } 02946 02947 #endif /* LIBXML_DOCB_ENABLED */ 02948 #define bottom_SAX2 02949 #include "elfgcchack.h" Generated on Sat May 19 2012 04:32:28 for ReactOS by
1.7.6.1
|