📄 sax2.c
字号:
/* * SAX2.c : Default SAX2 handler to build a tree. * * See Copyright for the status of this software. * * Daniel Veillard <daniel@veillard.com> */#define IN_LIBXML#include "libxml.h"#include <stdlib.h>#include <string.h>#include <libxml/xmlmemory.h>#include <libxml/tree.h>#include <libxml/parser.h>#include <libxml/parserInternals.h>#include <libxml/valid.h>#include <libxml/entities.h>#include <libxml/xmlerror.h>#include <libxml/debugXML.h>#include <libxml/xmlIO.h>#include <libxml/SAX.h>#include <libxml/uri.h>#include <libxml/valid.h>#include <libxml/HTMLtree.h>#include <libxml/globals.h>/* #define DEBUG_SAX2 *//* #define DEBUG_SAX2_TREE *//** * TODO: * * macro to flag unimplemented blocks * XML_CATALOG_PREFER user env to select between system/public prefered * option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk> *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with *> values "system" and "public". I have made the default be "system" to *> match yours. */#define TODO \ xmlGenericError(xmlGenericErrorContext, \ "Unimplemented block at %s:%d\n", \ __FILE__, __LINE__);/* * xmlSAX2ErrMemory: * @ctxt: an XML validation parser context * @msg: a string to accompany the error message */static voidxmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) { if (ctxt != NULL) { if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) ctxt->sax->error(ctxt->userData, "%s: out of memory\n", msg); ctxt->errNo = XML_ERR_NO_MEMORY; ctxt->instate = XML_PARSER_EOF; ctxt->disableSAX = 1; }}/** * xmlValidError: * @ctxt: an XML validation parser context * @error: the error number * @msg: the error message * @str1: extra data * @str2: extra data * * Handle a validation error */static voidxmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const char *str1, const char *str2){ xmlStructuredErrorFunc schannel = NULL; if ((ctxt != NULL) && (ctxt->disableSAX != 0) && (ctxt->instate == XML_PARSER_EOF)) return; if (ctxt != NULL) { ctxt->errNo = error; if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC)) schannel = ctxt->sax->serror; __xmlRaiseError(schannel, ctxt->vctxt.error, ctxt->vctxt.userData, ctxt, NULL, XML_FROM_DTD, error, XML_ERR_ERROR, NULL, 0, (const char *) str1, (const char *) str2, NULL, 0, 0, msg, (const char *) str1, (const char *) str2); ctxt->valid = 0; } else { __xmlRaiseError(schannel, NULL, NULL, ctxt, NULL, XML_FROM_DTD, error, XML_ERR_ERROR, NULL, 0, (const char *) str1, (const char *) str2, NULL, 0, 0, msg, (const char *) str1, (const char *) str2); }}/** * xmlFatalErrMsg: * @ctxt: an XML parser context * @error: the error number * @msg: the error message * @str1: an error string * @str2: an error string * * Handle a fatal parser error, i.e. violating Well-Formedness constraints */static voidxmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar *str1, const xmlChar *str2){ if ((ctxt != NULL) && (ctxt->disableSAX != 0) && (ctxt->instate == XML_PARSER_EOF)) return; if (ctxt != NULL) ctxt->errNo = error; __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL, NULL, 0, (const char *) str1, (const char *) str2, NULL, 0, 0, msg, str1, str2); if (ctxt != NULL) { ctxt->wellFormed = 0; ctxt->valid = 0; if (ctxt->recovery == 0) ctxt->disableSAX = 1; }}/** * xmlWarnMsg: * @ctxt: an XML parser context * @error: the error number * @msg: the error message * @str1: an error string * @str2: an error string * * Handle a parser warning */static voidxmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar *str1){ if ((ctxt != NULL) && (ctxt->disableSAX != 0) && (ctxt->instate == XML_PARSER_EOF)) return; if (ctxt != NULL) ctxt->errNo = error; __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_WARNING, NULL, 0, (const char *) str1, NULL, NULL, 0, 0, msg, str1);}/** * xmlNsErrMsg: * @ctxt: an XML parser context * @error: the error number * @msg: the error message * @str1: an error string * @str2: an error string * * Handle a namespace error */static voidxmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar *str1, const xmlChar *str2){ if ((ctxt != NULL) && (ctxt->disableSAX != 0) && (ctxt->instate == XML_PARSER_EOF)) return; if (ctxt != NULL) ctxt->errNo = error; __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error, XML_ERR_ERROR, NULL, 0, (const char *) str1, (const char *) str2, NULL, 0, 0, msg, str1, str2);}/** * xmlNsWarnMsg: * @ctxt: an XML parser context * @error: the error number * @msg: the error message * @str1: an error string * * Handle a namespace warning */static voidxmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar *str1, const xmlChar *str2){ if ((ctxt != NULL) && (ctxt->disableSAX != 0) && (ctxt->instate == XML_PARSER_EOF)) return; if (ctxt != NULL) ctxt->errNo = error; __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error, XML_ERR_WARNING, NULL, 0, (const char *) str1, (const char *) str2, NULL, 0, 0, msg, str1, str2);}/** * xmlSAX2GetPublicId: * @ctx: the user data (XML parser context) * * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN" * * Returns a xmlChar * */const xmlChar *xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED){ /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ return(NULL);}/** * xmlSAX2GetSystemId: * @ctx: the user data (XML parser context) * * Provides the system ID, basically URL or filename e.g. * http://www.sgmlsource.com/dtds/memo.dtd * * Returns a xmlChar * */const xmlChar *xmlSAX2GetSystemId(void *ctx){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; if ((ctx == NULL) || (ctxt->input == NULL)) return(NULL); return((const xmlChar *) ctxt->input->filename); }/** * xmlSAX2GetLineNumber: * @ctx: the user data (XML parser context) * * Provide the line number of the current parsing point. * * Returns an int */intxmlSAX2GetLineNumber(void *ctx){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; if ((ctx == NULL) || (ctxt->input == NULL)) return(0); return(ctxt->input->line);}/** * xmlSAX2GetColumnNumber: * @ctx: the user data (XML parser context) * * Provide the column number of the current parsing point. * * Returns an int */intxmlSAX2GetColumnNumber(void *ctx){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; if ((ctx == NULL) || (ctxt->input == NULL)) return(0); return(ctxt->input->col);}/** * xmlSAX2IsStandalone: * @ctx: the user data (XML parser context) * * Is this document tagged standalone ? * * Returns 1 if true */intxmlSAX2IsStandalone(void *ctx){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; if ((ctx == NULL) || (ctxt->myDoc == NULL)) return(0); return(ctxt->myDoc->standalone == 1);}/** * xmlSAX2HasInternalSubset: * @ctx: the user data (XML parser context) * * Does this document has an internal subset * * Returns 1 if true */intxmlSAX2HasInternalSubset(void *ctx){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0); return(ctxt->myDoc->intSubset != NULL);}/** * xmlSAX2HasExternalSubset: * @ctx: the user data (XML parser context) * * Does this document has an external subset * * Returns 1 if true */intxmlSAX2HasExternalSubset(void *ctx){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0); return(ctxt->myDoc->extSubset != NULL);}/** * xmlSAX2InternalSubset: * @ctx: the user data (XML parser context) * @name: the root element name * @ExternalID: the external ID * @SystemID: the SYSTEM ID (e.g. filename or URL) * * Callback on internal subset declaration. */voidxmlSAX2InternalSubset(void *ctx, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlDtdPtr dtd; if (ctx == NULL) return;#ifdef DEBUG_SAX xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n", name, ExternalID, SystemID);#endif if (ctxt->myDoc == NULL) return; dtd = xmlGetIntSubset(ctxt->myDoc); if (dtd != NULL) { if (ctxt->html) return; xmlUnlinkNode((xmlNodePtr) dtd); xmlFreeDtd(dtd); ctxt->myDoc->intSubset = NULL; } ctxt->myDoc->intSubset = xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID); if (ctxt->myDoc->intSubset == NULL) xmlSAX2ErrMemory(ctxt, "xmlSAX2InternalSubset");}/** * xmlSAX2ExternalSubset: * @ctx: the user data (XML parser context) * @name: the root element name * @ExternalID: the external ID * @SystemID: the SYSTEM ID (e.g. filename or URL) * * Callback on external subset declaration. */voidxmlSAX2ExternalSubset(void *ctx, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; if (ctx == NULL) return;#ifdef DEBUG_SAX xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n", name, ExternalID, SystemID);#endif if (((ExternalID != NULL) || (SystemID != NULL)) && (((ctxt->validate) || (ctxt->loadsubset != 0)) && (ctxt->wellFormed && ctxt->myDoc))) { /* * Try to fetch and parse the external subset. */ xmlParserInputPtr oldinput; int oldinputNr; int oldinputMax; xmlParserInputPtr *oldinputTab; xmlParserInputPtr input = NULL; xmlCharEncoding enc; int oldcharset; /* * Ask the Entity resolver to load the damn thing */ if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL)) input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID, SystemID); if (input == NULL) { return; } xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID); /* * make sure we won't destroy the main document context */ oldinput = ctxt->input; oldinputNr = ctxt->inputNr; oldinputMax = ctxt->inputMax; oldinputTab = ctxt->inputTab; oldcharset = ctxt->charset; ctxt->inputTab = (xmlParserInputPtr *) xmlMalloc(5 * sizeof(xmlParserInputPtr)); if (ctxt->inputTab == NULL) { xmlSAX2ErrMemory(ctxt, "xmlSAX2ExternalSubset"); ctxt->input = oldinput; ctxt->inputNr = oldinputNr; ctxt->inputMax = oldinputMax; ctxt->inputTab = oldinputTab; ctxt->charset = oldcharset; return; } ctxt->inputNr = 0; ctxt->inputMax = 5; ctxt->input = NULL; xmlPushInput(ctxt, input); /* * On the fly encoding conversion if needed */ if (ctxt->input->length >= 4) { enc = xmlDetectCharEncoding(ctxt->input->cur, 4); xmlSwitchEncoding(ctxt, enc); } if (input->filename == NULL) input->filename = (char *) xmlCanonicPath(SystemID); input->line = 1; input->col = 1; input->base = ctxt->input->cur; input->cur = ctxt->input->cur; input->free = NULL; /* * let's parse that entity knowing it's an external subset. */ xmlParseExternalSubset(ctxt, ExternalID, SystemID); /* * Free up the external entities */ while (ctxt->inputNr > 1) xmlPopInput(ctxt); xmlFreeInputStream(ctxt->input); xmlFree(ctxt->inputTab); /* * Restore the parsing context of the main entity */ ctxt->input = oldinput; ctxt->inputNr = oldinputNr; ctxt->inputMax = oldinputMax; ctxt->inputTab = oldinputTab; ctxt->charset = oldcharset; /* ctxt->wellFormed = oldwellFormed; */ }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -