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