📄 sax2.c
字号:
* 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; */
}
}
/**
* xmlSAX2ResolveEntity:
* @ctx: the user data (XML parser context)
* @publicId: The public ID of the entity
* @systemId: The system ID of the entity
*
* The entity loader, to control the loading of external entities,
* the application can either:
* - override this xmlSAX2ResolveEntity() callback in the SAX block
* - or better use the xmlSetExternalEntityLoader() function to
* set up it's own entity resolution routine
*
* Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
*/
xmlParserInputPtr
xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
xmlParserInputPtr ret;
xmlChar *URI;
const char *base = NULL;
if (ctx == NULL) return(NULL);
if (ctxt->input != NULL)
base = ctxt->input->filename;
if (base == NULL)
base = ctxt->directory;
URI = xmlBuildURI(systemId, (const xmlChar *) base);
#ifdef DEBUG_SAX
xmlGenericError(xmlGenericErrorContext,
"SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId, systemId);
#endif
ret = xmlLoadExternalEntity((const char *) URI,
(const char *) publicId, ctxt);
if (URI != NULL)
xmlFree(URI);
return(ret);
}
/**
* xmlSAX2GetEntity:
* @ctx: the user data (XML parser context)
* @name: The entity name
*
* Get an entity by name
*
* Returns the xmlEntityPtr if found.
*/
xmlEntityPtr
xmlSAX2GetEntity(void *ctx, const xmlChar *name)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
xmlEntityPtr ret = NULL;
if (ctx == NULL) return(NULL);
#ifdef DEBUG_SAX
xmlGenericError(xmlGenericErrorContext,
"SAX.xmlSAX2GetEntity(%s)\n", name);
#endif
if (ctxt->inSubset == 0) {
ret = xmlGetPredefinedEntity(name);
if (ret != NULL)
return(ret);
}
if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1)) {
if (ctxt->inSubset == 2) {
ctxt->myDoc->standalone = 0;
ret = xmlGetDocEntity(ctxt->myDoc, name);
ctxt->myDoc->standalone = 1;
} else {
ret = xmlGetDocEntity(ctxt->myDoc, name);
if (ret == NULL) {
ctxt->myDoc->standalone = 0;
ret = xmlGetDocEntity(ctxt->myDoc, name);
if (ret != NULL) {
xmlFatalErrMsg(ctxt, XML_ERR_NOT_STANDALONE,
"Entity(%s) document marked standalone but requires external subset\n",
name, NULL);
}
ctxt->myDoc->standalone = 1;
}
}
} else {
ret = xmlGetDocEntity(ctxt->myDoc, name);
}
if ((ret != NULL) &&
((ctxt->validate) || (ctxt->replaceEntities)) &&
(ret->children == NULL) &&
(ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
int val;
/*
* for validation purposes we really need to fetch and
* parse the external entity
*/
xmlNodePtr children;
val = xmlParseCtxtExternalEntity(ctxt, ret->URI,
ret->ExternalID, &children);
if (val == 0) {
xmlAddChildList((xmlNodePtr) ret, children);
} else {
xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
"Failure to process entity %s\n", name, NULL);
ctxt->validate = 0;
return(NULL);
}
ret->owner = 1;
}
return(ret);
}
/**
* xmlSAX2GetParameterEntity:
* @ctx: the user data (XML parser context)
* @name: The entity name
*
* Get a parameter entity by name
*
* Returns the xmlEntityPtr if found.
*/
xmlEntityPtr
xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
xmlEntityPtr ret;
if (ctx == NULL) return(NULL);
#ifdef DEBUG_SAX
xmlGenericError(xmlGenericErrorContext,
"SAX.xmlSAX2GetParameterEntity(%s)\n", name);
#endif
ret = xmlGetParameterEntity(ctxt->myDoc, name);
return(ret);
}
/**
* xmlSAX2EntityDecl:
* @ctx: the user data (XML parser context)
* @name: the entity name
* @type: the entity type
* @publicId: The public ID of the entity
* @systemId: The system ID of the entity
* @content: the entity value (without processing).
*
* An entity definition has been parsed
*/
void
xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type,
const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
{
xmlEntityPtr ent;
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
if (ctx == NULL) return;
#ifdef DEBUG_SAX
xmlGenericError(xmlGenericErrorContext,
"SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n",
name, type, publicId, systemId, content);
#endif
if (ctxt->inSubset == 1) {
ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
systemId, content);
if ((ent == NULL) && (ctxt->pedantic))
xmlWarnMsg(ctxt, XML_WAR_ENTITY_REDEFINED,
"Entity(%s) already defined in the internal subset\n",
name);
if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
xmlChar *URI;
const char *base = NULL;
if (ctxt->input != NULL)
base = ctxt->input->filename;
if (base == NULL)
base = ctxt->directory;
URI = xmlBuildURI(systemId, (const xmlChar *) base);
ent->URI = URI;
}
} else if (ctxt->inSubset == 2) {
ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
systemId, content);
if ((ent == NULL) && (ctxt->pedantic) &&
(ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
ctxt->sax->warning(ctxt->userData,
"Entity(%s) already defined in the external subset\n", name);
if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
xmlChar *URI;
const char *base = NULL;
if (ctxt->input != NULL)
base = ctxt->input->filename;
if (base == NULL)
base = ctxt->directory;
URI = xmlBuildURI(systemId, (const xmlChar *) base);
ent->URI = URI;
}
} else {
xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
"SAX.xmlSAX2EntityDecl(%s) called while not in subset\n",
name, NULL);
}
}
/**
* xmlSAX2AttributeDecl:
* @ctx: the user data (XML parser context)
* @elem: the name of the element
* @fullname: the attribute name
* @type: the attribute type
* @def: the type of default value
* @defaultValue: the attribute default value
* @tree: the tree of enumerated value set
*
* An attribute definition has been parsed
*/
void
xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
int type, int def, const xmlChar *defaultValue,
xmlEnumerationPtr tree)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
xmlAttributePtr attr;
xmlChar *name = NULL, *prefix = NULL;
if (ctx == NULL) return;
#ifdef DEBUG_SAX
xmlGenericError(xmlGenericErrorContext,
"SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n",
elem, fullname, type, def, defaultValue);
#endif
if ((xmlStrEqual(fullname, BAD_CAST "xml:id")) &&
(type != XML_ATTRIBUTE_ID)) {
/*
* Raise the error but keep the validity flag
*/
int tmp = ctxt->valid;
xmlErrValid(ctxt, XML_DTD_XMLID_TYPE,
"xml:id : attribute type should be ID\n", NULL, NULL);
ctxt->valid = tmp;
}
/* TODO: optimize name/prefix allocation */
name = xmlSplitQName(ctxt, fullname, &prefix);
ctxt->vctxt.valid = 1;
if (ctxt->inSubset == 1)
attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
name, prefix, (xmlAttributeType) type,
(xmlAttributeDefault) def, defaultValue, tree);
else if (ctxt->inSubset == 2)
attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
name, prefix, (xmlAttributeType) type,
(xmlAttributeDefault) def, defaultValue, tree);
else {
xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
"SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n",
name, NULL);
xmlFreeEnumeration(tree);
return;
}
#ifdef LIBXML_VALID_ENABLED
if (ctxt->vctxt.valid == 0)
ctxt->valid = 0;
if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) &&
(ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset != NULL))
ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
attr);
#endif /* LIBXML_VALID_ENABLED */
if (prefix != NULL)
xmlFree(prefix);
if (name != NULL)
xmlFree(name);
}
/**
* xmlSAX2ElementDecl:
* @ctx: the user data (XML parser context)
* @name: the element name
* @type: the element type
* @content: the element value tree
*
* An element definition has been parsed
*/
void
xmlSAX2ElementDecl(void *ctx, const xmlChar * name, int type,
xmlElementContentPtr content)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
xmlElementPtr elem = NULL;
if (ctx == NULL) return;
#ifdef DEBUG_SAX
xmlGenericError(xmlGenericErrorContext,
"SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name, type);
#endif
if (ctxt->inSubset == 1)
elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
name, (xmlElementTypeVal) type, content);
else if (ctxt->inSubset == 2)
elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
name, (xmlElementTypeVal) type, content);
else {
xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
"SAX.xmlSAX2ElementDecl(%s) called while not in subset\n",
name, NULL);
return;
}
#ifdef LIBXML_VALID_ENABLED
if (elem == NULL)
ctxt->valid = 0;
if (ctxt->validate && ctxt->wellFormed &&
ctxt->myDoc && ctxt->myDoc->intSubset)
ctxt->valid &=
xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
#endif /* LIBXML_VALID_ENABLED */
}
/**
* xmlSAX2NotationDecl:
* @ctx: the user data (XML parser context)
* @name: The name of the notation
* @publicId: The public ID of the entity
* @systemId: The system ID of the entity
*
* What to do when a notation declaration has been parsed.
*/
void
xmlSAX2NotationDecl(void *ctx, const xmlChar *name,
const xmlChar *publicId, const xmlChar *systemId)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
xmlNotationPtr nota = NULL;
if (ctx == NULL) return;
#ifdef DEBUG_SAX
xmlGenericError(xmlGenericErrorContext,
"SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name, publicId, systemId);
#endif
if ((publicId == NULL) && (systemId == NULL)) {
xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
"SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n",
name, NULL);
return;
} else if (ctxt->inSubset == 1)
nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
publicId, systemId);
else if (ctxt->inSubset == 2)
nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name,
publicId, systemId);
else {
xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
"SAX.xmlSAX2NotationDecl(%s) called while not in subset\n",
name, NULL);
return;
}
#ifdef LIBXML_VALID_ENABLED
if (nota == NULL) ctxt->valid = 0;
if (ctxt->validate && ctxt->wellFormed &&
ctxt->myDoc && ctxt->myDoc->intSubset)
ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
nota);
#endif /* LIBXML_VALID_ENABLED */
}
/**
* xmlSAX2UnparsedEntityDecl:
* @ctx: the user data (XML parser context)
* @name: The name of the entity
* @publicId: The public ID of the entity
* @systemId: The system ID of the entity
* @notationName: the name of the notation
*
* What to do when an unparsed entity declaration is parsed
*/
void
xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
const xmlChar *publicId, const xmlChar *systemId,
const xmlChar *notationName)
{
xmlEntityPtr ent;
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
if (ctx == NULL) return;
#ifdef DEBUG_SAX
xmlGenericError(xmlGenericErrorContext,
"SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n",
name, publicId, systemId, notationName);
#endif
if (ctxt->inSubset == 1) {
ent = xmlAddDocEntity(ctxt->myDoc, name,
XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
publicId, systemId, notationName);
if ((ent == NULL) && (ctxt->pedantic) &&
(ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
ctxt->sax->warning(ctxt->userData,
"Entity(%s) already defined in the internal subset\n", name);
if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
xmlChar *URI;
const char *base = NULL;
if (ctxt->input != NULL)
base = ctxt->input->filename;
if (base == NULL)
base = ctxt->directory;
URI = xmlBuildURI(systemId, (const xmlChar *) base);
ent->URI = URI;
}
} else if (ctxt->inSubset == 2) {
ent = xmlAddDtdEntity(ctxt->myDoc, name,
XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
publicId, systemId, notationName);
if ((ent == NULL) && (ctxt->pedantic) &&
(ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
ctxt->sax->warning(ctxt->userData,
"Entity(%s) already defined in the external subset\n", name);
if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
xmlChar *URI;
const char *base = NULL;
if (ctxt->input != NULL)
base = ctxt->input->filename;
if (base == NULL)
base = ctxt->directory;
URI = xmlBuildURI(systemId, (const xmlChar *) base);
ent->URI = URI;
}
} else {
xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
"SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n",
name, NULL);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -