SAX2.c revision a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4
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 * TODO: 34 * 35 * macro to flag unimplemented blocks 36 * XML_CATALOG_PREFER user env to select between system/public prefered 37 * option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk> 38 *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with 39 *> values "system" and "public". I have made the default be "system" to 40 *> match yours. 41 */ 42#define TODO \ 43 xmlGenericError(xmlGenericErrorContext, \ 44 "Unimplemented block at %s:%d\n", \ 45 __FILE__, __LINE__); 46 47/** 48 * xmlSAX2GetPublicId: 49 * @ctx: the user data (XML parser context) 50 * 51 * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN" 52 * 53 * Returns a xmlChar * 54 */ 55const xmlChar * 56xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED) 57{ 58 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ 59 return(NULL); 60} 61 62/** 63 * xmlSAX2GetSystemId: 64 * @ctx: the user data (XML parser context) 65 * 66 * Provides the system ID, basically URL or filename e.g. 67 * http://www.sgmlsource.com/dtds/memo.dtd 68 * 69 * Returns a xmlChar * 70 */ 71const xmlChar * 72xmlSAX2GetSystemId(void *ctx) 73{ 74 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 75 return((const xmlChar *) ctxt->input->filename); 76} 77 78/** 79 * xmlSAX2GetLineNumber: 80 * @ctx: the user data (XML parser context) 81 * 82 * Provide the line number of the current parsing point. 83 * 84 * Returns an int 85 */ 86int 87xmlSAX2GetLineNumber(void *ctx) 88{ 89 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 90 return(ctxt->input->line); 91} 92 93/** 94 * xmlSAX2GetColumnNumber: 95 * @ctx: the user data (XML parser context) 96 * 97 * Provide the column number of the current parsing point. 98 * 99 * Returns an int 100 */ 101int 102xmlSAX2GetColumnNumber(void *ctx) 103{ 104 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 105 return(ctxt->input->col); 106} 107 108/** 109 * xmlSAX2IsStandalone: 110 * @ctx: the user data (XML parser context) 111 * 112 * Is this document tagged standalone ? 113 * 114 * Returns 1 if true 115 */ 116int 117xmlSAX2IsStandalone(void *ctx) 118{ 119 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 120 return(ctxt->myDoc->standalone == 1); 121} 122 123/** 124 * xmlSAX2HasInternalSubset: 125 * @ctx: the user data (XML parser context) 126 * 127 * Does this document has an internal subset 128 * 129 * Returns 1 if true 130 */ 131int 132xmlSAX2HasInternalSubset(void *ctx) 133{ 134 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 135 return(ctxt->myDoc->intSubset != NULL); 136} 137 138/** 139 * xmlSAX2HasExternalSubset: 140 * @ctx: the user data (XML parser context) 141 * 142 * Does this document has an external subset 143 * 144 * Returns 1 if true 145 */ 146int 147xmlSAX2HasExternalSubset(void *ctx) 148{ 149 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 150 return(ctxt->myDoc->extSubset != NULL); 151} 152 153/** 154 * xmlSAX2InternalSubset: 155 * @ctx: the user data (XML parser context) 156 * @name: the root element name 157 * @ExternalID: the external ID 158 * @SystemID: the SYSTEM ID (e.g. filename or URL) 159 * 160 * Callback on internal subset declaration. 161 */ 162void 163xmlSAX2InternalSubset(void *ctx, const xmlChar *name, 164 const xmlChar *ExternalID, const xmlChar *SystemID) 165{ 166 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 167 xmlDtdPtr dtd; 168#ifdef DEBUG_SAX 169 xmlGenericError(xmlGenericErrorContext, 170 "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n", 171 name, ExternalID, SystemID); 172#endif 173 174 if (ctxt->myDoc == NULL) 175 return; 176 dtd = xmlGetIntSubset(ctxt->myDoc); 177 if (dtd != NULL) { 178 if (ctxt->html) 179 return; 180 xmlUnlinkNode((xmlNodePtr) dtd); 181 xmlFreeDtd(dtd); 182 ctxt->myDoc->intSubset = NULL; 183 } 184 ctxt->myDoc->intSubset = 185 xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID); 186} 187 188/** 189 * xmlSAX2ExternalSubset: 190 * @ctx: the user data (XML parser context) 191 * @name: the root element name 192 * @ExternalID: the external ID 193 * @SystemID: the SYSTEM ID (e.g. filename or URL) 194 * 195 * Callback on external subset declaration. 196 */ 197void 198xmlSAX2ExternalSubset(void *ctx, const xmlChar *name, 199 const xmlChar *ExternalID, const xmlChar *SystemID) 200{ 201 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 202#ifdef DEBUG_SAX 203 xmlGenericError(xmlGenericErrorContext, 204 "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n", 205 name, ExternalID, SystemID); 206#endif 207 if (((ExternalID != NULL) || (SystemID != NULL)) && 208 (((ctxt->validate) || (ctxt->loadsubset != 0)) && 209 (ctxt->wellFormed && ctxt->myDoc))) { 210 /* 211 * Try to fetch and parse the external subset. 212 */ 213 xmlParserInputPtr oldinput; 214 int oldinputNr; 215 int oldinputMax; 216 xmlParserInputPtr *oldinputTab; 217 xmlParserInputPtr input = NULL; 218 xmlCharEncoding enc; 219 int oldcharset; 220 221 /* 222 * Ask the Entity resolver to load the damn thing 223 */ 224 if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL)) 225 input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID, 226 SystemID); 227 if (input == NULL) { 228 return; 229 } 230 231 xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID); 232 233 /* 234 * make sure we won't destroy the main document context 235 */ 236 oldinput = ctxt->input; 237 oldinputNr = ctxt->inputNr; 238 oldinputMax = ctxt->inputMax; 239 oldinputTab = ctxt->inputTab; 240 oldcharset = ctxt->charset; 241 242 ctxt->inputTab = (xmlParserInputPtr *) 243 xmlMalloc(5 * sizeof(xmlParserInputPtr)); 244 if (ctxt->inputTab == NULL) { 245 ctxt->errNo = XML_ERR_NO_MEMORY; 246 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 247 ctxt->sax->error(ctxt->userData, 248 "xmlSAX2ExternalSubset: out of memory\n"); 249 ctxt->errNo = XML_ERR_NO_MEMORY; 250 ctxt->instate = XML_PARSER_EOF; 251 ctxt->disableSAX = 1; 252 ctxt->input = oldinput; 253 ctxt->inputNr = oldinputNr; 254 ctxt->inputMax = oldinputMax; 255 ctxt->inputTab = oldinputTab; 256 ctxt->charset = oldcharset; 257 return; 258 } 259 ctxt->inputNr = 0; 260 ctxt->inputMax = 5; 261 ctxt->input = NULL; 262 xmlPushInput(ctxt, input); 263 264 /* 265 * On the fly encoding conversion if needed 266 */ 267 if (ctxt->input->length >= 4) { 268 enc = xmlDetectCharEncoding(ctxt->input->cur, 4); 269 xmlSwitchEncoding(ctxt, enc); 270 } 271 272 if (input->filename == NULL) 273 input->filename = (char *) xmlCanonicPath(SystemID); 274 input->line = 1; 275 input->col = 1; 276 input->base = ctxt->input->cur; 277 input->cur = ctxt->input->cur; 278 input->free = NULL; 279 280 /* 281 * let's parse that entity knowing it's an external subset. 282 */ 283 xmlParseExternalSubset(ctxt, ExternalID, SystemID); 284 285 /* 286 * Free up the external entities 287 */ 288 289 while (ctxt->inputNr > 1) 290 xmlPopInput(ctxt); 291 xmlFreeInputStream(ctxt->input); 292 xmlFree(ctxt->inputTab); 293 294 /* 295 * Restore the parsing context of the main entity 296 */ 297 ctxt->input = oldinput; 298 ctxt->inputNr = oldinputNr; 299 ctxt->inputMax = oldinputMax; 300 ctxt->inputTab = oldinputTab; 301 ctxt->charset = oldcharset; 302 /* ctxt->wellFormed = oldwellFormed; */ 303 } 304} 305 306/** 307 * xmlSAX2ResolveEntity: 308 * @ctx: the user data (XML parser context) 309 * @publicId: The public ID of the entity 310 * @systemId: The system ID of the entity 311 * 312 * The entity loader, to control the loading of external entities, 313 * the application can either: 314 * - override this xmlSAX2ResolveEntity() callback in the SAX block 315 * - or better use the xmlSetExternalEntityLoader() function to 316 * set up it's own entity resolution routine 317 * 318 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour. 319 */ 320xmlParserInputPtr 321xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId) 322{ 323 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 324 xmlParserInputPtr ret; 325 xmlChar *URI; 326 const char *base = NULL; 327 328 if (ctxt->input != NULL) 329 base = ctxt->input->filename; 330 if (base == NULL) 331 base = ctxt->directory; 332 333 URI = xmlBuildURI(systemId, (const xmlChar *) base); 334 335#ifdef DEBUG_SAX 336 xmlGenericError(xmlGenericErrorContext, 337 "SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId, systemId); 338#endif 339 340 ret = xmlLoadExternalEntity((const char *) URI, 341 (const char *) publicId, ctxt); 342 if (URI != NULL) 343 xmlFree(URI); 344 return(ret); 345} 346 347/** 348 * xmlSAX2GetEntity: 349 * @ctx: the user data (XML parser context) 350 * @name: The entity name 351 * 352 * Get an entity by name 353 * 354 * Returns the xmlEntityPtr if found. 355 */ 356xmlEntityPtr 357xmlSAX2GetEntity(void *ctx, const xmlChar *name) 358{ 359 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 360 xmlEntityPtr ret = NULL; 361 362#ifdef DEBUG_SAX 363 xmlGenericError(xmlGenericErrorContext, 364 "SAX.xmlSAX2GetEntity(%s)\n", name); 365#endif 366 367 if (ctxt->inSubset == 0) { 368 ret = xmlGetPredefinedEntity(name); 369 if (ret != NULL) 370 return(ret); 371 } 372 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1)) { 373 if (ctxt->inSubset == 2) { 374 ctxt->myDoc->standalone = 0; 375 ret = xmlGetDocEntity(ctxt->myDoc, name); 376 ctxt->myDoc->standalone = 1; 377 } else { 378 ret = xmlGetDocEntity(ctxt->myDoc, name); 379 if (ret == NULL) { 380 ctxt->myDoc->standalone = 0; 381 ret = xmlGetDocEntity(ctxt->myDoc, name); 382 if (ret != NULL) { 383 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 384 ctxt->sax->error(ctxt->userData, 385 "Entity(%s) document marked standalone but requires external subset\n", 386 name); 387 ctxt->valid = 0; 388 ctxt->wellFormed = 0; 389 } 390 ctxt->myDoc->standalone = 1; 391 } 392 } 393 } else { 394 ret = xmlGetDocEntity(ctxt->myDoc, name); 395 } 396 if ((ret != NULL) && 397 ((ctxt->validate) || (ctxt->replaceEntities)) && 398 (ret->children == NULL) && 399 (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) { 400 int val; 401 402 /* 403 * for validation purposes we really need to fetch and 404 * parse the external entity 405 */ 406 xmlNodePtr children; 407 408 val = xmlParseCtxtExternalEntity(ctxt, ret->URI, 409 ret->ExternalID, &children); 410 if (val == 0) { 411 xmlAddChildList((xmlNodePtr) ret, children); 412 } else { 413 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 414 ctxt->sax->error(ctxt->userData, 415 "Failure to process entity %s\n", name); 416 ctxt->wellFormed = 0; 417 ctxt->valid = 0; 418 ctxt->validate = 0; 419 return(NULL); 420 } 421 ret->owner = 1; 422 } 423 return(ret); 424} 425 426/** 427 * xmlSAX2GetParameterEntity: 428 * @ctx: the user data (XML parser context) 429 * @name: The entity name 430 * 431 * Get a parameter entity by name 432 * 433 * Returns the xmlEntityPtr if found. 434 */ 435xmlEntityPtr 436xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name) 437{ 438 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 439 xmlEntityPtr ret; 440 441#ifdef DEBUG_SAX 442 xmlGenericError(xmlGenericErrorContext, 443 "SAX.xmlSAX2GetParameterEntity(%s)\n", name); 444#endif 445 446 ret = xmlGetParameterEntity(ctxt->myDoc, name); 447 return(ret); 448} 449 450 451/** 452 * xmlSAX2EntityDecl: 453 * @ctx: the user data (XML parser context) 454 * @name: the entity name 455 * @type: the entity type 456 * @publicId: The public ID of the entity 457 * @systemId: The system ID of the entity 458 * @content: the entity value (without processing). 459 * 460 * An entity definition has been parsed 461 */ 462void 463xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type, 464 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) 465{ 466 xmlEntityPtr ent; 467 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 468 469#ifdef DEBUG_SAX 470 xmlGenericError(xmlGenericErrorContext, 471 "SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n", 472 name, type, publicId, systemId, content); 473#endif 474 if (ctxt->inSubset == 1) { 475 ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId, 476 systemId, content); 477 if ((ent == NULL) && (ctxt->pedantic) && 478 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 479 ctxt->sax->warning(ctxt->userData, 480 "Entity(%s) already defined in the internal subset\n", name); 481 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 482 xmlChar *URI; 483 const char *base = NULL; 484 485 if (ctxt->input != NULL) 486 base = ctxt->input->filename; 487 if (base == NULL) 488 base = ctxt->directory; 489 490 URI = xmlBuildURI(systemId, (const xmlChar *) base); 491 ent->URI = URI; 492 } 493 } else if (ctxt->inSubset == 2) { 494 ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId, 495 systemId, content); 496 if ((ent == NULL) && (ctxt->pedantic) && 497 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 498 ctxt->sax->warning(ctxt->userData, 499 "Entity(%s) already defined in the external subset\n", name); 500 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 501 xmlChar *URI; 502 const char *base = NULL; 503 504 if (ctxt->input != NULL) 505 base = ctxt->input->filename; 506 if (base == NULL) 507 base = ctxt->directory; 508 509 URI = xmlBuildURI(systemId, (const xmlChar *) base); 510 ent->URI = URI; 511 } 512 } else { 513 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 514 ctxt->sax->error(ctxt->userData, 515 "SAX.xmlSAX2EntityDecl(%s) called while not in subset\n", name); 516 } 517} 518 519/** 520 * xmlSAX2AttributeDecl: 521 * @ctx: the user data (XML parser context) 522 * @elem: the name of the element 523 * @fullname: the attribute name 524 * @type: the attribute type 525 * @def: the type of default value 526 * @defaultValue: the attribute default value 527 * @tree: the tree of enumerated value set 528 * 529 * An attribute definition has been parsed 530 */ 531void 532xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname, 533 int type, int def, const xmlChar *defaultValue, 534 xmlEnumerationPtr tree) 535{ 536 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 537 xmlAttributePtr attr; 538 xmlChar *name = NULL, *prefix = NULL; 539 540#ifdef DEBUG_SAX 541 xmlGenericError(xmlGenericErrorContext, 542 "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n", 543 elem, fullname, type, def, defaultValue); 544#endif 545 /* TODO: optimize name/prefix allocation */ 546 name = xmlSplitQName(ctxt, fullname, &prefix); 547 ctxt->vctxt.valid = 1; 548 if (ctxt->inSubset == 1) 549 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem, 550 name, prefix, (xmlAttributeType) type, 551 (xmlAttributeDefault) def, defaultValue, tree); 552 else if (ctxt->inSubset == 2) 553 attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem, 554 name, prefix, (xmlAttributeType) type, 555 (xmlAttributeDefault) def, defaultValue, tree); 556 else { 557 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 558 ctxt->sax->error(ctxt->userData, 559 "SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n", name); 560 xmlFreeEnumeration(tree); 561 return; 562 } 563#ifdef LIBXML_VALID_ENABLED 564 if (ctxt->vctxt.valid == 0) 565 ctxt->valid = 0; 566 if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) && 567 (ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset != NULL)) 568 ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc, 569 attr); 570#endif /* LIBXML_VALID_ENABLED */ 571 if (prefix != NULL) 572 xmlFree(prefix); 573 if (name != NULL) 574 xmlFree(name); 575} 576 577/** 578 * xmlSAX2ElementDecl: 579 * @ctx: the user data (XML parser context) 580 * @name: the element name 581 * @type: the element type 582 * @content: the element value tree 583 * 584 * An element definition has been parsed 585 */ 586void 587xmlSAX2ElementDecl(void *ctx, const xmlChar * name, int type, 588 xmlElementContentPtr content) 589{ 590 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 591 xmlElementPtr elem = NULL; 592 593#ifdef DEBUG_SAX 594 xmlGenericError(xmlGenericErrorContext, 595 "SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name, type); 596#endif 597 598 if (ctxt->inSubset == 1) 599 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, 600 name, (xmlElementTypeVal) type, content); 601 else if (ctxt->inSubset == 2) 602 elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, 603 name, (xmlElementTypeVal) type, content); 604 else { 605 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 606 ctxt->sax->error(ctxt->userData, 607 "SAX.xmlSAX2ElementDecl(%s) called while not in subset\n", 608 name); 609 return; 610 } 611#ifdef LIBXML_VALID_ENABLED 612 if (elem == NULL) 613 ctxt->valid = 0; 614 if (ctxt->validate && ctxt->wellFormed && 615 ctxt->myDoc && ctxt->myDoc->intSubset) 616 ctxt->valid &= 617 xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem); 618#endif /* LIBXML_VALID_ENABLED */ 619} 620 621/** 622 * xmlSAX2NotationDecl: 623 * @ctx: the user data (XML parser context) 624 * @name: The name of the notation 625 * @publicId: The public ID of the entity 626 * @systemId: The system ID of the entity 627 * 628 * What to do when a notation declaration has been parsed. 629 */ 630void 631xmlSAX2NotationDecl(void *ctx, const xmlChar *name, 632 const xmlChar *publicId, const xmlChar *systemId) 633{ 634 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 635 xmlNotationPtr nota = NULL; 636 637#ifdef DEBUG_SAX 638 xmlGenericError(xmlGenericErrorContext, 639 "SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name, publicId, systemId); 640#endif 641 642 if ((publicId == NULL) && (systemId == NULL)) { 643 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 644 ctxt->sax->error(ctxt->userData, 645 "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n", name); 646 ctxt->valid = 0; 647 ctxt->wellFormed = 0; 648 return; 649 } else if (ctxt->inSubset == 1) 650 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name, 651 publicId, systemId); 652 else if (ctxt->inSubset == 2) 653 nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name, 654 publicId, systemId); 655 else { 656 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 657 ctxt->sax->error(ctxt->userData, 658 "SAX.xmlSAX2NotationDecl(%s) called while not in subset\n", name); 659 return; 660 } 661#ifdef LIBXML_VALID_ENABLED 662 if (nota == NULL) ctxt->valid = 0; 663 if (ctxt->validate && ctxt->wellFormed && 664 ctxt->myDoc && ctxt->myDoc->intSubset) 665 ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc, 666 nota); 667#endif /* LIBXML_VALID_ENABLED */ 668} 669 670/** 671 * xmlSAX2UnparsedEntityDecl: 672 * @ctx: the user data (XML parser context) 673 * @name: The name of the entity 674 * @publicId: The public ID of the entity 675 * @systemId: The system ID of the entity 676 * @notationName: the name of the notation 677 * 678 * What to do when an unparsed entity declaration is parsed 679 */ 680void 681xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name, 682 const xmlChar *publicId, const xmlChar *systemId, 683 const xmlChar *notationName) 684{ 685 xmlEntityPtr ent; 686 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 687#ifdef DEBUG_SAX 688 xmlGenericError(xmlGenericErrorContext, 689 "SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n", 690 name, publicId, systemId, notationName); 691#endif 692 if (ctxt->inSubset == 1) { 693 ent = xmlAddDocEntity(ctxt->myDoc, name, 694 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY, 695 publicId, systemId, notationName); 696 if ((ent == NULL) && (ctxt->pedantic) && 697 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 698 ctxt->sax->warning(ctxt->userData, 699 "Entity(%s) already defined in the internal subset\n", name); 700 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 701 xmlChar *URI; 702 const char *base = NULL; 703 704 if (ctxt->input != NULL) 705 base = ctxt->input->filename; 706 if (base == NULL) 707 base = ctxt->directory; 708 709 URI = xmlBuildURI(systemId, (const xmlChar *) base); 710 ent->URI = URI; 711 } 712 } else if (ctxt->inSubset == 2) { 713 ent = xmlAddDtdEntity(ctxt->myDoc, name, 714 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY, 715 publicId, systemId, notationName); 716 if ((ent == NULL) && (ctxt->pedantic) && 717 (ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 718 ctxt->sax->warning(ctxt->userData, 719 "Entity(%s) already defined in the external subset\n", name); 720 if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) { 721 xmlChar *URI; 722 const char *base = NULL; 723 724 if (ctxt->input != NULL) 725 base = ctxt->input->filename; 726 if (base == NULL) 727 base = ctxt->directory; 728 729 URI = xmlBuildURI(systemId, (const xmlChar *) base); 730 ent->URI = URI; 731 } 732 } else { 733 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 734 ctxt->sax->error(ctxt->userData, 735 "SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n", name); 736 } 737} 738 739/** 740 * xmlSAX2SetDocumentLocator: 741 * @ctx: the user data (XML parser context) 742 * @loc: A SAX Locator 743 * 744 * Receive the document locator at startup, actually xmlDefaultSAXLocator 745 * Everything is available on the context, so this is useless in our case. 746 */ 747void 748xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED) 749{ 750 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ 751#ifdef DEBUG_SAX 752 xmlGenericError(xmlGenericErrorContext, 753 "SAX.xmlSAX2SetDocumentLocator()\n"); 754#endif 755} 756 757/** 758 * xmlSAX2StartDocument: 759 * @ctx: the user data (XML parser context) 760 * 761 * called when the document start being processed. 762 */ 763void 764xmlSAX2StartDocument(void *ctx) 765{ 766 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 767 xmlDocPtr doc; 768 769#ifdef DEBUG_SAX 770 xmlGenericError(xmlGenericErrorContext, 771 "SAX.xmlSAX2StartDocument()\n"); 772#endif 773 if (ctxt->html) { 774#ifdef LIBXML_HTML_ENABLED 775 if (ctxt->myDoc == NULL) 776 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL); 777 if (ctxt->myDoc == NULL) { 778 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 779 ctxt->sax->error(ctxt->userData, 780 "SAX.xmlSAX2StartDocument(): out of memory\n"); 781 ctxt->errNo = XML_ERR_NO_MEMORY; 782 ctxt->instate = XML_PARSER_EOF; 783 ctxt->disableSAX = 1; 784 return; 785 } 786#else 787 xmlGenericError(xmlGenericErrorContext, 788 "libxml2 built without HTML support\n"); 789 ctxt->errNo = XML_ERR_INTERNAL_ERROR; 790 ctxt->instate = XML_PARSER_EOF; 791 ctxt->disableSAX = 1; 792 return; 793#endif 794 } else { 795 doc = ctxt->myDoc = xmlNewDoc(ctxt->version); 796 if (doc != NULL) { 797 if (ctxt->encoding != NULL) 798 doc->encoding = xmlStrdup(ctxt->encoding); 799 else 800 doc->encoding = NULL; 801 doc->standalone = ctxt->standalone; 802 } else { 803 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 804 ctxt->sax->error(ctxt->userData, 805 "SAX.xmlSAX2StartDocument(): out of memory\n"); 806 ctxt->errNo = XML_ERR_NO_MEMORY; 807 ctxt->instate = XML_PARSER_EOF; 808 ctxt->disableSAX = 1; 809 return; 810 } 811 if ((ctxt->dictNames) && (doc != NULL)) 812 doc->dict = ctxt->dict; 813 } 814 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) && 815 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) { 816 ctxt->myDoc->URL = xmlCanonicPath((const xmlChar *) ctxt->input->filename); 817 if (ctxt->myDoc->URL == NULL) 818 ctxt->myDoc->URL = xmlStrdup((const xmlChar *) ctxt->input->filename); 819 } 820} 821 822/** 823 * xmlSAX2EndDocument: 824 * @ctx: the user data (XML parser context) 825 * 826 * called when the document end has been detected. 827 */ 828void 829xmlSAX2EndDocument(void *ctx) 830{ 831 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 832#ifdef DEBUG_SAX 833 xmlGenericError(xmlGenericErrorContext, 834 "SAX.xmlSAX2EndDocument()\n"); 835#endif 836#ifdef LIBXML_VALID_ENABLED 837 if (ctxt->validate && ctxt->wellFormed && 838 ctxt->myDoc && ctxt->myDoc->intSubset) 839 ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc); 840#endif /* LIBXML_VALID_ENABLED */ 841 842 /* 843 * Grab the encoding if it was added on-the-fly 844 */ 845 if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) && 846 (ctxt->myDoc->encoding == NULL)) { 847 ctxt->myDoc->encoding = ctxt->encoding; 848 ctxt->encoding = NULL; 849 } 850 if ((ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) && 851 (ctxt->myDoc->encoding == NULL)) { 852 ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding); 853 } 854 if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) && 855 (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) { 856 ctxt->myDoc->charset = ctxt->charset; 857 } 858} 859 860/** 861 * xmlSAX2AttributeInternal: 862 * @ctx: the user data (XML parser context) 863 * @fullname: The attribute name, including namespace prefix 864 * @value: The attribute value 865 * @prefix: the prefix on the element node 866 * 867 * Handle an attribute that has been read by the parser. 868 * The default handling is to convert the attribute into an 869 * DOM subtree and past it in a new xmlAttr element added to 870 * the element. 871 */ 872static void 873xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname, 874 const xmlChar *value, const xmlChar *prefix ATTRIBUTE_UNUSED) 875{ 876 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 877 xmlAttrPtr ret; 878 xmlChar *name; 879 xmlChar *ns; 880 xmlChar *nval; 881 xmlNsPtr namespace; 882 883 /* 884 * Split the full name into a namespace prefix and the tag name 885 */ 886 name = xmlSplitQName(ctxt, fullname, &ns); 887 if ((name != NULL) && (name[0] == 0)) { 888 if (xmlStrEqual(ns, BAD_CAST "xmlns")) { 889 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 890 ctxt->sax->error(ctxt->userData, 891 "invalid namespace declaration '%s'\n", fullname); 892 } else { 893 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 894 ctxt->sax->warning(ctxt->userData, 895 "Avoid attribute ending with ':' like '%s'\n", fullname); 896 } 897 if (ns != NULL) 898 xmlFree(ns); 899 ns = NULL; 900 xmlFree(name); 901 name = xmlStrdup(fullname); 902 } 903 if (name == NULL) { 904 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 905 ctxt->sax->error(ctxt->userData, 906 "SAX.xmlSAX2StartElement(): out of memory\n"); 907 ctxt->errNo = XML_ERR_NO_MEMORY; 908 ctxt->instate = XML_PARSER_EOF; 909 ctxt->disableSAX = 1; 910 if (ns != NULL) 911 xmlFree(ns); 912 return; 913 } 914 915#ifdef LIBXML_VALID_ENABLED 916 /* 917 * Do the last stage of the attribute normalization 918 * Needed for HTML too: 919 * http://www.w3.org/TR/html4/types.html#h-6.2 920 */ 921 ctxt->vctxt.valid = 1; 922 nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt, 923 ctxt->myDoc, ctxt->node, 924 fullname, value); 925 if (ctxt->vctxt.valid != 1) { 926 ctxt->valid = 0; 927 } 928 if (nval != NULL) 929 value = nval; 930#else 931 nval = NULL; 932#endif /* LIBXML_VALID_ENABLED */ 933 934 /* 935 * Check whether it's a namespace definition 936 */ 937 if ((!ctxt->html) && (ns == NULL) && 938 (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') && 939 (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) { 940 xmlNsPtr nsret; 941 xmlChar *val; 942 943 if (!ctxt->replaceEntities) { 944 ctxt->depth++; 945 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF, 946 0,0,0); 947 ctxt->depth--; 948 } else { 949 val = (xmlChar *) value; 950 } 951 952 if (val[0] != 0) { 953 xmlURIPtr uri; 954 955 uri = xmlParseURI((const char *)val); 956 if (uri == NULL) { 957 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 958 ctxt->sax->warning(ctxt->userData, 959 "xmlns: %s not a valid URI\n", val); 960 } else { 961 if (uri->scheme == NULL) { 962 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 963 ctxt->sax->warning(ctxt->userData, 964 "xmlns: URI %s is not absolute\n", val); 965 } 966 xmlFreeURI(uri); 967 } 968 } 969 970 /* a default namespace definition */ 971 nsret = xmlNewNs(ctxt->node, val, NULL); 972 973#ifdef LIBXML_VALID_ENABLED 974 /* 975 * Validate also for namespace decls, they are attributes from 976 * an XML-1.0 perspective 977 */ 978 if (nsret != NULL && ctxt->validate && ctxt->wellFormed && 979 ctxt->myDoc && ctxt->myDoc->intSubset) 980 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc, 981 ctxt->node, prefix, nsret, val); 982#endif /* LIBXML_VALID_ENABLED */ 983 if (name != NULL) 984 xmlFree(name); 985 if (nval != NULL) 986 xmlFree(nval); 987 if (val != value) 988 xmlFree(val); 989 return; 990 } 991 if ((!ctxt->html) && 992 (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') && 993 (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) { 994 xmlNsPtr nsret; 995 xmlChar *val; 996 997 if (!ctxt->replaceEntities) { 998 ctxt->depth++; 999 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF, 1000 0,0,0); 1001 ctxt->depth--; 1002 if (val == NULL) { 1003 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 1004 ctxt->sax->error(ctxt->userData, 1005 "SAX.xmlSAX2StartElement(): out of memory\n"); 1006 ctxt->errNo = XML_ERR_NO_MEMORY; 1007 ctxt->instate = XML_PARSER_EOF; 1008 ctxt->disableSAX = 1; 1009 xmlFree(ns); 1010 if (name != NULL) 1011 xmlFree(name); 1012 return; 1013 } 1014 } else { 1015 val = (xmlChar *) value; 1016 } 1017 1018 if (val[0] == 0) { 1019 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 1020 ctxt->sax->error(ctxt->userData, 1021 "Empty namespace name for prefix %s\n", name); 1022 } 1023 if ((ctxt->pedantic != 0) && (val[0] != 0)) { 1024 xmlURIPtr uri; 1025 1026 uri = xmlParseURI((const char *)val); 1027 if (uri == NULL) { 1028 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 1029 ctxt->sax->warning(ctxt->userData, 1030 "xmlns:%s: %s not a valid URI\n", name, value); 1031 } else { 1032 if (uri->scheme == NULL) { 1033 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 1034 ctxt->sax->warning(ctxt->userData, 1035 "xmlns:%s: URI %s is not absolute\n", name, value); 1036 } 1037 xmlFreeURI(uri); 1038 } 1039 } 1040 1041 /* a standard namespace definition */ 1042 nsret = xmlNewNs(ctxt->node, val, name); 1043 xmlFree(ns); 1044#ifdef LIBXML_VALID_ENABLED 1045 /* 1046 * Validate also for namespace decls, they are attributes from 1047 * an XML-1.0 perspective 1048 */ 1049 if (nsret != NULL && ctxt->validate && ctxt->wellFormed && 1050 ctxt->myDoc && ctxt->myDoc->intSubset) 1051 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc, 1052 ctxt->node, prefix, nsret, value); 1053#endif /* LIBXML_VALID_ENABLED */ 1054 if (name != NULL) 1055 xmlFree(name); 1056 if (nval != NULL) 1057 xmlFree(nval); 1058 if (val != value) 1059 xmlFree(val); 1060 return; 1061 } 1062 1063 if (ns != NULL) { 1064 xmlAttrPtr prop; 1065 namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns); 1066 if (namespace == NULL) { 1067 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 1068 ctxt->sax->error(ctxt->userData, 1069 "Namespace prefix %s of attribute %s is not defined\n", 1070 ns, name); 1071 } 1072 1073 prop = ctxt->node->properties; 1074 while (prop != NULL) { 1075 if (prop->ns != NULL) { 1076 if ((xmlStrEqual(name, prop->name)) && 1077 ((namespace == prop->ns) || 1078 (xmlStrEqual(namespace->href, prop->ns->href)))) { 1079 ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED; 1080 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 1081 ctxt->sax->error(ctxt->userData, 1082 "Attribute %s in %s redefined\n", 1083 name, namespace->href); 1084 ctxt->wellFormed = 0; 1085 if (ctxt->recovery == 0) ctxt->disableSAX = 1; 1086 goto error; 1087 } 1088 } 1089 prop = prop->next; 1090 } 1091 } else { 1092 namespace = NULL; 1093 } 1094 1095 /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */ 1096 ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL); 1097 1098 if (ret != NULL) { 1099 if ((ctxt->replaceEntities == 0) && (!ctxt->html)) { 1100 xmlNodePtr tmp; 1101 1102 ret->children = xmlStringGetNodeList(ctxt->myDoc, value); 1103 tmp = ret->children; 1104 while (tmp != NULL) { 1105 tmp->parent = (xmlNodePtr) ret; 1106 if (tmp->next == NULL) 1107 ret->last = tmp; 1108 tmp = tmp->next; 1109 } 1110 } else if (value != NULL) { 1111 ret->children = xmlNewDocText(ctxt->myDoc, value); 1112 ret->last = ret->children; 1113 if (ret->children != NULL) 1114 ret->children->parent = (xmlNodePtr) ret; 1115 } 1116 } 1117 1118#ifdef LIBXML_VALID_ENABLED 1119 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed && 1120 ctxt->myDoc && ctxt->myDoc->intSubset) { 1121 1122 /* 1123 * If we don't substitute entities, the validation should be 1124 * done on a value with replaced entities anyway. 1125 */ 1126 if (!ctxt->replaceEntities) { 1127 xmlChar *val; 1128 1129 ctxt->depth++; 1130 val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF, 1131 0,0,0); 1132 ctxt->depth--; 1133 1134 if (val == NULL) 1135 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 1136 ctxt->myDoc, ctxt->node, ret, value); 1137 else { 1138 xmlChar *nvalnorm; 1139 1140 /* 1141 * Do the last stage of the attribute normalization 1142 * It need to be done twice ... it's an extra burden related 1143 * to the ability to keep xmlSAX2References in attributes 1144 */ 1145 nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc, 1146 ctxt->node, fullname, val); 1147 if (nvalnorm != NULL) { 1148 xmlFree(val); 1149 val = nvalnorm; 1150 } 1151 1152 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 1153 ctxt->myDoc, ctxt->node, ret, val); 1154 xmlFree(val); 1155 } 1156 } else { 1157 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, 1158 ctxt->node, ret, value); 1159 } 1160 } else 1161#endif /* LIBXML_VALID_ENABLED */ 1162 if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) && 1163 (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) || 1164 ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) { 1165 /* 1166 * when validating, the ID registration is done at the attribute 1167 * validation level. Otherwise we have to do specific handling here. 1168 */ 1169 if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) 1170 xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret); 1171 else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) 1172 xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret); 1173 } 1174 1175error: 1176 if (nval != NULL) 1177 xmlFree(nval); 1178 if (ns != NULL) 1179 xmlFree(ns); 1180} 1181 1182/* 1183 * xmlCheckDefaultedAttributes: 1184 * 1185 * Check defaulted attributes from the DTD 1186 */ 1187static void 1188xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name, 1189 const xmlChar *prefix, const xmlChar **atts) { 1190 xmlElementPtr elemDecl; 1191 const xmlChar *att; 1192 int internal = 1; 1193 int i; 1194 1195 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix); 1196 if (elemDecl == NULL) { 1197 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix); 1198 internal = 0; 1199 } 1200 1201process_external_subset: 1202 1203 if (elemDecl != NULL) { 1204 xmlAttributePtr attr = elemDecl->attributes; 1205 /* 1206 * Check against defaulted attributes from the external subset 1207 * if the document is stamped as standalone 1208 */ 1209 if ((ctxt->myDoc->standalone == 1) && 1210 (ctxt->myDoc->extSubset != NULL) && 1211 (ctxt->validate)) { 1212 while (attr != NULL) { 1213 if ((attr->defaultValue != NULL) && 1214 (xmlGetDtdQAttrDesc(ctxt->myDoc->extSubset, 1215 attr->elem, attr->name, 1216 attr->prefix) == attr) && 1217 (xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset, 1218 attr->elem, attr->name, 1219 attr->prefix) == NULL)) { 1220 xmlChar *fulln; 1221 1222 if (attr->prefix != NULL) { 1223 fulln = xmlStrdup(attr->prefix); 1224 fulln = xmlStrcat(fulln, BAD_CAST ":"); 1225 fulln = xmlStrcat(fulln, attr->name); 1226 } else { 1227 fulln = xmlStrdup(attr->name); 1228 } 1229 1230 /* 1231 * Check that the attribute is not declared in the 1232 * serialization 1233 */ 1234 att = NULL; 1235 if (atts != NULL) { 1236 i = 0; 1237 att = atts[i]; 1238 while (att != NULL) { 1239 if (xmlStrEqual(att, fulln)) 1240 break; 1241 i += 2; 1242 att = atts[i]; 1243 } 1244 } 1245 if (att == NULL) { 1246 if (ctxt->vctxt.error != NULL) 1247 ctxt->vctxt.error(ctxt->vctxt.userData, 1248 "standalone: attribute %s on %s defaulted from external subset\n", 1249 fulln, attr->elem); 1250 ctxt->valid = 0; 1251 } 1252 } 1253 attr = attr->nexth; 1254 } 1255 } 1256 1257 /* 1258 * Actually insert defaulted values when needed 1259 */ 1260 attr = elemDecl->attributes; 1261 while (attr != NULL) { 1262 /* 1263 * Make sure that attributes redefinition occuring in the 1264 * internal subset are not overriden by definitions in the 1265 * external subset. 1266 */ 1267 if (attr->defaultValue != NULL) { 1268 /* 1269 * the element should be instantiated in the tree if: 1270 * - this is a namespace prefix 1271 * - the user required for completion in the tree 1272 * like XSLT 1273 * - there isn't already an attribute definition 1274 * in the internal subset overriding it. 1275 */ 1276 if (((attr->prefix != NULL) && 1277 (xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) || 1278 ((attr->prefix == NULL) && 1279 (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) || 1280 (ctxt->loadsubset & XML_COMPLETE_ATTRS)) { 1281 xmlAttributePtr tst; 1282 1283 tst = xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset, 1284 attr->elem, attr->name, 1285 attr->prefix); 1286 if ((tst == attr) || (tst == NULL)) { 1287 xmlChar fn[50]; 1288 xmlChar *fulln; 1289 1290 fulln = xmlBuildQName(attr->name, attr->prefix, fn, 50); 1291 if (fulln == NULL) { 1292 if ((ctxt->sax != NULL) && 1293 (ctxt->sax->error != NULL)) 1294 ctxt->sax->error(ctxt->userData, 1295 "SAX.xmlSAX2StartElement(): out of memory\n"); 1296 ctxt->errNo = XML_ERR_NO_MEMORY; 1297 ctxt->instate = XML_PARSER_EOF; 1298 ctxt->disableSAX = 1; 1299 return; 1300 } 1301 1302 /* 1303 * Check that the attribute is not declared in the 1304 * serialization 1305 */ 1306 att = NULL; 1307 if (atts != NULL) { 1308 i = 0; 1309 att = atts[i]; 1310 while (att != NULL) { 1311 if (xmlStrEqual(att, fulln)) 1312 break; 1313 i += 2; 1314 att = atts[i]; 1315 } 1316 } 1317 if (att == NULL) { 1318 xmlSAX2AttributeInternal(ctxt, fulln, 1319 attr->defaultValue, prefix); 1320 } 1321 if ((fulln != fn) && (fulln != attr->name)) 1322 xmlFree(fulln); 1323 } 1324 } 1325 } 1326 attr = attr->nexth; 1327 } 1328 if (internal == 1) { 1329 elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, 1330 name, prefix); 1331 internal = 0; 1332 goto process_external_subset; 1333 } 1334 } 1335} 1336 1337/** 1338 * xmlSAX2StartElement: 1339 * @ctx: the user data (XML parser context) 1340 * @fullname: The element name, including namespace prefix 1341 * @atts: An array of name/value attributes pairs, NULL terminated 1342 * 1343 * called when an opening tag has been processed. 1344 */ 1345void 1346xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts) 1347{ 1348 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 1349 xmlNodePtr ret; 1350 xmlNodePtr parent = ctxt->node; 1351 xmlNsPtr ns; 1352 xmlChar *name; 1353 xmlChar *prefix; 1354 const xmlChar *att; 1355 const xmlChar *value; 1356 int i; 1357 1358#ifdef DEBUG_SAX 1359 xmlGenericError(xmlGenericErrorContext, 1360 "SAX.xmlSAX2StartElement(%s)\n", fullname); 1361#endif 1362 1363 /* 1364 * First check on validity: 1365 */ 1366 if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) && 1367 ((ctxt->myDoc->intSubset == NULL) || 1368 ((ctxt->myDoc->intSubset->notations == NULL) && 1369 (ctxt->myDoc->intSubset->elements == NULL) && 1370 (ctxt->myDoc->intSubset->attributes == NULL) && 1371 (ctxt->myDoc->intSubset->entities == NULL)))) { 1372 if (ctxt->vctxt.error != NULL) { 1373 ctxt->vctxt.error(ctxt->vctxt.userData, 1374 "Validation failed: no DTD found !\n"); 1375 } 1376 ctxt->validate = 0; 1377 ctxt->valid = 0; 1378 ctxt->errNo = XML_ERR_NO_DTD; 1379 } 1380 1381 1382 /* 1383 * Split the full name into a namespace prefix and the tag name 1384 */ 1385 name = xmlSplitQName(ctxt, fullname, &prefix); 1386 1387 1388 /* 1389 * Note : the namespace resolution is deferred until the end of the 1390 * attributes parsing, since local namespace can be defined as 1391 * an attribute at this level. 1392 */ 1393 ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL); 1394 if (ret == NULL) { 1395 if (prefix != NULL) 1396 xmlFree(prefix); 1397 ctxt->errNo = XML_ERR_NO_MEMORY; 1398 ctxt->instate = XML_PARSER_EOF; 1399 ctxt->disableSAX = 1; 1400 return; 1401 } 1402 if (ctxt->myDoc->children == NULL) { 1403#ifdef DEBUG_SAX_TREE 1404 xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name); 1405#endif 1406 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); 1407 } else if (parent == NULL) { 1408 parent = ctxt->myDoc->children; 1409 } 1410 ctxt->nodemem = -1; 1411 if (ctxt->linenumbers) { 1412 if (ctxt->input != NULL) 1413 ret->content = (void *) (long) ctxt->input->line; 1414 } 1415 1416 /* 1417 * We are parsing a new node. 1418 */ 1419#ifdef DEBUG_SAX_TREE 1420 xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name); 1421#endif 1422 nodePush(ctxt, ret); 1423 1424 /* 1425 * Link the child element 1426 */ 1427 if (parent != NULL) { 1428 if (parent->type == XML_ELEMENT_NODE) { 1429#ifdef DEBUG_SAX_TREE 1430 xmlGenericError(xmlGenericErrorContext, 1431 "adding child %s to %s\n", name, parent->name); 1432#endif 1433 xmlAddChild(parent, ret); 1434 } else { 1435#ifdef DEBUG_SAX_TREE 1436 xmlGenericError(xmlGenericErrorContext, 1437 "adding sibling %s to ", name); 1438 xmlDebugDumpOneNode(stderr, parent, 0); 1439#endif 1440 xmlAddSibling(parent, ret); 1441 } 1442 } 1443 1444 /* 1445 * Insert all the defaulted attributes from the DTD especially namespaces 1446 */ 1447 if ((!ctxt->html) && 1448 ((ctxt->myDoc->intSubset != NULL) || 1449 (ctxt->myDoc->extSubset != NULL))) { 1450 xmlCheckDefaultedAttributes(ctxt, name, prefix, atts); 1451 } 1452 1453 /* 1454 * process all the attributes whose name start with "xmlns" 1455 */ 1456 if (atts != NULL) { 1457 i = 0; 1458 att = atts[i++]; 1459 value = atts[i++]; 1460 if (!ctxt->html) { 1461 while ((att != NULL) && (value != NULL)) { 1462 if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') && 1463 (att[3] == 'n') && (att[4] == 's')) 1464 xmlSAX2AttributeInternal(ctxt, att, value, prefix); 1465 1466 att = atts[i++]; 1467 value = atts[i++]; 1468 } 1469 } 1470 } 1471 1472 /* 1473 * Search the namespace, note that since the attributes have been 1474 * processed, the local namespaces are available. 1475 */ 1476 ns = xmlSearchNs(ctxt->myDoc, ret, prefix); 1477 if ((ns == NULL) && (parent != NULL)) 1478 ns = xmlSearchNs(ctxt->myDoc, parent, prefix); 1479 if ((prefix != NULL) && (ns == NULL)) { 1480 ns = xmlNewNs(ret, NULL, prefix); 1481 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 1482 ctxt->sax->warning(ctxt->userData, 1483 "Namespace prefix %s is not defined\n", prefix); 1484 } 1485 1486 /* 1487 * set the namespace node, making sure that if the default namspace 1488 * is unbound on a parent we simply kee it NULL 1489 */ 1490 if ((ns != NULL) && (ns->href != NULL) && 1491 ((ns->href[0] != 0) || (ns->prefix != NULL))) 1492 xmlSetNs(ret, ns); 1493 1494 /* 1495 * process all the other attributes 1496 */ 1497 if (atts != NULL) { 1498 i = 0; 1499 att = atts[i++]; 1500 value = atts[i++]; 1501 if (ctxt->html) { 1502 while (att != NULL) { 1503 xmlSAX2AttributeInternal(ctxt, att, value, NULL); 1504 att = atts[i++]; 1505 value = atts[i++]; 1506 } 1507 } else { 1508 while ((att != NULL) && (value != NULL)) { 1509 if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l') || 1510 (att[3] != 'n') || (att[4] != 's')) 1511 xmlSAX2AttributeInternal(ctxt, att, value, NULL); 1512 1513 /* 1514 * Next ones 1515 */ 1516 att = atts[i++]; 1517 value = atts[i++]; 1518 } 1519 } 1520 } 1521 1522#ifdef LIBXML_VALID_ENABLED 1523 /* 1524 * If it's the Document root, finish the DTD validation and 1525 * check the document root element for validity 1526 */ 1527 if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) { 1528 int chk; 1529 1530 chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc); 1531 if (chk <= 0) 1532 ctxt->valid = 0; 1533 if (chk < 0) 1534 ctxt->wellFormed = 0; 1535 ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc); 1536 ctxt->vctxt.finishDtd = 1; 1537 } 1538#endif /* LIBXML_VALID_ENABLED */ 1539 1540 if (prefix != NULL) 1541 xmlFree(prefix); 1542 1543} 1544 1545/** 1546 * xmlSAX2EndElement: 1547 * @ctx: the user data (XML parser context) 1548 * @name: The element name 1549 * 1550 * called when the end of an element has been detected. 1551 */ 1552void 1553xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED) 1554{ 1555 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 1556 xmlParserNodeInfo node_info; 1557 xmlNodePtr cur = ctxt->node; 1558 1559#ifdef DEBUG_SAX 1560 if (name == NULL) 1561 xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(NULL)\n"); 1562 else 1563 xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(%s)\n", name); 1564#endif 1565 1566 /* Capture end position and add node */ 1567 if (cur != NULL && ctxt->record_info) { 1568 node_info.end_pos = ctxt->input->cur - ctxt->input->base; 1569 node_info.end_line = ctxt->input->line; 1570 node_info.node = cur; 1571 xmlParserAddNodeInfo(ctxt, &node_info); 1572 } 1573 ctxt->nodemem = -1; 1574 1575#ifdef LIBXML_VALID_ENABLED 1576 if (ctxt->validate && ctxt->wellFormed && 1577 ctxt->myDoc && ctxt->myDoc->intSubset) 1578 ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, 1579 cur); 1580#endif /* LIBXML_VALID_ENABLED */ 1581 1582 1583 /* 1584 * end of parsing of this node. 1585 */ 1586#ifdef DEBUG_SAX_TREE 1587 xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name); 1588#endif 1589 nodePop(ctxt); 1590} 1591 1592int nb_interned = 0; 1593/* 1594 * xmlSAX2TextNode: 1595 * @ctxt: the parser context 1596 * @str: the input string 1597 * @len: the string length 1598 * 1599 * Remove the entities from an attribute value 1600 * 1601 * Returns the newly allocated string or NULL if not needed or error 1602 */ 1603static xmlNodePtr 1604xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) { 1605 xmlNodePtr ret; 1606 const xmlChar *intern = NULL; 1607 1608 /* 1609 * Allocate 1610 */ 1611 if (ctxt->freeElems != NULL) { 1612 ret = ctxt->freeElems; 1613 ctxt->freeElems = ret->next; 1614 ctxt->freeElemsNr--; 1615 } else { 1616 ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode)); 1617 } 1618 if (ret == NULL) { 1619 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 1620 ctxt->sax->error(ctxt->userData, 1621 "SAX.xmlSAX2Characters(): out of memory\n"); 1622 ctxt->errNo = XML_ERR_NO_MEMORY; 1623 ctxt->instate = XML_PARSER_EOF; 1624 ctxt->disableSAX = 1; 1625 return(NULL); 1626 } 1627 /* 1628 * intern the formatting blanks found between tags, or the 1629 * very short strings 1630 */ 1631 if (ctxt->dictNames) { 1632 xmlChar cur = str[len]; 1633 1634 if ((len <= 3) && ((cur == '"') || (cur == '\'') || 1635 ((cur == '<') && (str[len + 1] != '!')))) { 1636 intern = xmlDictLookup(ctxt->dict, str, len); 1637 } else if (IS_BLANK(*str) && (len < 60) && (cur == '<') && 1638 (str[len + 1] != '!')) { 1639 int i; 1640 1641 for (i = 1;i < len;i++) { 1642 if (!IS_BLANK(*str)) goto skip; 1643 } 1644 intern = xmlDictLookup(ctxt->dict, str, len); 1645 } 1646 } 1647skip: 1648 memset(ret, 0, sizeof(xmlNode)); 1649 ret->type = XML_TEXT_NODE; 1650 1651 ret->name = xmlStringText; 1652 if (intern == NULL) 1653 ret->content = xmlStrndup(str, len); 1654 else 1655 ret->content = (xmlChar *) intern; 1656 1657 if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) 1658 xmlRegisterNodeDefaultValue(ret); 1659 return(ret); 1660} 1661 1662#ifdef LIBXML_VALID_ENABLED 1663/* 1664 * xmlSAX2DecodeAttrEntities: 1665 * @ctxt: the parser context 1666 * @str: the input string 1667 * @len: the string length 1668 * 1669 * Remove the entities from an attribute value 1670 * 1671 * Returns the newly allocated string or NULL if not needed or error 1672 */ 1673static xmlChar * 1674xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, 1675 const xmlChar *end) { 1676 const xmlChar *in; 1677 xmlChar *ret; 1678 1679 in = str; 1680 while (in < end) 1681 if (*in++ == '&') 1682 goto decode; 1683 return(NULL); 1684decode: 1685 ctxt->depth++; 1686 ret = xmlStringLenDecodeEntities(ctxt, str, end - str, 1687 XML_SUBSTITUTE_REF, 0,0,0); 1688 ctxt->depth--; 1689 return(ret); 1690} 1691#endif /* LIBXML_VALID_ENABLED */ 1692 1693/** 1694 * xmlSAX2AttributeNs: 1695 * @ctx: the user data (XML parser context) 1696 * @localname: the local name of the attribute 1697 * @prefix: the attribute namespace prefix if available 1698 * @URI: the attribute namespace name if available 1699 * @value: Start of the attribute value 1700 * @valueend: end of the attribute value 1701 * 1702 * Handle an attribute that has been read by the parser. 1703 * The default handling is to convert the attribute into an 1704 * DOM subtree and past it in a new xmlAttr element added to 1705 * the element. 1706 */ 1707static void 1708xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt, 1709 const xmlChar * localname, 1710 const xmlChar * prefix, 1711 const xmlChar * value, 1712 const xmlChar * valueend) 1713{ 1714 xmlAttrPtr ret; 1715 xmlNsPtr namespace = NULL; 1716 xmlChar *dup = NULL; 1717 1718 /* 1719 * Note: if prefix == NULL, the attribute is not in the default namespace 1720 */ 1721 if (prefix != NULL) 1722 namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, prefix); 1723 1724 /* 1725 * allocate the node 1726 */ 1727 if (ctxt->freeAttrs != NULL) { 1728 ret = ctxt->freeAttrs; 1729 ctxt->freeAttrs = ret->next; 1730 ctxt->freeAttrsNr--; 1731 memset(ret, 0, sizeof(xmlAttr)); 1732 ret->type = XML_ATTRIBUTE_NODE; 1733 1734 ret->parent = ctxt->node; 1735 ret->doc = ctxt->myDoc; 1736 ret->ns = namespace; 1737 1738 if (ctxt->dictNames) 1739 ret->name = localname; 1740 else 1741 ret->name = xmlStrdup(localname); 1742 1743 /* link at the end to preserv order, TODO speed up with a last */ 1744 if (ctxt->node->properties == NULL) { 1745 ctxt->node->properties = ret; 1746 } else { 1747 xmlAttrPtr prev = ctxt->node->properties; 1748 1749 while (prev->next != NULL) prev = prev->next; 1750 prev->next = ret; 1751 ret->prev = prev; 1752 } 1753 1754 if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) 1755 xmlRegisterNodeDefaultValue((xmlNodePtr)ret); 1756 } else { 1757 if (ctxt->dictNames) 1758 ret = xmlNewNsPropEatName(ctxt->node, namespace, 1759 (xmlChar *) localname, NULL); 1760 else 1761 ret = xmlNewNsProp(ctxt->node, namespace, localname, NULL); 1762 if (ret == NULL) { 1763 ctxt->errNo = XML_ERR_NO_MEMORY; 1764 ctxt->instate = XML_PARSER_EOF; 1765 ctxt->disableSAX = 1; 1766 return; 1767 } 1768 } 1769 1770 if ((ctxt->replaceEntities == 0) && (!ctxt->html)) { 1771 xmlNodePtr tmp; 1772 1773 /* 1774 * We know that if there is an entity reference, then 1775 * the string has been dup'ed and terminates with 0 1776 * otherwise with ' or " 1777 */ 1778 if (*valueend != 0) { 1779 tmp = xmlSAX2TextNode(ctxt, value, valueend - value); 1780 ret->children = tmp; 1781 ret->last = tmp; 1782 if (tmp != NULL) { 1783 tmp->doc = ret->doc; 1784 tmp->parent = (xmlNodePtr) ret; 1785 } 1786 } else { 1787 ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value, 1788 valueend - value); 1789 tmp = ret->children; 1790 while (tmp != NULL) { 1791 tmp->parent = (xmlNodePtr) ret; 1792 if (tmp->next == NULL) 1793 ret->last = tmp; 1794 tmp = tmp->next; 1795 } 1796 } 1797 } else if (value != NULL) { 1798 xmlNodePtr tmp; 1799 1800 tmp = xmlSAX2TextNode(ctxt, value, valueend - value); 1801 ret->children = tmp; 1802 ret->last = tmp; 1803 if (tmp != NULL) { 1804 tmp->doc = ret->doc; 1805 tmp->parent = (xmlNodePtr) ret; 1806 } 1807 } 1808 1809#ifdef LIBXML_VALID_ENABLED 1810 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed && 1811 ctxt->myDoc && ctxt->myDoc->intSubset) { 1812 /* 1813 * If we don't substitute entities, the validation should be 1814 * done on a value with replaced entities anyway. 1815 */ 1816 if (!ctxt->replaceEntities) { 1817 dup = xmlSAX2DecodeAttrEntities(ctxt, value, valueend); 1818 if (dup == NULL) { 1819 if (*valueend == 0) { 1820 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 1821 ctxt->myDoc, ctxt->node, ret, value); 1822 } else { 1823 /* 1824 * That should already be normalized. 1825 * cheaper to finally allocate here than duplicate 1826 * entry points in the full validation code 1827 */ 1828 dup = xmlStrndup(value, valueend - value); 1829 1830 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 1831 ctxt->myDoc, ctxt->node, ret, dup); 1832 } 1833 } else { 1834 /* 1835 * dup now contains a string of the flattened attribute 1836 * content with entities substitued. Check if we need to 1837 * apply an extra layer of normalization. 1838 * It need to be done twice ... it's an extra burden related 1839 * to the ability to keep references in attributes 1840 */ 1841 if (ctxt->attsSpecial != NULL) { 1842 xmlChar *nvalnorm; 1843 xmlChar fn[50]; 1844 xmlChar *fullname; 1845 1846 fullname = xmlBuildQName(localname, prefix, fn, 50); 1847 if (fullname != NULL) { 1848 ctxt->vctxt.valid = 1; 1849 nvalnorm = xmlValidCtxtNormalizeAttributeValue( 1850 &ctxt->vctxt, ctxt->myDoc, 1851 ctxt->node, fullname, dup); 1852 if (ctxt->vctxt.valid != 1) 1853 ctxt->valid = 0; 1854 1855 if ((fullname != fn) && (fullname != localname)) 1856 xmlFree(fullname); 1857 if (nvalnorm != NULL) { 1858 xmlFree(dup); 1859 dup = nvalnorm; 1860 } 1861 } 1862 } 1863 1864 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 1865 ctxt->myDoc, ctxt->node, ret, dup); 1866 } 1867 } else { 1868 /* 1869 * if entities already have been substitued, then 1870 * the attribute as passed is already normalized 1871 */ 1872 dup = xmlStrndup(value, valueend - value); 1873 1874 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, 1875 ctxt->myDoc, ctxt->node, ret, dup); 1876 } 1877 } else 1878#endif /* LIBXML_VALID_ENABLED */ 1879 if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) && 1880 (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) || 1881 ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) { 1882 /* 1883 * when validating, the ID registration is done at the attribute 1884 * validation level. Otherwise we have to do specific handling here. 1885 */ 1886 if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) { 1887 /* might be worth duplicate entry points and not copy */ 1888 if (dup == NULL) 1889 dup = xmlStrndup(value, valueend - value); 1890 xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret); 1891 } else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) { 1892 if (dup == NULL) 1893 dup = xmlStrndup(value, valueend - value); 1894 xmlAddRef(&ctxt->vctxt, ctxt->myDoc, dup, ret); 1895 } 1896 } 1897 if (dup != NULL) 1898 xmlFree(dup); 1899} 1900 1901/** 1902 * xmlSAX2StartElementNs: 1903 * @ctx: the user data (XML parser context) 1904 * @localname: the local name of the element 1905 * @prefix: the element namespace prefix if available 1906 * @URI: the element namespace name if available 1907 * @nb_namespaces: number of namespace definitions on that node 1908 * @namespaces: pointer to the array of prefix/URI pairs namespace definitions 1909 * @nb_attributes: the number of attributes on that node 1910 * @nb_defaulted: the number of defaulted attributes. 1911 * @attributes: pointer to the array of (localname/prefix/URI/value/end) 1912 * attribute values. 1913 * 1914 * SAX2 callback when an element start has been detected by the parser. 1915 * It provides the namespace informations for the element, as well as 1916 * the new namespace declarations on the element. 1917 */ 1918void 1919xmlSAX2StartElementNs(void *ctx, 1920 const xmlChar *localname, 1921 const xmlChar *prefix, 1922 const xmlChar *URI, 1923 int nb_namespaces, 1924 const xmlChar **namespaces, 1925 int nb_attributes, 1926 int nb_defaulted, 1927 const xmlChar **attributes) 1928{ 1929 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 1930 xmlNodePtr ret; 1931 xmlNodePtr parent = ctxt->node; 1932 xmlNsPtr last = NULL, ns; 1933 const xmlChar *uri, *pref; 1934 int i, j; 1935 1936 /* 1937 * First check on validity: 1938 */ 1939 if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) && 1940 ((ctxt->myDoc->intSubset == NULL) || 1941 ((ctxt->myDoc->intSubset->notations == NULL) && 1942 (ctxt->myDoc->intSubset->elements == NULL) && 1943 (ctxt->myDoc->intSubset->attributes == NULL) && 1944 (ctxt->myDoc->intSubset->entities == NULL)))) { 1945 if (ctxt->vctxt.error != NULL) { 1946 ctxt->vctxt.error(ctxt->vctxt.userData, 1947 "Validation failed: no DTD found !\n"); 1948 } 1949 ctxt->validate = 0; 1950 ctxt->valid = 0; 1951 ctxt->errNo = XML_ERR_NO_DTD; 1952 } 1953 1954 /* 1955 * allocate the node 1956 */ 1957 if (ctxt->freeElems != NULL) { 1958 ret = ctxt->freeElems; 1959 ctxt->freeElems = ret->next; 1960 ctxt->freeElemsNr--; 1961 memset(ret, 0, sizeof(xmlNode)); 1962 ret->type = XML_ELEMENT_NODE; 1963 1964 if (ctxt->dictNames) 1965 ret->name = localname; 1966 else 1967 ret->name = xmlStrdup(localname); 1968 1969 if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) 1970 xmlRegisterNodeDefaultValue(ret); 1971 } else { 1972 if (ctxt->dictNames) 1973 ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, 1974 (xmlChar *) localname, NULL); 1975 else 1976 ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL); 1977 if (ret == NULL) { 1978 ctxt->errNo = XML_ERR_NO_MEMORY; 1979 ctxt->instate = XML_PARSER_EOF; 1980 ctxt->disableSAX = 1; 1981 return; 1982 } 1983 } 1984 if (ctxt->linenumbers) { 1985 if (ctxt->input != NULL) 1986 ret->content = (void *) (long) ctxt->input->line; 1987 } 1988 1989 if (ctxt->myDoc->children == NULL) { 1990 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); 1991 } else if (parent == NULL) { 1992 parent = ctxt->myDoc->children; 1993 } 1994 /* 1995 * Build the namespace list 1996 */ 1997 for (i = 0,j = 0;j < nb_namespaces;j++) { 1998 pref = namespaces[i++]; 1999 uri = namespaces[i++]; 2000 ns = xmlNewNs(NULL, uri, pref); 2001 if (ns != NULL) { 2002 if (last == NULL) { 2003 ret->nsDef = last = ns; 2004 } else { 2005 last->next = ns; 2006 last = ns; 2007 } 2008 if ((URI != NULL) && (prefix == pref)) 2009 ret->ns = ns; 2010 } else { 2011 ctxt->errNo = XML_ERR_NO_MEMORY; 2012 ctxt->instate = XML_PARSER_EOF; 2013 ctxt->disableSAX = 1; 2014 return; 2015 } 2016#ifdef LIBXML_VALID_ENABLED 2017 if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed && 2018 ctxt->myDoc && ctxt->myDoc->intSubset) { 2019 ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc, 2020 ret, prefix, ns, uri); 2021 } 2022#endif /* LIBXML_VALID_ENABLED */ 2023 } 2024 ctxt->nodemem = -1; 2025 2026 /* 2027 * We are parsing a new node. 2028 */ 2029 nodePush(ctxt, ret); 2030 2031 /* 2032 * Link the child element 2033 */ 2034 if (parent != NULL) { 2035 if (parent->type == XML_ELEMENT_NODE) { 2036 xmlAddChild(parent, ret); 2037 } else { 2038 xmlAddSibling(parent, ret); 2039 } 2040 } 2041 2042 /* 2043 * Insert the defaulted attributes from the DTD only if requested: 2044 */ 2045 if ((nb_defaulted != 0) && 2046 ((ctxt->loadsubset & XML_COMPLETE_ATTRS) == 0)) 2047 nb_attributes -= nb_defaulted; 2048 2049 /* 2050 * Search the namespace if it wasn't already found 2051 */ 2052 if ((URI != NULL) && (ret->ns == NULL)) { 2053 ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix); 2054 if (ret->ns == NULL) { 2055 ns = xmlNewNs(ret, NULL, prefix); 2056 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) 2057 ctxt->sax->warning(ctxt->userData, 2058 "Namespace prefix %s was not found\n", prefix); 2059 } 2060 } 2061 2062 /* 2063 * process all the other attributes 2064 */ 2065 if (nb_attributes > 0) { 2066 for (j = 0,i = 0;i < nb_attributes;i++,j+=5) { 2067 xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1], 2068 attributes[j+3], attributes[j+4]); 2069 } 2070 } 2071 2072#ifdef LIBXML_VALID_ENABLED 2073 /* 2074 * If it's the Document root, finish the DTD validation and 2075 * check the document root element for validity 2076 */ 2077 if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) { 2078 int chk; 2079 2080 chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc); 2081 if (chk <= 0) 2082 ctxt->valid = 0; 2083 if (chk < 0) 2084 ctxt->wellFormed = 0; 2085 ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc); 2086 ctxt->vctxt.finishDtd = 1; 2087 } 2088#endif /* LIBXML_VALID_ENABLED */ 2089} 2090 2091/** 2092 * xmlSAX2EndElementNs: 2093 * @ctx: the user data (XML parser context) 2094 * @localname: the local name of the element 2095 * @prefix: the element namespace prefix if available 2096 * @URI: the element namespace name if available 2097 * 2098 * SAX2 callback when an element end has been detected by the parser. 2099 * It provides the namespace informations for the element. 2100 */ 2101void 2102xmlSAX2EndElementNs(void *ctx, 2103 const xmlChar * localname ATTRIBUTE_UNUSED, 2104 const xmlChar * prefix ATTRIBUTE_UNUSED, 2105 const xmlChar * URI ATTRIBUTE_UNUSED) 2106{ 2107 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 2108 xmlParserNodeInfo node_info; 2109 xmlNodePtr cur = ctxt->node; 2110 2111 /* Capture end position and add node */ 2112 if ((ctxt->record_info) && (cur != NULL)) { 2113 node_info.end_pos = ctxt->input->cur - ctxt->input->base; 2114 node_info.end_line = ctxt->input->line; 2115 node_info.node = cur; 2116 xmlParserAddNodeInfo(ctxt, &node_info); 2117 } 2118 ctxt->nodemem = -1; 2119 2120#ifdef LIBXML_VALID_ENABLED 2121 if (ctxt->validate && ctxt->wellFormed && 2122 ctxt->myDoc && ctxt->myDoc->intSubset) 2123 ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, cur); 2124#endif /* LIBXML_VALID_ENABLED */ 2125 2126 /* 2127 * end of parsing of this node. 2128 */ 2129 nodePop(ctxt); 2130} 2131 2132/** 2133 * xmlSAX2Reference: 2134 * @ctx: the user data (XML parser context) 2135 * @name: The entity name 2136 * 2137 * called when an entity xmlSAX2Reference is detected. 2138 */ 2139void 2140xmlSAX2Reference(void *ctx, const xmlChar *name) 2141{ 2142 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 2143 xmlNodePtr ret; 2144 2145#ifdef DEBUG_SAX 2146 xmlGenericError(xmlGenericErrorContext, 2147 "SAX.xmlSAX2Reference(%s)\n", name); 2148#endif 2149 if (name[0] == '#') 2150 ret = xmlNewCharRef(ctxt->myDoc, name); 2151 else 2152 ret = xmlNewReference(ctxt->myDoc, name); 2153#ifdef DEBUG_SAX_TREE 2154 xmlGenericError(xmlGenericErrorContext, 2155 "add xmlSAX2Reference %s to %s \n", name, ctxt->node->name); 2156#endif 2157 xmlAddChild(ctxt->node, ret); 2158} 2159 2160/** 2161 * xmlSAX2Characters: 2162 * @ctx: the user data (XML parser context) 2163 * @ch: a xmlChar string 2164 * @len: the number of xmlChar 2165 * 2166 * receiving some chars from the parser. 2167 */ 2168void 2169xmlSAX2Characters(void *ctx, const xmlChar *ch, int len) 2170{ 2171 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 2172 xmlNodePtr lastChild; 2173 2174#ifdef DEBUG_SAX 2175 xmlGenericError(xmlGenericErrorContext, 2176 "SAX.xmlSAX2Characters(%.30s, %d)\n", ch, len); 2177#endif 2178 /* 2179 * Handle the data if any. If there is no child 2180 * add it as content, otherwise if the last child is text, 2181 * concatenate it, else create a new node of type text. 2182 */ 2183 2184 if (ctxt->node == NULL) { 2185#ifdef DEBUG_SAX_TREE 2186 xmlGenericError(xmlGenericErrorContext, 2187 "add chars: ctxt->node == NULL !\n"); 2188#endif 2189 return; 2190 } 2191 lastChild = ctxt->node->last; 2192#ifdef DEBUG_SAX_TREE 2193 xmlGenericError(xmlGenericErrorContext, 2194 "add chars to %s \n", ctxt->node->name); 2195#endif 2196 2197 /* 2198 * Here we needed an accelerator mechanism in case of very large 2199 * elements. Use an attribute in the structure !!! 2200 */ 2201 if (lastChild == NULL) { 2202 lastChild = xmlSAX2TextNode(ctxt, ch, len); 2203 if (lastChild != NULL) { 2204 ctxt->node->children = lastChild; 2205 ctxt->node->last = lastChild; 2206 lastChild->parent = ctxt->node; 2207 lastChild->doc = ctxt->node->doc; 2208 ctxt->nodelen = len; 2209 ctxt->nodemem = len + 1; 2210 } 2211 } else { 2212 int coalesceText = (lastChild != NULL) && 2213 (lastChild->type == XML_TEXT_NODE) && 2214 (lastChild->name == xmlStringText); 2215 if ((coalesceText) && (ctxt->nodemem != 0)) { 2216 /* 2217 * The whole point of maintaining nodelen and nodemem, 2218 * xmlTextConcat is too costly, i.e. compute length, 2219 * reallocate a new buffer, move data, append ch. Here 2220 * We try to minimaze realloc() uses and avoid copying 2221 * and recomputing length over and over. 2222 */ 2223 if (ctxt->nodelen + len >= ctxt->nodemem) { 2224 xmlChar *newbuf; 2225 int size; 2226 2227 size = ctxt->nodemem + len; 2228 size *= 2; 2229 newbuf = (xmlChar *) xmlRealloc(lastChild->content,size); 2230 if (newbuf == NULL) { 2231 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 2232 ctxt->sax->error(ctxt->userData, 2233 "SAX.xmlSAX2Characters(): out of memory\n"); 2234 ctxt->errNo = XML_ERR_NO_MEMORY; 2235 ctxt->instate = XML_PARSER_EOF; 2236 ctxt->disableSAX = 1; 2237 return; 2238 } 2239 ctxt->nodemem = size; 2240 lastChild->content = newbuf; 2241 } 2242 memcpy(&lastChild->content[ctxt->nodelen], ch, len); 2243 ctxt->nodelen += len; 2244 lastChild->content[ctxt->nodelen] = 0; 2245 } else if (coalesceText) { 2246 if (xmlTextConcat(lastChild, ch, len)) { 2247 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 2248 ctxt->sax->error(ctxt->userData, 2249 "SAX.xmlSAX2Characters(): out of memory\n"); 2250 ctxt->errNo = XML_ERR_NO_MEMORY; 2251 ctxt->instate = XML_PARSER_EOF; 2252 ctxt->disableSAX = 1; 2253 } 2254 if (ctxt->node->children != NULL) { 2255 ctxt->nodelen = xmlStrlen(lastChild->content); 2256 ctxt->nodemem = ctxt->nodelen + 1; 2257 } 2258 } else { 2259 /* Mixed content, first time */ 2260 lastChild = xmlSAX2TextNode(ctxt, ch, len); 2261 if (lastChild != NULL) { 2262 xmlAddChild(ctxt->node, lastChild); 2263 if (ctxt->node->children != NULL) { 2264 ctxt->nodelen = len; 2265 ctxt->nodemem = len + 1; 2266 } 2267 } 2268 } 2269 } 2270} 2271 2272/** 2273 * xmlSAX2IgnorableWhitespace: 2274 * @ctx: the user data (XML parser context) 2275 * @ch: a xmlChar string 2276 * @len: the number of xmlChar 2277 * 2278 * receiving some ignorable whitespaces from the parser. 2279 * UNUSED: by default the DOM building will use xmlSAX2Characters 2280 */ 2281void 2282xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED) 2283{ 2284 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ 2285#ifdef DEBUG_SAX 2286 xmlGenericError(xmlGenericErrorContext, 2287 "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch, len); 2288#endif 2289} 2290 2291/** 2292 * xmlSAX2ProcessingInstruction: 2293 * @ctx: the user data (XML parser context) 2294 * @target: the target name 2295 * @data: the PI data's 2296 * 2297 * A processing instruction has been parsed. 2298 */ 2299void 2300xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target, 2301 const xmlChar *data) 2302{ 2303 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 2304 xmlNodePtr ret; 2305 xmlNodePtr parent = ctxt->node; 2306 2307#ifdef DEBUG_SAX 2308 xmlGenericError(xmlGenericErrorContext, 2309 "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target, data); 2310#endif 2311 2312 ret = xmlNewPI(target, data); 2313 if (ret == NULL) return; 2314 parent = ctxt->node; 2315 2316 if (ctxt->inSubset == 1) { 2317 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret); 2318 return; 2319 } else if (ctxt->inSubset == 2) { 2320 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret); 2321 return; 2322 } 2323 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) { 2324#ifdef DEBUG_SAX_TREE 2325 xmlGenericError(xmlGenericErrorContext, 2326 "Setting PI %s as root\n", target); 2327#endif 2328 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); 2329 return; 2330 } 2331 if (parent->type == XML_ELEMENT_NODE) { 2332#ifdef DEBUG_SAX_TREE 2333 xmlGenericError(xmlGenericErrorContext, 2334 "adding PI %s child to %s\n", target, parent->name); 2335#endif 2336 xmlAddChild(parent, ret); 2337 } else { 2338#ifdef DEBUG_SAX_TREE 2339 xmlGenericError(xmlGenericErrorContext, 2340 "adding PI %s sibling to ", target); 2341 xmlDebugDumpOneNode(stderr, parent, 0); 2342#endif 2343 xmlAddSibling(parent, ret); 2344 } 2345} 2346 2347/** 2348 * xmlSAX2Comment: 2349 * @ctx: the user data (XML parser context) 2350 * @value: the xmlSAX2Comment content 2351 * 2352 * A xmlSAX2Comment has been parsed. 2353 */ 2354void 2355xmlSAX2Comment(void *ctx, const xmlChar *value) 2356{ 2357 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 2358 xmlNodePtr ret; 2359 xmlNodePtr parent = ctxt->node; 2360 2361#ifdef DEBUG_SAX 2362 xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Comment(%s)\n", value); 2363#endif 2364 ret = xmlNewDocComment(ctxt->myDoc, value); 2365 if (ret == NULL) return; 2366 2367 if (ctxt->inSubset == 1) { 2368 xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret); 2369 return; 2370 } else if (ctxt->inSubset == 2) { 2371 xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret); 2372 return; 2373 } 2374 if ((ctxt->myDoc->children == NULL) || (parent == NULL)) { 2375#ifdef DEBUG_SAX_TREE 2376 xmlGenericError(xmlGenericErrorContext, 2377 "Setting xmlSAX2Comment as root\n"); 2378#endif 2379 xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); 2380 return; 2381 } 2382 if (parent->type == XML_ELEMENT_NODE) { 2383#ifdef DEBUG_SAX_TREE 2384 xmlGenericError(xmlGenericErrorContext, 2385 "adding xmlSAX2Comment child to %s\n", parent->name); 2386#endif 2387 xmlAddChild(parent, ret); 2388 } else { 2389#ifdef DEBUG_SAX_TREE 2390 xmlGenericError(xmlGenericErrorContext, 2391 "adding xmlSAX2Comment sibling to "); 2392 xmlDebugDumpOneNode(stderr, parent, 0); 2393#endif 2394 xmlAddSibling(parent, ret); 2395 } 2396} 2397 2398/** 2399 * xmlSAX2CDataBlock: 2400 * @ctx: the user data (XML parser context) 2401 * @value: The pcdata content 2402 * @len: the block length 2403 * 2404 * called when a pcdata block has been parsed 2405 */ 2406void 2407xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len) 2408{ 2409 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 2410 xmlNodePtr ret, lastChild; 2411 2412#ifdef DEBUG_SAX 2413 xmlGenericError(xmlGenericErrorContext, 2414 "SAX.pcdata(%.10s, %d)\n", value, len); 2415#endif 2416 lastChild = xmlGetLastChild(ctxt->node); 2417#ifdef DEBUG_SAX_TREE 2418 xmlGenericError(xmlGenericErrorContext, 2419 "add chars to %s \n", ctxt->node->name); 2420#endif 2421 if ((lastChild != NULL) && 2422 (lastChild->type == XML_CDATA_SECTION_NODE)) { 2423 xmlTextConcat(lastChild, value, len); 2424 } else { 2425 ret = xmlNewCDataBlock(ctxt->myDoc, value, len); 2426 xmlAddChild(ctxt->node, ret); 2427 } 2428} 2429 2430static int xmlSAX2DefaultVersionValue = 2; 2431 2432/** 2433 * xmlSAXDefaultVersion: 2434 * @version: the version, 1 or 2 2435 * 2436 * Set the default version of SAX used globally by the library. 2437 * Note that this may not be a good thing to do from a library 2438 * it is better to use xmlSAXVersion() to set up specifically the 2439 * version for a given parsing context. 2440 * 2441 * Returns the previous value in case of success and -1 in case of error. 2442 */ 2443int 2444xmlSAXDefaultVersion(int version) 2445{ 2446 int ret = xmlSAX2DefaultVersionValue; 2447 2448 if ((version != 1) && (version != 2)) 2449 return(-1); 2450 xmlSAX2DefaultVersionValue = version; 2451 return(ret); 2452} 2453 2454/** 2455 * xmlSAXVersion: 2456 * @hdlr: the SAX handler 2457 * @version: the version, 1 or 2 2458 * 2459 * Initialize the default XML SAX handler according to the version 2460 * 2461 * Returns 0 in case of success and -1 in case of error. 2462 */ 2463int 2464xmlSAXVersion(xmlSAXHandler *hdlr, int version) 2465{ 2466 if (hdlr == NULL) return(-1); 2467 if (version == 1) { 2468 hdlr->startElement = xmlSAX2StartElement; 2469 hdlr->endElement = xmlSAX2EndElement; 2470 hdlr->initialized = 1; 2471 } else if (version == 2) { 2472 hdlr->startElement = NULL; 2473 hdlr->endElement = NULL; 2474 hdlr->startElementNs = xmlSAX2StartElementNs; 2475 hdlr->endElementNs = xmlSAX2EndElementNs; 2476 hdlr->initialized = XML_SAX2_MAGIC; 2477 } else 2478 return(-1); 2479 hdlr->internalSubset = xmlSAX2InternalSubset; 2480 hdlr->externalSubset = xmlSAX2ExternalSubset; 2481 hdlr->isStandalone = xmlSAX2IsStandalone; 2482 hdlr->hasInternalSubset = xmlSAX2HasInternalSubset; 2483 hdlr->hasExternalSubset = xmlSAX2HasExternalSubset; 2484 hdlr->resolveEntity = xmlSAX2ResolveEntity; 2485 hdlr->getEntity = xmlSAX2GetEntity; 2486 hdlr->getParameterEntity = xmlSAX2GetParameterEntity; 2487 hdlr->entityDecl = xmlSAX2EntityDecl; 2488 hdlr->attributeDecl = xmlSAX2AttributeDecl; 2489 hdlr->elementDecl = xmlSAX2ElementDecl; 2490 hdlr->notationDecl = xmlSAX2NotationDecl; 2491 hdlr->unparsedEntityDecl = xmlSAX2UnparsedEntityDecl; 2492 hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator; 2493 hdlr->startDocument = xmlSAX2StartDocument; 2494 hdlr->endDocument = xmlSAX2EndDocument; 2495 hdlr->reference = xmlSAX2Reference; 2496 hdlr->characters = xmlSAX2Characters; 2497 hdlr->cdataBlock = xmlSAX2CDataBlock; 2498 hdlr->ignorableWhitespace = xmlSAX2Characters; 2499 hdlr->processingInstruction = xmlSAX2ProcessingInstruction; 2500 hdlr->comment = xmlSAX2Comment; 2501 hdlr->warning = xmlParserWarning; 2502 hdlr->error = xmlParserError; 2503 hdlr->fatalError = xmlParserError; 2504 2505 return(0); 2506} 2507 2508/** 2509 * xmlSAX2InitDefaultSAXHandler: 2510 * @hdlr: the SAX handler 2511 * @warning: flag if non-zero sets the handler warning procedure 2512 * 2513 * Initialize the default XML SAX2 handler 2514 */ 2515void 2516xmlSAX2InitDefaultSAXHandler(xmlSAXHandler *hdlr, int warning) 2517{ 2518 if ((hdlr == NULL) || (hdlr->initialized != 0)) 2519 return; 2520 2521 xmlSAXVersion(hdlr, xmlSAX2DefaultVersionValue); 2522 if (warning == 0) 2523 hdlr->warning = NULL; 2524 else 2525 hdlr->warning = xmlParserWarning; 2526} 2527 2528/** 2529 * xmlDefaultSAXHandlerInit: 2530 * 2531 * Initialize the default SAX2 handler 2532 */ 2533void 2534xmlDefaultSAXHandlerInit(void) 2535{ 2536 xmlSAXVersion((xmlSAXHandlerPtr) &xmlDefaultSAXHandler, 1); 2537} 2538 2539#ifdef LIBXML_HTML_ENABLED 2540 2541/** 2542 * xmlSAX2InitHtmlDefaultSAXHandler: 2543 * @hdlr: the SAX handler 2544 * 2545 * Initialize the default HTML SAX2 handler 2546 */ 2547void 2548xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr) 2549{ 2550 if(hdlr->initialized != 0) 2551 return; 2552 2553 hdlr->internalSubset = xmlSAX2InternalSubset; 2554 hdlr->externalSubset = NULL; 2555 hdlr->isStandalone = NULL; 2556 hdlr->hasInternalSubset = NULL; 2557 hdlr->hasExternalSubset = NULL; 2558 hdlr->resolveEntity = NULL; 2559 hdlr->getEntity = xmlSAX2GetEntity; 2560 hdlr->getParameterEntity = NULL; 2561 hdlr->entityDecl = NULL; 2562 hdlr->attributeDecl = NULL; 2563 hdlr->elementDecl = NULL; 2564 hdlr->notationDecl = NULL; 2565 hdlr->unparsedEntityDecl = NULL; 2566 hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator; 2567 hdlr->startDocument = xmlSAX2StartDocument; 2568 hdlr->endDocument = xmlSAX2EndDocument; 2569 hdlr->startElement = xmlSAX2StartElement; 2570 hdlr->endElement = xmlSAX2EndElement; 2571 hdlr->reference = NULL; 2572 hdlr->characters = xmlSAX2Characters; 2573 hdlr->cdataBlock = xmlSAX2CDataBlock; 2574 hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace; 2575 hdlr->processingInstruction = NULL; 2576 hdlr->comment = xmlSAX2Comment; 2577 hdlr->warning = xmlParserWarning; 2578 hdlr->error = xmlParserError; 2579 hdlr->fatalError = xmlParserError; 2580 2581 hdlr->initialized = 1; 2582} 2583 2584/** 2585 * htmlDefaultSAXHandlerInit: 2586 * 2587 * Initialize the default SAX handler 2588 */ 2589void 2590htmlDefaultSAXHandlerInit(void) 2591{ 2592 xmlSAX2InitHtmlDefaultSAXHandler((xmlSAXHandlerPtr) &htmlDefaultSAXHandler); 2593} 2594 2595#endif /* LIBXML_HTML_ENABLED */ 2596 2597#ifdef LIBXML_DOCB_ENABLED 2598 2599/** 2600 * xmlSAX2InitDocbDefaultSAXHandler: 2601 * @hdlr: the SAX handler 2602 * 2603 * Initialize the default DocBook SAX2 handler 2604 */ 2605void 2606xmlSAX2InitDocbDefaultSAXHandler(xmlSAXHandler *hdlr) 2607{ 2608 if(hdlr->initialized != 0) 2609 return; 2610 2611 hdlr->internalSubset = xmlSAX2InternalSubset; 2612 hdlr->externalSubset = NULL; 2613 hdlr->isStandalone = xmlSAX2IsStandalone; 2614 hdlr->hasInternalSubset = xmlSAX2HasInternalSubset; 2615 hdlr->hasExternalSubset = xmlSAX2HasExternalSubset; 2616 hdlr->resolveEntity = xmlSAX2ResolveEntity; 2617 hdlr->getEntity = xmlSAX2GetEntity; 2618 hdlr->getParameterEntity = NULL; 2619 hdlr->entityDecl = xmlSAX2EntityDecl; 2620 hdlr->attributeDecl = NULL; 2621 hdlr->elementDecl = NULL; 2622 hdlr->notationDecl = NULL; 2623 hdlr->unparsedEntityDecl = NULL; 2624 hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator; 2625 hdlr->startDocument = xmlSAX2StartDocument; 2626 hdlr->endDocument = xmlSAX2EndDocument; 2627 hdlr->startElement = xmlSAX2StartElement; 2628 hdlr->endElement = xmlSAX2EndElement; 2629 hdlr->reference = xmlSAX2Reference; 2630 hdlr->characters = xmlSAX2Characters; 2631 hdlr->cdataBlock = NULL; 2632 hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace; 2633 hdlr->processingInstruction = NULL; 2634 hdlr->comment = xmlSAX2Comment; 2635 hdlr->warning = xmlParserWarning; 2636 hdlr->error = xmlParserError; 2637 hdlr->fatalError = xmlParserError; 2638 2639 hdlr->initialized = XML_SAX2_MAGIC; 2640} 2641 2642/** 2643 * docbDefaultSAXHandlerInit: 2644 * 2645 * Initialize the default SAX handler 2646 */ 2647void 2648docbDefaultSAXHandlerInit(void) 2649{ 2650 xmlSAX2InitDocbDefaultSAXHandler((xmlSAXHandlerPtr) &docbDefaultSAXHandler); 2651} 2652 2653#endif /* LIBXML_DOCB_ENABLED */ 2654