SAX2.c revision 67906944fc97811009b5ad51c70da86ea8505581
1/* 2 * SAX2.c : Default SAX2 handler to build a tree. 3 * 4 * See Copyright for the status of this software. 5 * 6 * Daniel Veillard <daniel@veillard.com> 7 */ 8 9 10#define IN_LIBXML 11#include "libxml.h" 12#include <stdlib.h> 13#include <string.h> 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> 28 29/* #define DEBUG_SAX2 */ 30/* #define DEBUG_SAX2_TREE */ 31 32/** 33 * xmlSAX2GetPublicId: 34 * @ctx: the user data (XML parser context) 35 * 36 * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN" 37 * 38 * Returns a xmlChar * 39 */ 40const xmlChar * 41xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED) 42{ 43 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ 44 return(NULL); 45} 46 47/** 48 * xmlSAX2GetSystemId: 49 * @ctx: the user data (XML parser context) 50 * 51 * Provides the system ID, basically URL or filename e.g. 52 * http://www.sgmlsource.com/dtds/memo.dtd 53 * 54 * Returns a xmlChar * 55 */ 56const xmlChar * 57xmlSAX2GetSystemId(void *ctx) 58{ 59 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 60 return((const xmlChar *) ctxt->input->filename); 61} 62 63/** 64 * xmlSAX2GetLineNumber: 65 * @ctx: the user data (XML parser context) 66 * 67 * Provide the line number of the current parsing point. 68 * 69 * Returns an int 70 */ 71int 72xmlSAX2GetLineNumber(void *ctx) 73{ 74 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 75 return(ctxt->input->line); 76} 77 78/** 79 * xmlSAX2GetColumnNumber: 80 * @ctx: the user data (XML parser context) 81 * 82 * Provide the column number of the current parsing point. 83 * 84 * Returns an int 85 */ 86int 87xmlSAX2GetColumnNumber(void *ctx) 88{ 89 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 90 return(ctxt->input->col); 91} 92 93/** 94 * xmlSAX2IsStandalone: 95 * @ctx: the user data (XML parser context) 96 * 97 * Is this document tagged standalone ? 98 * 99 * Returns 1 if true 100 */ 101int 102xmlSAX2IsStandalone(void *ctx) 103{ 104 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 105 return(ctxt->myDoc->standalone == 1); 106} 107 108/** 109 * xmlSAX2HasInternalSubset: 110 * @ctx: the user data (XML parser context) 111 * 112 * Does this document has an internal subset 113 * 114 * Returns 1 if true 115 */ 116int 117xmlSAX2HasInternalSubset(void *ctx) 118{ 119 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 120 return(ctxt->myDoc->intSubset != NULL); 121} 122 123/** 124 * xmlSAX2HasExternalSubset: 125 * @ctx: the user data (XML parser context) 126 * 127 * Does this document has an external subset 128 * 129 * Returns 1 if true 130 */ 131int 132xmlSAX2HasExternalSubset(void *ctx) 133{ 134 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 135 return(ctxt->myDoc->extSubset != NULL); 136} 137 138/** 139 * xmlSAX2InternalSubset: 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) 144 * 145 * Callback on internal subset declaration. 146 */ 147void 148xmlSAX2InternalSubset(void *ctx, const xmlChar *name, 149 const xmlChar *ExternalID, const xmlChar *SystemID) 150{ 151 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 152 xmlDtdPtr dtd; 153#ifdef DEBUG_SAX 154 xmlGenericError(xmlGenericErrorContext, 155 "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n", 156 name, ExternalID, SystemID); 157#endif 158 159 if (ctxt->myDoc == NULL) 160 return; 161 dtd = xmlGetIntSubset(ctxt->myDoc); 162 if (dtd != NULL) { 163 if (ctxt->html) 164 return; 165 xmlUnlinkNode((xmlNodePtr) dtd); 166 xmlFreeDtd(dtd); 167 ctxt->myDoc->intSubset = NULL; 168 } 169 ctxt->myDoc->intSubset = 170 xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID); 171} 172 173/** 174 * xmlSAX2ExternalSubset: 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) 179 * 180 * Callback on external subset declaration. 181 */ 182void 183xmlSAX2ExternalSubset(void *ctx, const xmlChar *name, 184 const xmlChar *ExternalID, const xmlChar *SystemID) 185{ 186 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 187#ifdef DEBUG_SAX 188 xmlGenericError(xmlGenericErrorContext, 189 "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n", 190 name, ExternalID, SystemID); 191#endif 192 if (((ExternalID != NULL) || (SystemID != NULL)) && 193 (((ctxt->validate) || (ctxt->loadsubset != 0)) && 194 (ctxt->wellFormed && ctxt->myDoc))) { 195 /* 196 * Try to fetch and parse the external subset. 197 */ 198 xmlParserInputPtr oldinput; 199 int oldinputNr; 200 int oldinputMax; 201 xmlParserInputPtr *oldinputTab; 202 xmlParserInputPtr input = NULL; 203 xmlCharEncoding enc; 204 int oldcharset; 205 206 /* 207 * Ask the Entity resolver to load the damn thing 208 */ 209 if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL)) 210 input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID, 211 SystemID); 212 if (input == NULL) { 213 return; 214 } 215 216 xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID); 217 218 /* 219 * make sure we won't destroy the main document context 220 */ 221 oldinput = ctxt->input; 222 oldinputNr = ctxt->inputNr; 223 oldinputMax = ctxt->inputMax; 224 oldinputTab = ctxt->inputTab; 225 oldcharset = ctxt->charset; 226 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 "xmlSAX2ExternalSubset: out of memory\n"); 234 ctxt->errNo = XML_ERR_NO_MEMORY; 235 ctxt->instate = XML_PARSER_EOF; 236 ctxt->disableSAX = 1; 237 ctxt->input = oldinput; 238 ctxt->inputNr = oldinputNr; 239 ctxt->inputMax = oldinputMax; 240 ctxt->inputTab = oldinputTab; 241 ctxt->charset = oldcharset; 242 return; 243 } 244 ctxt->inputNr = 0; 245 ctxt->inputMax = 5; 246 ctxt->input = NULL; 247 xmlPushInput(ctxt, input); 248 249 /* 250 * On the fly encoding conversion if needed 251 */ 252 if (ctxt->input->length >= 4) { 253 enc = xmlDetectCharEncoding(ctxt->input->cur, 4); 254 xmlSwitchEncoding(ctxt, enc); 255 } 256 257 if (input->filename == NULL) 258 input->filename = (char *) xmlCanonicPath(SystemID); 259 input->line = 1; 260 input->col = 1; 261 input->base = ctxt->input->cur; 262 input->cur = ctxt->input->cur; 263 input->free = NULL; 264 265 /* 266 * let's parse that entity knowing it's an external subset. 267 */ 268 xmlParseExternalSubset(ctxt, ExternalID, SystemID); 269 270 /* 271 * Free up the external entities 272 */ 273 274 while (ctxt->inputNr > 1) 275 xmlPopInput(ctxt); 276 xmlFreeInputStream(ctxt->input); 277 xmlFree(ctxt->inputTab); 278 279 /* 280 * Restore the parsing context of the main entity 281 */ 282 ctxt->input = oldinput; 283 ctxt->inputNr = oldinputNr; 284 ctxt->inputMax = oldinputMax; 285 ctxt->inputTab = oldinputTab; 286 ctxt->charset = oldcharset; 287 /* ctxt->wellFormed = oldwellFormed; */ 288 } 289} 290 291/** 292 * xmlSAX2ResolveEntity: 293 * @ctx: the user data (XML parser context) 294 * @publicId: The public ID of the entity 295 * @systemId: The system ID of the entity 296 * 297 * The entity loader, to control the loading of external entities, 298 * the application can either: 299 * - override this xmlSAX2ResolveEntity() callback in the SAX block 300 * - or better use the xmlSetExternalEntityLoader() function to 301 * set up it's own entity resolution routine 302 * 303 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour. 304 */ 305xmlParserInputPtr 306xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId) 307{ 308 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 309 xmlParserInputPtr ret; 310 xmlChar *URI; 311 const char *base = NULL; 312 313 if (ctxt->input != NULL) 314 base = ctxt->input->filename; 315 if (base == NULL) 316 base = ctxt->directory; 317 318 URI = xmlBuildURI(systemId, (const xmlChar *) base); 319 320#ifdef DEBUG_SAX 321 xmlGenericError(xmlGenericErrorContext, 322 "SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId, systemId); 323#endif 324 325 ret = xmlLoadExternalEntity((const char *) URI, 326 (const char *) publicId, ctxt); 327 if (URI != NULL) 328 xmlFree(URI); 329 return(ret); 330} 331 332/** 333 * xmlSAX2GetEntity: 334 * @ctx: the user data (XML parser context) 335 * @name: The entity name 336 * 337 * Get an entity by name 338 * 339 * Returns the xmlEntityPtr if found. 340 */ 341xmlEntityPtr 342xmlSAX2GetEntity(void *ctx, const xmlChar *name) 343{ 344 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 345 xmlEntityPtr ret = NULL; 346 347#ifdef DEBUG_SAX 348 xmlGenericError(xmlGenericErrorContext, 349 "SAX.xmlSAX2GetEntity(%s)\n", name); 350#endif 351 352 if (ctxt->inSubset == 0) { 353 ret = xmlGetPredefinedEntity(name); 354 if (ret != NULL) 355 return(ret); 356 } 357 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1)) { 358 if (ctxt->inSubset == 2) { 359 ctxt->myDoc->standalone = 0; 360 ret = xmlGetDocEntity(ctxt->myDoc, name); 361 ctxt->myDoc->standalone = 1; 362 } else { 363 ret = xmlGetDocEntity(ctxt->myDoc, name); 364 if (ret == NULL) { 365 ctxt->myDoc->standalone = 0; 366 ret = xmlGetDocEntity(ctxt->myDoc, name); 367 if (ret != NULL) { 368 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 369 ctxt->sax->error(ctxt, 370 "Entity(%s) document marked standalone but require external subset\n", 371 name); 372 ctxt->valid = 0; 373 ctxt->wellFormed = 0; 374 } 375 ctxt->myDoc->standalone = 1; 376 } 377 } 378 } else { 379 ret = xmlGetDocEntity(ctxt->myDoc, name); 380 } 381 if ((ret != NULL) && 382 ((ctxt->validate) || (ctxt->replaceEntities)) && 383 (ret->children == NULL) && 384 (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) { 385 int val; 386 387 /* 388 * for validation purposes we really need to fetch and 389 * parse the external entity 390 */ 391 xmlNodePtr children; 392 393 val = xmlParseCtxtExternalEntity(ctxt, ret->URI, 394 ret->ExternalID, &children); 395 if (val == 0) { 396 xmlAddChildList((xmlNodePtr) ret, children); 397 } else { 398 ctxt->sax->error(ctxt, 399 "Failure to process entity %s\n", name); 400 ctxt->wellFormed = 0; 401 ctxt->valid = 0; 402 ctxt->validate = 0; 403 return(NULL); 404 } 405 ret->owner = 1; 406 } 407 return(ret); 408} 409 410/** 411 * xmlSAX2GetParameterEntity: 412 * @ctx: the user data (XML parser context) 413 * @name: The entity name 414 * 415 * Get a parameter entity by name 416 * 417 * Returns the xmlEntityPtr if found. 418 */ 419xmlEntityPtr 420xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name) 421{ 422 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 423 xmlEntityPtr ret; 424 425#ifdef DEBUG_SAX 426 xmlGenericError(xmlGenericErrorContext, 427 "SAX.xmlSAX2GetParameterEntity(%s)\n", name); 428#endif 429 430 ret = xmlGetParameterEntity(ctxt->myDoc, name); 431 return(ret); 432} 433 434 435/** 436 * xmlSAX2EntityDecl: 437 * @ctx: the user data (XML parser context) 438 * @name: the entity name 439 * @type: the entity type 440 * @publicId: The public ID of the entity 441 * @systemId: The system ID of the entity 442 * @content: the entity value (without processing). 443 * 444 * An entity definition has been parsed 445 */ 446void 447xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type, 448 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) 449{ 450 xmlEntityPtr ent; 451 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 452 453#ifdef DEBUG_SAX 454 xmlGenericError(xmlGenericErrorContext, 455 "SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n", 456 name, type, publicId, systemId, content); 457#endif 458 if (ctxt->inSubset == 1) { 459 ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId, 460 systemId, content); 461 if ((ent == NULL) && (ctxt->pedantic) && 462 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 463 ctxt->sax->warning(ctxt, 464 "Entity(%s) already defined in the internal subset\n", name); 465 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 466 xmlChar *URI; 467 const char *base = NULL; 468 469 if (ctxt->input != NULL) 470 base = ctxt->input->filename; 471 if (base == NULL) 472 base = ctxt->directory; 473 474 URI = xmlBuildURI(systemId, (const xmlChar *) base); 475 ent->URI = URI; 476 } 477 } else if (ctxt->inSubset == 2) { 478 ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId, 479 systemId, content); 480 if ((ent == NULL) && (ctxt->pedantic) && 481 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 482 ctxt->sax->warning(ctxt, 483 "Entity(%s) already defined in the external subset\n", name); 484 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 485 xmlChar *URI; 486 const char *base = NULL; 487 488 if (ctxt->input != NULL) 489 base = ctxt->input->filename; 490 if (base == NULL) 491 base = ctxt->directory; 492 493 URI = xmlBuildURI(systemId, (const xmlChar *) base); 494 ent->URI = URI; 495 } 496 } else { 497 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 498 ctxt->sax->error(ctxt, 499 "SAX.xmlSAX2EntityDecl(%s) called while not in subset\n", name); 500 } 501} 502 503/** 504 * xmlSAX2AttributeDecl: 505 * @ctx: the user data (XML parser context) 506 * @elem: the name of the element 507 * @fullname: the attribute name 508 * @type: the attribute type 509 * @def: the type of default value 510 * @defaultValue: the attribute default value 511 * @tree: the tree of enumerated value set 512 * 513 * An attribute definition has been parsed 514 */ 515void 516xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname, 517 int type, int def, const xmlChar *defaultValue, 518 xmlEnumerationPtr tree) 519{ 520 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 521 xmlAttributePtr attr; 522 xmlChar *name = NULL, *prefix = NULL; 523 524#ifdef DEBUG_SAX 525 xmlGenericError(xmlGenericErrorContext, 526 "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n", 527 elem, fullname, type, def, defaultValue); 528#endif 529 name = xmlSplitQName(ctxt, fullname, &prefix); 530 ctxt->vctxt.valid = 1; 531 if (ctxt->inSubset == 1) 532 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem, 533 name, prefix, (xmlAttributeType) type, 534 (xmlAttributeDefault) def, defaultValue, tree); 535 else if (ctxt->inSubset == 2) 536 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem, 537 name, prefix, (xmlAttributeType) type, 538 (xmlAttributeDefault) def, defaultValue, tree); 539 else { 540 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 541 ctxt->sax->error(ctxt, 542 "SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n", name); 543 return; 544 } 545 if (ctxt->vctxt.valid == 0) 546 ctxt->valid = 0; 547 if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) && 548 (ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset != NULL)) 549 ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc, 550 attr); 551 if (prefix != NULL) 552 xmlFree(prefix); 553 if (name != NULL) 554 xmlFree(name); 555} 556 557/** 558 * xmlSAX2ElementDecl: 559 * @ctx: the user data (XML parser context) 560 * @name: the element name 561 * @type: the element type 562 * @content: the element value tree 563 * 564 * An element definition has been parsed 565 */ 566void 567xmlSAX2ElementDecl(void *ctx, const xmlChar * name, int type, 568 xmlElementContentPtr content) 569{ 570 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 571 xmlElementPtr elem = NULL; 572 573#ifdef DEBUG_SAX 574 xmlGenericError(xmlGenericErrorContext, 575 "SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name, type); 576#endif 577 578 if (ctxt->inSubset == 1) 579 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, 580 name, (xmlElementTypeVal) type, content); 581 else if (ctxt->inSubset == 2) 582 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, 583 name, (xmlElementTypeVal) type, content); 584 else { 585 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 586 ctxt->sax->error(ctxt, 587 "SAX.xmlSAX2ElementDecl(%s) called while not in subset\n", 588 name); 589 return; 590 } 591 if (elem == NULL) 592 ctxt->valid = 0; 593 if (ctxt->validate && ctxt->wellFormed && 594 ctxt->myDoc && ctxt->myDoc->intSubset) 595 ctxt->valid &= 596 xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem); 597} 598 599/** 600 * xmlSAX2NotationDecl: 601 * @ctx: the user data (XML parser context) 602 * @name: The name of the notation 603 * @publicId: The public ID of the entity 604 * @systemId: The system ID of the entity 605 * 606 * What to do when a notation declaration has been parsed. 607 */ 608void 609xmlSAX2NotationDecl(void *ctx, const xmlChar *name, 610 const xmlChar *publicId, const xmlChar *systemId) 611{ 612 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 613 xmlNotationPtr nota = NULL; 614 615#ifdef DEBUG_SAX 616 xmlGenericError(xmlGenericErrorContext, 617 "SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name, publicId, systemId); 618#endif 619 620 if ((publicId == NULL) && (systemId == NULL)) { 621 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 622 ctxt->sax->error(ctxt, 623 "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n", name); 624 ctxt->valid = 0; 625 ctxt->wellFormed = 0; 626 return; 627 } else if (ctxt->inSubset == 1) 628 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name, 629 publicId, systemId); 630 else if (ctxt->inSubset == 2) 631 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name, 632 publicId, systemId); 633 else { 634 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 635 ctxt->sax->error(ctxt, 636 "SAX.xmlSAX2NotationDecl(%s) called while not in subset\n", name); 637 return; 638 } 639 if (nota == NULL) ctxt->valid = 0; 640 if (ctxt->validate && ctxt->wellFormed && 641 ctxt->myDoc && ctxt->myDoc->intSubset) 642 ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc, 643 nota); 644} 645 646/** 647 * xmlSAX2UnparsedEntityDecl: 648 * @ctx: the user data (XML parser context) 649 * @name: The name of the entity 650 * @publicId: The public ID of the entity 651 * @systemId: The system ID of the entity 652 * @notationName: the name of the notation 653 * 654 * What to do when an unparsed entity declaration is parsed 655 */ 656void 657xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name, 658 const xmlChar *publicId, const xmlChar *systemId, 659 const xmlChar *notationName) 660{ 661 xmlEntityPtr ent; 662 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 663#ifdef DEBUG_SAX 664 xmlGenericError(xmlGenericErrorContext, 665 "SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n", 666 name, publicId, systemId, notationName); 667#endif 668 if (ctxt->inSubset == 1) { 669 ent = xmlAddDocEntity(ctxt->myDoc, name, 670 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY, 671 publicId, systemId, notationName); 672 if ((ent == NULL) && (ctxt->pedantic) && 673 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 674 ctxt->sax->warning(ctxt, 675 "Entity(%s) already defined in the internal subset\n", name); 676 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 677 xmlChar *URI; 678 const char *base = NULL; 679 680 if (ctxt->input != NULL) 681 base = ctxt->input->filename; 682 if (base == NULL) 683 base = ctxt->directory; 684 685 URI = xmlBuildURI(systemId, (const xmlChar *) base); 686 ent->URI = URI; 687 } 688 } else if (ctxt->inSubset == 2) { 689 ent = xmlAddDtdEntity(ctxt->myDoc, name, 690 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY, 691 publicId, systemId, notationName); 692 if ((ent == NULL) && (ctxt->pedantic) && 693 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 694 ctxt->sax->warning(ctxt, 695 "Entity(%s) already defined in the external subset\n", name); 696 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 697 xmlChar *URI; 698 const char *base = NULL; 699 700 if (ctxt->input != NULL) 701 base = ctxt->input->filename; 702 if (base == NULL) 703 base = ctxt->directory; 704 705 URI = xmlBuildURI(systemId, (const xmlChar *) base); 706 ent->URI = URI; 707 } 708 } else { 709 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 710 ctxt->sax->error(ctxt, 711 "SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n", name); 712 } 713} 714 715/** 716 * xmlSAX2SetDocumentLocator: 717 * @ctx: the user data (XML parser context) 718 * @loc: A SAX Locator 719 * 720 * Receive the document locator at startup, actually xmlDefaultSAXLocator 721 * Everything is available on the context, so this is useless in our case. 722 */ 723void 724xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED) 725{ 726 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ 727#ifdef DEBUG_SAX 728 xmlGenericError(xmlGenericErrorContext, 729 "SAX.xmlSAX2SetDocumentLocator()\n"); 730#endif 731} 732 733/** 734 * xmlSAX2StartDocument: 735 * @ctx: the user data (XML parser context) 736 * 737 * called when the document start being processed. 738 */ 739void 740xmlSAX2StartDocument(void *ctx) 741{ 742 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 743 xmlDocPtr doc; 744 745#ifdef DEBUG_SAX 746 xmlGenericError(xmlGenericErrorContext, 747 "SAX.xmlSAX2StartDocument()\n"); 748#endif 749 if (ctxt->html) { 750#ifdef LIBXML_HTML_ENABLED 751 if (ctxt->myDoc == NULL) 752 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL); 753 if (ctxt->myDoc == NULL) { 754 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 755 ctxt->sax->error(ctxt->userData, 756 "SAX.xmlSAX2StartDocument(): out of memory\n"); 757 ctxt->errNo = XML_ERR_NO_MEMORY; 758 ctxt->instate = XML_PARSER_EOF; 759 ctxt->disableSAX = 1; 760 return; 761 } 762#else 763 xmlGenericError(xmlGenericErrorContext, 764 "libxml2 built without HTML support\n"); 765 ctxt->errNo = XML_ERR_INTERNAL_ERROR; 766 ctxt->instate = XML_PARSER_EOF; 767 ctxt->disableSAX = 1; 768 return; 769#endif 770 } else { 771 doc = ctxt->myDoc = xmlNewDoc(ctxt->version); 772 if (doc != NULL) { 773 if (ctxt->encoding != NULL) 774 doc->encoding = xmlStrdup(ctxt->encoding); 775 else 776 doc->encoding = NULL; 777 doc->standalone = ctxt->standalone; 778 } else { 779 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 780 ctxt->sax->error(ctxt->userData, 781 "SAX.xmlSAX2StartDocument(): out of memory\n"); 782 ctxt->errNo = XML_ERR_NO_MEMORY; 783 ctxt->instate = XML_PARSER_EOF; 784 ctxt->disableSAX = 1; 785 return; 786 } 787 } 788 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) && 789 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) { 790 ctxt->myDoc->URL = xmlCanonicPath((const xmlChar *) ctxt->input->filename); 791 if (ctxt->myDoc->URL == NULL) 792 ctxt->myDoc->URL = xmlStrdup((const xmlChar *) ctxt->input->filename); 793 } 794} 795 796/** 797 * xmlSAX2EndDocument: 798 * @ctx: the user data (XML parser context) 799 * 800 * called when the document end has been detected. 801 */ 802void 803xmlSAX2EndDocument(void *ctx) 804{ 805 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 806#ifdef DEBUG_SAX 807 xmlGenericError(xmlGenericErrorContext, 808 "SAX.xmlSAX2EndDocument()\n"); 809#endif 810 if (ctxt->validate && ctxt->wellFormed && 811 ctxt->myDoc && ctxt->myDoc->intSubset) 812 ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc); 813 814 /* 815 * Grab the encoding if it was added on-the-fly 816 */ 817 if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) && 818 (ctxt->myDoc->encoding == NULL)) { 819 ctxt->myDoc->encoding = ctxt->encoding; 820 ctxt->encoding = NULL; 821 } 822 if ((ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) && 823 (ctxt->myDoc->encoding == NULL)) { 824 ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding); 825 } 826 if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) && 827 (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) { 828 ctxt->myDoc->charset = ctxt->charset; 829 } 830} 831 832/** 833 * xmlSAX2AttributeInternal: 834 * @ctx: the user data (XML parser context) 835 * @fullname: The attribute name, including namespace prefix 836 * @value: The attribute value 837 * @prefix: the prefix on the element node 838 * 839 * Handle an attribute that has been read by the parser. 840 * The default handling is to convert the attribute into an 841 * DOM subtree and past it in a new xmlAttr element added to 842 * the element. 843 */ 844static void 845xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname, 846 const xmlChar *value, const xmlChar *prefix) 847{ 848 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 849 xmlAttrPtr ret; 850 xmlChar *name; 851 xmlChar *ns; 852 xmlChar *nval; 853 xmlNsPtr namespace; 854 855 /* 856 * Split the full name into a namespace prefix and the tag name 857 */ 858 name = xmlSplitQName(ctxt, fullname, &ns); 859 if ((name != NULL) && (name[0] == 0)) { 860 if (xmlStrEqual(ns, BAD_CAST "xmlns")) { 861 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 862 ctxt->sax->error(ctxt->userData, 863 "invalid namespace declaration '%s'\n", fullname); 864 } else { 865 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 866 ctxt->sax->warning(ctxt->userData, 867 "Avoid attribute ending with ':' like '%s'\n", fullname); 868 } 869 if (ns != NULL) 870 xmlFree(ns); 871 ns = NULL; 872 xmlFree(name); 873 name = xmlStrdup(fullname); 874 } 875 if (name == NULL) { 876 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 877 ctxt->sax->error(ctxt->userData, 878 "SAX.xmlSAX2StartElement(): out of memory\n"); 879 ctxt->errNo = XML_ERR_NO_MEMORY; 880 ctxt->instate = XML_PARSER_EOF; 881 ctxt->disableSAX = 1; 882 if (ns != NULL) 883 xmlFree(ns); 884 return; 885 } 886 887 /* 888 * Do the last stage of the attribute normalization 889 * Needed for HTML too: 890 * http://www.w3.org/TR/html4/types.html#h-6.2 891 */ 892 ctxt->vctxt.valid = 1; 893 nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt, 894 ctxt->myDoc, ctxt->node, 895 fullname, value); 896 if (ctxt->vctxt.valid != 1) { 897 ctxt->valid = 0; 898 } 899 if (nval != NULL) 900 value = nval; 901 902 /* 903 * Check whether it's a namespace definition 904 */ 905 if ((!ctxt->html) && (ns == NULL) && 906 (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') && 907 (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) { 908 xmlNsPtr nsret; 909 xmlChar *val; 910 911 if (!ctxt->replaceEntities) { 912 ctxt->depth++; 913 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF, 914 0,0,0); 915 ctxt->depth--; 916 } else { 917 val = (xmlChar *) value; 918 } 919 920 if (val[0] != 0) { 921 xmlURIPtr uri; 922 923 uri = xmlParseURI((const char *)val); 924 if (uri == NULL) { 925 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 926 ctxt->sax->warning(ctxt->userData, 927 "nmlns: %s not a valid URI\n", val); 928 } else { 929 if (uri->scheme == NULL) { 930 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 931 ctxt->sax->warning(ctxt->userData, 932 "xmlns: URI %s is not absolute\n", val); 933 } 934 xmlFreeURI(uri); 935 } 936 } 937 938 /* a default namespace definition */ 939 nsret = xmlNewNs(ctxt->node, val, NULL); 940 941 /* 942 * Validate also for namespace decls, they are attributes from 943 * an XML-1.0 perspective 944 */ 945 if (nsret != NULL && ctxt->validate && ctxt->wellFormed && 946 ctxt->myDoc && ctxt->myDoc->intSubset) 947 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc, 948 ctxt->node, prefix, nsret, val); 949 if (name != NULL) 950 xmlFree(name); 951 if (nval != NULL) 952 xmlFree(nval); 953 if (val != value) 954 xmlFree(val); 955 return; 956 } 957 if ((!ctxt->html) && 958 (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') && 959 (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) { 960 xmlNsPtr nsret; 961 xmlChar *val; 962 963 if (!ctxt->replaceEntities) { 964 ctxt->depth++; 965 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF, 966 0,0,0); 967 ctxt->depth--; 968 if (val == NULL) { 969 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 970 ctxt->sax->error(ctxt->userData, 971 "SAX.xmlSAX2StartElement(): out of memory\n"); 972 ctxt->errNo = XML_ERR_NO_MEMORY; 973 ctxt->instate = XML_PARSER_EOF; 974 ctxt->disableSAX = 1; 975 xmlFree(ns); 976 if (name != NULL) 977 xmlFree(name); 978 return; 979 } 980 } else { 981 val = (xmlChar *) value; 982 } 983 984 if (val[0] == 0) { 985 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 986 ctxt->sax->error(ctxt->userData, 987 "Empty namespace name for prefix %s\n", name); 988 } 989 if ((ctxt->pedantic != 0) && (val[0] != 0)) { 990 xmlURIPtr uri; 991 992 uri = xmlParseURI((const char *)val); 993 if (uri == NULL) { 994 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 995 ctxt->sax->warning(ctxt->userData, 996 "xmlns:%s: %s not a valid URI\n", name, value); 997 } else { 998 if (uri->scheme == NULL) { 999 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 1000 ctxt->sax->warning(ctxt->userData, 1001 "xmlns:%s: URI %s is not absolute\n", name, value); 1002 } 1003 xmlFreeURI(uri); 1004 } 1005 } 1006 1007 /* a standard namespace definition */ 1008 nsret = xmlNewNs(ctxt->node, val, name); 1009 xmlFree(ns); 1010 /* 1011 * Validate also for namespace decls, they are attributes from 1012 * an XML-1.0 perspective 1013 */ 1014 if (nsret != NULL && ctxt->validate && ctxt->wellFormed && 1015 ctxt->myDoc && ctxt->myDoc->intSubset) 1016 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc, 1017 ctxt->node, prefix, nsret, value); 1018 if (name != NULL) 1019 xmlFree(name); 1020 if (nval != NULL) 1021 xmlFree(nval); 1022 if (val != value) 1023 xmlFree(val); 1024 return; 1025 } 1026 1027 if (ns != NULL) { 1028 xmlAttrPtr prop; 1029 namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns); 1030 if (namespace == NULL) { 1031 ctxt->sax->error(ctxt->userData, 1032 "Namespace prefix %s of attribute %s is not defined\n", 1033 ns, name); 1034 } 1035 1036 prop = ctxt->node->properties; 1037 while (prop != NULL) { 1038 if (prop->ns != NULL) { 1039 if ((xmlStrEqual(name, prop->name)) && 1040 ((namespace == prop->ns) || 1041 (xmlStrEqual(namespace->href, prop->ns->href)))) { 1042 ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED; 1043 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 1044 ctxt->sax->error(ctxt->userData, 1045 "Attribute %s in %s redefined\n", 1046 name, namespace->href); 1047 ctxt->wellFormed = 0; 1048 if (ctxt->recovery == 0) ctxt->disableSAX = 1; 1049 goto error; 1050 } 1051 } 1052 prop = prop->next; 1053 } 1054 } else { 1055 namespace = NULL; 1056 } 1057 1058 /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */ 1059 ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL); 1060 1061 if (ret != NULL) { 1062 if ((ctxt->replaceEntities == 0) && (!ctxt->html)) { 1063 xmlNodePtr tmp; 1064 1065 ret->children = xmlStringGetNodeList(ctxt->myDoc, value); 1066 tmp = ret->children; 1067 while (tmp != NULL) { 1068 tmp->parent = (xmlNodePtr) ret; 1069 if (tmp->next == NULL) 1070 ret->last = tmp; 1071 tmp = tmp->next; 1072 } 1073 } else if (value != NULL) { 1074 ret->children = xmlNewDocText(ctxt->myDoc, value); 1075 ret->last = ret->children; 1076 if (ret->children != NULL) 1077 ret->children->parent = (xmlNodePtr) ret; 1078 } 1079 } 1080 1081 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed && 1082 ctxt->myDoc && ctxt->myDoc->intSubset) { 1083 1084 /* 1085 * If we don't substitute entities, the validation should be 1086 * done on a value with replaced entities anyway. 1087 */ 1088 if (!ctxt->replaceEntities) { 1089 xmlChar *val; 1090 1091 ctxt->depth++; 1092 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF, 1093 0,0,0); 1094 ctxt->depth--; 1095 1096 if (val == NULL) 1097 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 1098 ctxt->myDoc, ctxt->node, ret, value); 1099 else { 1100 xmlChar *nvalnorm; 1101 1102 /* 1103 * Do the last stage of the attribute normalization 1104 * It need to be done twice ... it's an extra burden related 1105 * to the ability to keep xmlSAX2References in attributes 1106 */ 1107 nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc, 1108 ctxt->node, fullname, val); 1109 if (nvalnorm != NULL) { 1110 xmlFree(val); 1111 val = nvalnorm; 1112 } 1113 1114 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 1115 ctxt->myDoc, ctxt->node, ret, val); 1116 xmlFree(val); 1117 } 1118 } else { 1119 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, 1120 ctxt->node, ret, value); 1121 } 1122 } else if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) && 1123 (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) || 1124 ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) { 1125 /* 1126 * when validating, the ID registration is done at the attribute 1127 * validation level. Otherwise we have to do specific handling here. 1128 */ 1129 if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) 1130 xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret); 1131 else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) 1132 xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret); 1133 } 1134 1135error: 1136 if (nval != NULL) 1137 xmlFree(nval); 1138 if (ns != NULL) 1139 xmlFree(ns); 1140} 1141 1142/** 1143 * attribute: 1144 * @ctx: the user data (XML parser context) 1145 * @fullname: The attribute name, including namespace prefix 1146 * @value: The attribute value 1147 * 1148 * Handle an attribute that has been read by the parser. 1149 * The default handling is to convert the attribute into an 1150 * DOM subtree and past it in a new xmlAttr element added to 1151 * the element. 1152 */ 1153static void 1154xmlSAX2Attribute(void *ctx, const xmlChar *fullname, const xmlChar *value) 1155{ 1156 xmlSAX2AttributeInternal(ctx, fullname, value, NULL); 1157} 1158 1159/* 1160 * xmlCheckDefaultedAttributes: 1161 * 1162 * Check defaulted attributes from the DTD 1163 */ 1164static void 1165xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name, 1166 const xmlChar *prefix, const xmlChar **atts) { 1167 xmlElementPtr elemDecl; 1168 const xmlChar *att; 1169 int internal = 1; 1170 int i; 1171 1172 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix); 1173 if (elemDecl == NULL) { 1174 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix); 1175 internal = 0; 1176 } 1177 1178process_external_subset: 1179 1180 if (elemDecl != NULL) { 1181 xmlAttributePtr attr = elemDecl->attributes; 1182 /* 1183 * Check against defaulted attributes from the external subset 1184 * if the document is stamped as standalone 1185 */ 1186 if ((ctxt->myDoc->standalone == 1) && 1187 (ctxt->myDoc->extSubset != NULL) && 1188 (ctxt->validate)) { 1189 while (attr != NULL) { 1190 if ((attr->defaultValue != NULL) && 1191 (xmlGetDtdQAttrDesc(ctxt->myDoc->extSubset, 1192 attr->elem, attr->name, 1193 attr->prefix) == attr) && 1194 (xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset, 1195 attr->elem, attr->name, 1196 attr->prefix) == NULL)) { 1197 xmlChar *fulln; 1198 1199 if (attr->prefix != NULL) { 1200 fulln = xmlStrdup(attr->prefix); 1201 fulln = xmlStrcat(fulln, BAD_CAST ":"); 1202 fulln = xmlStrcat(fulln, attr->name); 1203 } else { 1204 fulln = xmlStrdup(attr->name); 1205 } 1206 1207 /* 1208 * Check that the attribute is not declared in the 1209 * serialization 1210 */ 1211 att = NULL; 1212 if (atts != NULL) { 1213 i = 0; 1214 att = atts[i]; 1215 while (att != NULL) { 1216 if (xmlStrEqual(att, fulln)) 1217 break; 1218 i += 2; 1219 att = atts[i]; 1220 } 1221 } 1222 if (att == NULL) { 1223 if (ctxt->vctxt.error != NULL) 1224 ctxt->vctxt.error(ctxt->vctxt.userData, 1225 "standalone: attribute %s on %s defaulted from external subset\n", 1226 fulln, attr->elem); 1227 ctxt->valid = 0; 1228 } 1229 } 1230 attr = attr->nexth; 1231 } 1232 } 1233 1234 /* 1235 * Actually insert defaulted values when needed 1236 */ 1237 attr = elemDecl->attributes; 1238 while (attr != NULL) { 1239 /* 1240 * Make sure that attributes redefinition occuring in the 1241 * internal subset are not overriden by definitions in the 1242 * external subset. 1243 */ 1244 if (attr->defaultValue != NULL) { 1245 /* 1246 * the element should be instantiated in the tree if: 1247 * - this is a namespace prefix 1248 * - the user required for completion in the tree 1249 * like XSLT 1250 * - there isn't already an attribute definition 1251 * in the internal subset overriding it. 1252 */ 1253 if (((attr->prefix != NULL) && 1254 (xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) || 1255 ((attr->prefix == NULL) && 1256 (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) || 1257 (ctxt->loadsubset & XML_COMPLETE_ATTRS)) { 1258 xmlAttributePtr tst; 1259 1260 tst = xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset, 1261 attr->elem, attr->name, 1262 attr->prefix); 1263 if ((tst == attr) || (tst == NULL)) { 1264 xmlChar fn[50]; 1265 xmlChar *fulln; 1266 1267 fulln = xmlBuildQName(attr->name, attr->prefix, fn, 50); 1268 if (fulln == NULL) { 1269 if ((ctxt->sax != NULL) && 1270 (ctxt->sax->error != NULL)) 1271 ctxt->sax->error(ctxt->userData, 1272 "SAX.xmlSAX2StartElement(): out of memory\n"); 1273 ctxt->errNo = XML_ERR_NO_MEMORY; 1274 ctxt->instate = XML_PARSER_EOF; 1275 ctxt->disableSAX = 1; 1276 return; 1277 } 1278 1279 /* 1280 * Check that the attribute is not declared in the 1281 * serialization 1282 */ 1283 att = NULL; 1284 if (atts != NULL) { 1285 i = 0; 1286 att = atts[i]; 1287 while (att != NULL) { 1288 if (xmlStrEqual(att, fulln)) 1289 break; 1290 i += 2; 1291 att = atts[i]; 1292 } 1293 } 1294 if (att == NULL) { 1295 xmlSAX2AttributeInternal(ctxt, fulln, 1296 attr->defaultValue, prefix); 1297 } 1298 if ((fulln != fn) && (fulln != attr->name)) 1299 xmlFree(fulln); 1300 } 1301 } 1302 } 1303 attr = attr->nexth; 1304 } 1305 if (internal == 1) { 1306 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, 1307 name, prefix); 1308 internal = 0; 1309 goto process_external_subset; 1310 } 1311 } 1312} 1313 1314/** 1315 * xmlSAX2StartElement: 1316 * @ctx: the user data (XML parser context) 1317 * @fullname: The element name, including namespace prefix 1318 * @atts: An array of name/value attributes pairs, NULL terminated 1319 * 1320 * called when an opening tag has been processed. 1321 */ 1322void 1323xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts) 1324{ 1325 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 1326 xmlNodePtr ret; 1327 xmlNodePtr parent = ctxt->node; 1328 xmlNsPtr ns; 1329 xmlChar *name; 1330 xmlChar *prefix; 1331 const xmlChar *att; 1332 const xmlChar *value; 1333 int i; 1334 1335#ifdef DEBUG_SAX 1336 xmlGenericError(xmlGenericErrorContext, 1337 "SAX.xmlSAX2StartElement(%s)\n", fullname); 1338#endif 1339 1340 /* 1341 * First check on validity: 1342 */ 1343 if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) && 1344 ((ctxt->myDoc->intSubset == NULL) || 1345 ((ctxt->myDoc->intSubset->notations == NULL) && 1346 (ctxt->myDoc->intSubset->elements == NULL) && 1347 (ctxt->myDoc->intSubset->attributes == NULL) && 1348 (ctxt->myDoc->intSubset->entities == NULL)))) { 1349 if (ctxt->vctxt.error != NULL) { 1350 ctxt->vctxt.error(ctxt->vctxt.userData, 1351 "Validation failed: no DTD found !\n"); 1352 } 1353 ctxt->validate = 0; 1354 ctxt->valid = 0; 1355 ctxt->errNo = XML_ERR_NO_DTD; 1356 } 1357 1358 1359 /* 1360 * Split the full name into a namespace prefix and the tag name 1361 */ 1362 name = xmlSplitQName(ctxt, fullname, &prefix); 1363 1364 1365 /* 1366 * Note : the namespace resolution is deferred until the end of the 1367 * attributes parsing, since local namespace can be defined as 1368 * an attribute at this level. 1369 */ 1370 ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL); 1371 if (ret == NULL) { 1372 if (prefix != NULL) 1373 xmlFree(prefix); 1374 ctxt->errNo = XML_ERR_NO_MEMORY; 1375 ctxt->instate = XML_PARSER_EOF; 1376 ctxt->disableSAX = 1; 1377 return; 1378 } 1379 if (ctxt->myDoc->children == NULL) { 1380#ifdef DEBUG_SAX_TREE 1381 xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name); 1382#endif 1383 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); 1384 } else if (parent == NULL) { 1385 parent = ctxt->myDoc->children; 1386 } 1387 ctxt->nodemem = -1; 1388 if (ctxt->linenumbers) { 1389 if (ctxt->input != NULL) 1390 ret->content = (void *) (long) ctxt->input->line; 1391 } 1392 1393 /* 1394 * We are parsing a new node. 1395 */ 1396#ifdef DEBUG_SAX_TREE 1397 xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name); 1398#endif 1399 nodePush(ctxt, ret); 1400 1401 /* 1402 * Link the child element 1403 */ 1404 if (parent != NULL) { 1405 if (parent->type == XML_ELEMENT_NODE) { 1406#ifdef DEBUG_SAX_TREE 1407 xmlGenericError(xmlGenericErrorContext, 1408 "adding child %s to %s\n", name, parent->name); 1409#endif 1410 xmlAddChild(parent, ret); 1411 } else { 1412#ifdef DEBUG_SAX_TREE 1413 xmlGenericError(xmlGenericErrorContext, 1414 "adding sibling %s to ", name); 1415 xmlDebugDumpOneNode(stderr, parent, 0); 1416#endif 1417 xmlAddSibling(parent, ret); 1418 } 1419 } 1420 1421 /* 1422 * Insert all the defaulted attributes from the DTD especially namespaces 1423 */ 1424 if ((!ctxt->html) && 1425 ((ctxt->myDoc->intSubset != NULL) || 1426 (ctxt->myDoc->extSubset != NULL))) { 1427 xmlCheckDefaultedAttributes(ctxt, name, prefix, atts); 1428 } 1429 1430 /* 1431 * process all the attributes whose name start with "xmlns" 1432 */ 1433 if (atts != NULL) { 1434 i = 0; 1435 att = atts[i++]; 1436 value = atts[i++]; 1437 if (!ctxt->html) { 1438 while ((att != NULL) && (value != NULL)) { 1439 if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') && 1440 (att[3] == 'n') && (att[4] == 's')) 1441 xmlSAX2AttributeInternal(ctxt, att, value, prefix); 1442 1443 att = atts[i++]; 1444 value = atts[i++]; 1445 } 1446 } 1447 } 1448 1449 /* 1450 * Search the namespace, note that since the attributes have been 1451 * processed, the local namespaces are available. 1452 */ 1453 ns = xmlSearchNs(ctxt->myDoc, ret, prefix); 1454 if ((ns == NULL) && (parent != NULL)) 1455 ns = xmlSearchNs(ctxt->myDoc, parent, prefix); 1456 if ((prefix != NULL) && (ns == NULL)) { 1457 ns = xmlNewNs(ret, NULL, prefix); 1458 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 1459 ctxt->sax->warning(ctxt->userData, 1460 "Namespace prefix %s is not defined\n", prefix); 1461 } 1462 1463 /* 1464 * set the namespace node, making sure that if the default namspace 1465 * is unbound on a parent we simply kee it NULL 1466 */ 1467 if ((ns != NULL) && (ns->href != NULL) && 1468 ((ns->href[0] != 0) || (ns->prefix != NULL))) 1469 xmlSetNs(ret, ns); 1470 1471 /* 1472 * process all the other attributes 1473 */ 1474 if (atts != NULL) { 1475 i = 0; 1476 att = atts[i++]; 1477 value = atts[i++]; 1478 if (ctxt->html) { 1479 while (att != NULL) { 1480 xmlSAX2AttributeInternal(ctxt, att, value, NULL); 1481 att = atts[i++]; 1482 value = atts[i++]; 1483 } 1484 } else { 1485 while ((att != NULL) && (value != NULL)) { 1486 if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l') || 1487 (att[3] != 'n') || (att[4] != 's')) 1488 xmlSAX2AttributeInternal(ctxt, att, value, NULL); 1489 1490 /* 1491 * Next ones 1492 */ 1493 att = atts[i++]; 1494 value = atts[i++]; 1495 } 1496 } 1497 } 1498 1499 /* 1500 * If it's the Document root, finish the DTD validation and 1501 * check the document root element for validity 1502 */ 1503 if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) { 1504 int chk; 1505 1506 chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc); 1507 if (chk <= 0) 1508 ctxt->valid = 0; 1509 if (chk < 0) 1510 ctxt->wellFormed = 0; 1511 ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc); 1512 ctxt->vctxt.finishDtd = 1; 1513 } 1514 1515 if (prefix != NULL) 1516 xmlFree(prefix); 1517 1518} 1519 1520/** 1521 * xmlSAX2EndElement: 1522 * @ctx: the user data (XML parser context) 1523 * @name: The element name 1524 * 1525 * called when the end of an element has been detected. 1526 */ 1527void 1528xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED) 1529{ 1530 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 1531 xmlParserNodeInfo node_info; 1532 xmlNodePtr cur = ctxt->node; 1533 1534#ifdef DEBUG_SAX 1535 if (name == NULL) 1536 xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(NULL)\n"); 1537 else 1538 xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(%s)\n", name); 1539#endif 1540 1541 /* Capture end position and add node */ 1542 if (cur != NULL && ctxt->record_info) { 1543 node_info.end_pos = ctxt->input->cur - ctxt->input->base; 1544 node_info.end_line = ctxt->input->line; 1545 node_info.node = cur; 1546 xmlParserAddNodeInfo(ctxt, &node_info); 1547 } 1548 ctxt->nodemem = -1; 1549 1550 if (ctxt->validate && ctxt->wellFormed && 1551 ctxt->myDoc && ctxt->myDoc->intSubset) 1552 ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, 1553 cur); 1554 1555 1556 /* 1557 * end of parsing of this node. 1558 */ 1559#ifdef DEBUG_SAX_TREE 1560 xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name); 1561#endif 1562 nodePop(ctxt); 1563} 1564 1565/** 1566 * xmlSAX2Reference: 1567 * @ctx: the user data (XML parser context) 1568 * @name: The entity name 1569 * 1570 * called when an entity xmlSAX2Reference is detected. 1571 */ 1572void 1573xmlSAX2Reference(void *ctx, const xmlChar *name) 1574{ 1575 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 1576 xmlNodePtr ret; 1577 1578#ifdef DEBUG_SAX 1579 xmlGenericError(xmlGenericErrorContext, 1580 "SAX.xmlSAX2Reference(%s)\n", name); 1581#endif 1582 if (name[0] == '#') 1583 ret = xmlNewCharRef(ctxt->myDoc, name); 1584 else 1585 ret = xmlNewReference(ctxt->myDoc, name); 1586#ifdef DEBUG_SAX_TREE 1587 xmlGenericError(xmlGenericErrorContext, 1588 "add xmlSAX2Reference %s to %s \n", name, ctxt->node->name); 1589#endif 1590 xmlAddChild(ctxt->node, ret); 1591} 1592 1593/** 1594 * xmlSAX2Characters: 1595 * @ctx: the user data (XML parser context) 1596 * @ch: a xmlChar string 1597 * @len: the number of xmlChar 1598 * 1599 * receiving some chars from the parser. 1600 */ 1601void 1602xmlSAX2Characters(void *ctx, const xmlChar *ch, int len) 1603{ 1604 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 1605 xmlNodePtr lastChild; 1606 1607#ifdef DEBUG_SAX 1608 xmlGenericError(xmlGenericErrorContext, 1609 "SAX.xmlSAX2Characters(%.30s, %d)\n", ch, len); 1610#endif 1611 /* 1612 * Handle the data if any. If there is no child 1613 * add it as content, otherwise if the last child is text, 1614 * concatenate it, else create a new node of type text. 1615 */ 1616 1617 if (ctxt->node == NULL) { 1618#ifdef DEBUG_SAX_TREE 1619 xmlGenericError(xmlGenericErrorContext, 1620 "add chars: ctxt->node == NULL !\n"); 1621#endif 1622 return; 1623 } 1624 lastChild = xmlGetLastChild(ctxt->node); 1625#ifdef DEBUG_SAX_TREE 1626 xmlGenericError(xmlGenericErrorContext, 1627 "add chars to %s \n", ctxt->node->name); 1628#endif 1629 1630 /* 1631 * Here we needed an accelerator mechanism in case of very large 1632 * elements. Use an attribute in the structure !!! 1633 */ 1634 if (lastChild == NULL) { 1635 /* first node, first time */ 1636 xmlNodeAddContentLen(ctxt->node, ch, len); 1637 if (ctxt->node->children != NULL) { 1638 ctxt->nodelen = len; 1639 ctxt->nodemem = len + 1; 1640 } 1641 } else { 1642 int coalesceText = (lastChild != NULL) && 1643 (lastChild->type == XML_TEXT_NODE) && 1644 (lastChild->name == xmlStringText); 1645 if ((coalesceText) && (ctxt->nodemem != 0)) { 1646 /* 1647 * The whole point of maintaining nodelen and nodemem, 1648 * xmlTextConcat is too costly, i.e. compute length, 1649 * reallocate a new buffer, move data, append ch. Here 1650 * We try to minimaze realloc() uses and avoid copying 1651 * and recomputing length over and over. 1652 */ 1653 if (ctxt->nodelen + len >= ctxt->nodemem) { 1654 xmlChar *newbuf; 1655 int size; 1656 1657 size = ctxt->nodemem + len; 1658 size *= 2; 1659 newbuf = (xmlChar *) xmlRealloc(lastChild->content,size); 1660 if (newbuf == NULL) { 1661 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 1662 ctxt->sax->error(ctxt->userData, 1663 "SAX.xmlSAX2Characters(): out of memory\n"); 1664 ctxt->errNo = XML_ERR_NO_MEMORY; 1665 ctxt->instate = XML_PARSER_EOF; 1666 ctxt->disableSAX = 1; 1667 return; 1668 } 1669 ctxt->nodemem = size; 1670 lastChild->content = newbuf; 1671 } 1672 memcpy(&lastChild->content[ctxt->nodelen], ch, len); 1673 ctxt->nodelen += len; 1674 lastChild->content[ctxt->nodelen] = 0; 1675 } else if (coalesceText) { 1676 if (xmlTextConcat(lastChild, ch, len)) { 1677 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 1678 ctxt->sax->error(ctxt->userData, 1679 "SAX.xmlSAX2Characters(): out of memory\n"); 1680 ctxt->errNo = XML_ERR_NO_MEMORY; 1681 ctxt->instate = XML_PARSER_EOF; 1682 ctxt->disableSAX = 1; 1683 } 1684 if (ctxt->node->children != NULL) { 1685 ctxt->nodelen = xmlStrlen(lastChild->content); 1686 ctxt->nodemem = ctxt->nodelen + 1; 1687 } 1688 } else { 1689 /* Mixed content, first time */ 1690 lastChild = xmlNewTextLen(ch, len); 1691 if (lastChild == NULL) { 1692 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 1693 ctxt->sax->error(ctxt->userData, 1694 "SAX.xmlSAX2Characters(): out of memory\n"); 1695 ctxt->errNo = XML_ERR_NO_MEMORY; 1696 ctxt->instate = XML_PARSER_EOF; 1697 ctxt->disableSAX = 1; 1698 } else { 1699 xmlAddChild(ctxt->node, lastChild); 1700 if (ctxt->node->children != NULL) { 1701 ctxt->nodelen = len; 1702 ctxt->nodemem = len + 1; 1703 } 1704 } 1705 } 1706 } 1707} 1708 1709/** 1710 * xmlSAX2IgnorableWhitespace: 1711 * @ctx: the user data (XML parser context) 1712 * @ch: a xmlChar string 1713 * @len: the number of xmlChar 1714 * 1715 * receiving some ignorable whitespaces from the parser. 1716 * UNUSED: by default the DOM building will use xmlSAX2Characters 1717 */ 1718void 1719xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED) 1720{ 1721 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ 1722#ifdef DEBUG_SAX 1723 xmlGenericError(xmlGenericErrorContext, 1724 "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch, len); 1725#endif 1726} 1727 1728/** 1729 * xmlSAX2ProcessingInstruction: 1730 * @ctx: the user data (XML parser context) 1731 * @target: the target name 1732 * @data: the PI data's 1733 * 1734 * A processing instruction has been parsed. 1735 */ 1736void 1737xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target, 1738 const xmlChar *data) 1739{ 1740 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 1741 xmlNodePtr ret; 1742 xmlNodePtr parent = ctxt->node; 1743 1744#ifdef DEBUG_SAX 1745 xmlGenericError(xmlGenericErrorContext, 1746 "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target, data); 1747#endif 1748 1749 ret = xmlNewPI(target, data); 1750 if (ret == NULL) return; 1751 parent = ctxt->node; 1752 1753 if (ctxt->inSubset == 1) { 1754 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret); 1755 return; 1756 } else if (ctxt->inSubset == 2) { 1757 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret); 1758 return; 1759 } 1760 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) { 1761#ifdef DEBUG_SAX_TREE 1762 xmlGenericError(xmlGenericErrorContext, 1763 "Setting PI %s as root\n", target); 1764#endif 1765 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); 1766 return; 1767 } 1768 if (parent->type == XML_ELEMENT_NODE) { 1769#ifdef DEBUG_SAX_TREE 1770 xmlGenericError(xmlGenericErrorContext, 1771 "adding PI %s child to %s\n", target, parent->name); 1772#endif 1773 xmlAddChild(parent, ret); 1774 } else { 1775#ifdef DEBUG_SAX_TREE 1776 xmlGenericError(xmlGenericErrorContext, 1777 "adding PI %s sibling to ", target); 1778 xmlDebugDumpOneNode(stderr, parent, 0); 1779#endif 1780 xmlAddSibling(parent, ret); 1781 } 1782} 1783 1784/** 1785 * xmlSAX2Comment: 1786 * @ctx: the user data (XML parser context) 1787 * @value: the xmlSAX2Comment content 1788 * 1789 * A xmlSAX2Comment has been parsed. 1790 */ 1791void 1792xmlSAX2Comment(void *ctx, const xmlChar *value) 1793{ 1794 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 1795 xmlNodePtr ret; 1796 xmlNodePtr parent = ctxt->node; 1797 1798#ifdef DEBUG_SAX 1799 xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Comment(%s)\n", value); 1800#endif 1801 ret = xmlNewDocComment(ctxt->myDoc, value); 1802 if (ret == NULL) return; 1803 1804 if (ctxt->inSubset == 1) { 1805 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret); 1806 return; 1807 } else if (ctxt->inSubset == 2) { 1808 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret); 1809 return; 1810 } 1811 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) { 1812#ifdef DEBUG_SAX_TREE 1813 xmlGenericError(xmlGenericErrorContext, 1814 "Setting xmlSAX2Comment as root\n"); 1815#endif 1816 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); 1817 return; 1818 } 1819 if (parent->type == XML_ELEMENT_NODE) { 1820#ifdef DEBUG_SAX_TREE 1821 xmlGenericError(xmlGenericErrorContext, 1822 "adding xmlSAX2Comment child to %s\n", parent->name); 1823#endif 1824 xmlAddChild(parent, ret); 1825 } else { 1826#ifdef DEBUG_SAX_TREE 1827 xmlGenericError(xmlGenericErrorContext, 1828 "adding xmlSAX2Comment sibling to "); 1829 xmlDebugDumpOneNode(stderr, parent, 0); 1830#endif 1831 xmlAddSibling(parent, ret); 1832 } 1833} 1834 1835/** 1836 * xmlSAX2CDataBlock: 1837 * @ctx: the user data (XML parser context) 1838 * @value: The pcdata content 1839 * @len: the block length 1840 * 1841 * called when a pcdata block has been parsed 1842 */ 1843void 1844xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len) 1845{ 1846 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 1847 xmlNodePtr ret, lastChild; 1848 1849#ifdef DEBUG_SAX 1850 xmlGenericError(xmlGenericErrorContext, 1851 "SAX.pcdata(%.10s, %d)\n", value, len); 1852#endif 1853 lastChild = xmlGetLastChild(ctxt->node); 1854#ifdef DEBUG_SAX_TREE 1855 xmlGenericError(xmlGenericErrorContext, 1856 "add chars to %s \n", ctxt->node->name); 1857#endif 1858 if ((lastChild != NULL) && 1859 (lastChild->type == XML_CDATA_SECTION_NODE)) { 1860 xmlTextConcat(lastChild, value, len); 1861 } else { 1862 ret = xmlNewCDataBlock(ctxt->myDoc, value, len); 1863 xmlAddChild(ctxt->node, ret); 1864 } 1865} 1866 1867/** 1868 * xmlSAX2InitDefaultSAXHandler: 1869 * @hdlr: the SAX handler 1870 * @warning: flag if non-zero sets the handler warning procedure 1871 * 1872 * Initialize the default XML SAX2 handler 1873 */ 1874void 1875xmlSAX2InitDefaultSAXHandler(xmlSAXHandler *hdlr, int warning) 1876{ 1877 if (hdlr->initialized != 0) 1878 return; 1879 1880 hdlr->internalSubset = xmlSAX2InternalSubset; 1881 hdlr->externalSubset = xmlSAX2ExternalSubset; 1882 hdlr->isStandalone = xmlSAX2IsStandalone; 1883 hdlr->hasInternalSubset = xmlSAX2HasInternalSubset; 1884 hdlr->hasExternalSubset = xmlSAX2HasExternalSubset; 1885 hdlr->resolveEntity = xmlSAX2ResolveEntity; 1886 hdlr->getEntity = xmlSAX2GetEntity; 1887 hdlr->getParameterEntity = xmlSAX2GetParameterEntity; 1888 hdlr->entityDecl = xmlSAX2EntityDecl; 1889 hdlr->attributeDecl = xmlSAX2AttributeDecl; 1890 hdlr->elementDecl = xmlSAX2ElementDecl; 1891 hdlr->notationDecl = xmlSAX2NotationDecl; 1892 hdlr->unparsedEntityDecl = xmlSAX2UnparsedEntityDecl; 1893 hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator; 1894 hdlr->startDocument = xmlSAX2StartDocument; 1895 hdlr->endDocument = xmlSAX2EndDocument; 1896 hdlr->startElement = xmlSAX2StartElement; 1897 hdlr->endElement = xmlSAX2EndElement; 1898 hdlr->reference = xmlSAX2Reference; 1899 hdlr->characters = xmlSAX2Characters; 1900 hdlr->cdataBlock = xmlSAX2CDataBlock; 1901 hdlr->ignorableWhitespace = xmlSAX2Characters; 1902 hdlr->processingInstruction = xmlSAX2ProcessingInstruction; 1903 hdlr->comment = xmlSAX2Comment; 1904 /* if (xmlGetWarningsDefaultValue == 0) */ 1905 if (warning == 0) 1906 hdlr->warning = NULL; 1907 else 1908 hdlr->warning = xmlParserWarning; 1909 hdlr->error = xmlParserError; 1910 hdlr->fatalError = xmlParserError; 1911 1912 hdlr->initialized = XML_SAX2_MAGIC; 1913} 1914 1915/** 1916 * xmlDefaultSAXHandlerInit: 1917 * 1918 * Initialize the default SAX2 handler 1919 */ 1920void 1921xmlDefaultSAXHandlerInit(void) 1922{ 1923 xmlSAX2InitDefaultSAXHandler(&xmlDefaultSAXHandler, 1924 xmlGetWarningsDefaultValue); 1925} 1926 1927#ifdef LIBXML_HTML_ENABLED 1928 1929/** 1930 * xmlSAX2InitHtmlDefaultSAXHandler: 1931 * @hdlr: the SAX handler 1932 * 1933 * Initialize the default HTML SAX2 handler 1934 */ 1935void 1936xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr) 1937{ 1938 if(hdlr->initialized != 0) 1939 return; 1940 1941 hdlr->internalSubset = xmlSAX2InternalSubset; 1942 hdlr->externalSubset = NULL; 1943 hdlr->isStandalone = NULL; 1944 hdlr->hasInternalSubset = NULL; 1945 hdlr->hasExternalSubset = NULL; 1946 hdlr->resolveEntity = NULL; 1947 hdlr->getEntity = xmlSAX2GetEntity; 1948 hdlr->getParameterEntity = NULL; 1949 hdlr->entityDecl = NULL; 1950 hdlr->attributeDecl = NULL; 1951 hdlr->elementDecl = NULL; 1952 hdlr->notationDecl = NULL; 1953 hdlr->unparsedEntityDecl = NULL; 1954 hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator; 1955 hdlr->startDocument = xmlSAX2StartDocument; 1956 hdlr->endDocument = xmlSAX2EndDocument; 1957 hdlr->startElement = xmlSAX2StartElement; 1958 hdlr->endElement = xmlSAX2EndElement; 1959 hdlr->reference = NULL; 1960 hdlr->characters = xmlSAX2Characters; 1961 hdlr->cdataBlock = xmlSAX2CDataBlock; 1962 hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace; 1963 hdlr->processingInstruction = NULL; 1964 hdlr->comment = xmlSAX2Comment; 1965 hdlr->warning = xmlParserWarning; 1966 hdlr->error = xmlParserError; 1967 hdlr->fatalError = xmlParserError; 1968 1969 hdlr->initialized = XML_SAX2_MAGIC; 1970} 1971 1972/** 1973 * htmlDefaultSAXHandlerInit: 1974 * 1975 * Initialize the default SAX handler 1976 */ 1977void 1978htmlDefaultSAXHandlerInit(void) 1979{ 1980 xmlSAX2InitHtmlDefaultSAXHandler(&htmlDefaultSAXHandler); 1981} 1982 1983#endif /* LIBXML_HTML_ENABLED */ 1984 1985#ifdef LIBXML_DOCB_ENABLED 1986 1987/** 1988 * xmlSAX2InitDocbDefaultSAXHandler: 1989 * @hdlr: the SAX handler 1990 * 1991 * Initialize the default DocBook SAX2 handler 1992 */ 1993void 1994xmlSAX2InitDocbDefaultSAXHandler(xmlSAXHandler *hdlr) 1995{ 1996 if(hdlr->initialized != 0) 1997 return; 1998 1999 hdlr->internalSubset = xmlSAX2InternalSubset; 2000 hdlr->externalSubset = NULL; 2001 hdlr->isStandalone = xmlSAX2IsStandalone; 2002 hdlr->hasInternalSubset = xmlSAX2HasInternalSubset; 2003 hdlr->hasExternalSubset = xmlSAX2HasExternalSubset; 2004 hdlr->resolveEntity = xmlSAX2ResolveEntity; 2005 hdlr->getEntity = xmlSAX2GetEntity; 2006 hdlr->getParameterEntity = NULL; 2007 hdlr->entityDecl = xmlSAX2EntityDecl; 2008 hdlr->attributeDecl = NULL; 2009 hdlr->elementDecl = NULL; 2010 hdlr->notationDecl = NULL; 2011 hdlr->unparsedEntityDecl = NULL; 2012 hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator; 2013 hdlr->startDocument = xmlSAX2StartDocument; 2014 hdlr->endDocument = xmlSAX2EndDocument; 2015 hdlr->startElement = xmlSAX2StartElement; 2016 hdlr->endElement = xmlSAX2EndElement; 2017 hdlr->reference = xmlSAX2Reference; 2018 hdlr->characters = xmlSAX2Characters; 2019 hdlr->cdataBlock = NULL; 2020 hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace; 2021 hdlr->processingInstruction = NULL; 2022 hdlr->comment = xmlSAX2Comment; 2023 hdlr->warning = xmlParserWarning; 2024 hdlr->error = xmlParserError; 2025 hdlr->fatalError = xmlParserError; 2026 2027 hdlr->initialized = XML_SAX2_MAGIC; 2028} 2029 2030/** 2031 * docbDefaultSAXHandlerInit: 2032 * 2033 * Initialize the default SAX handler 2034 */ 2035void 2036docbDefaultSAXHandlerInit(void) 2037{ 2038 xmlSAX2InitDocbDefaultSAXHandler(&docbDefaultSAXHandler); 2039} 2040 2041#endif /* LIBXML_DOCB_ENABLED */ 2042