📄 catalog.c
字号:
return(0);
}
if (xmlCatalogXMLFiles != NULL) {
doc = (xmlCatalogEntryPtr)
xmlHashLookup(xmlCatalogXMLFiles, catal->URL);
if (doc != NULL) {
if (xmlDebugCatalogs)
xmlGenericError(xmlGenericErrorContext,
"Found %s in file hash\n", catal->URL);
if (catal->type == XML_CATA_CATALOG)
catal->children = doc->children;
else
catal->children = doc;
catal->dealloc = 0;
xmlRMutexUnlock(xmlCatalogMutex);
return(0);
}
if (xmlDebugCatalogs)
xmlGenericError(xmlGenericErrorContext,
"%s not found in file hash\n", catal->URL);
}
/*
* Fetch and parse. Note that xmlParseXMLCatalogFile does not
* use the existing catalog, there is no recursion allowed at
* that level.
*/
doc = xmlParseXMLCatalogFile(catal->prefer, catal->URL);
if (doc == NULL) {
catal->type = XML_CATA_BROKEN_CATALOG;
xmlRMutexUnlock(xmlCatalogMutex);
return(-1);
}
if (catal->type == XML_CATA_CATALOG)
catal->children = doc->children;
else
catal->children = doc;
doc->dealloc = 1;
if (xmlCatalogXMLFiles == NULL)
xmlCatalogXMLFiles = xmlHashCreate(10);
if (xmlCatalogXMLFiles != NULL) {
if (xmlDebugCatalogs)
xmlGenericError(xmlGenericErrorContext,
"%s added to file hash\n", catal->URL);
xmlHashAddEntry(xmlCatalogXMLFiles, catal->URL, doc);
}
xmlRMutexUnlock(xmlCatalogMutex);
return(0);
}
/************************************************************************
* *
* XML Catalog handling *
* *
************************************************************************/
/**
* xmlAddXMLCatalog:
* @catal: top of an XML catalog
* @type: the type of record to add to the catalog
* @orig: the system, public or prefix to match (or NULL)
* @replace: the replacement value for the match
*
* Add an entry in the XML catalog, it may overwrite existing but
* different entries.
*
* Returns 0 if successful, -1 otherwise
*/
static int
xmlAddXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *type,
const xmlChar *orig, const xmlChar *replace) {
xmlCatalogEntryPtr cur;
xmlCatalogEntryType typ;
int doregister = 0;
if ((catal == NULL) ||
((catal->type != XML_CATA_CATALOG) &&
(catal->type != XML_CATA_BROKEN_CATALOG)))
return(-1);
if (catal->children == NULL) {
xmlFetchXMLCatalogFile(catal);
}
if (catal->children == NULL)
doregister = 1;
typ = xmlGetXMLCatalogEntryType(type);
if (typ == XML_CATA_NONE) {
if (xmlDebugCatalogs)
xmlGenericError(xmlGenericErrorContext,
"Failed to add unknown element %s to catalog\n", type);
return(-1);
}
cur = catal->children;
/*
* Might be a simple "update in place"
*/
if (cur != NULL) {
while (cur != NULL) {
if ((orig != NULL) && (cur->type == typ) &&
(xmlStrEqual(orig, cur->name))) {
if (xmlDebugCatalogs)
xmlGenericError(xmlGenericErrorContext,
"Updating element %s to catalog\n", type);
if (cur->value != NULL)
xmlFree(cur->value);
if (cur->URL != NULL)
xmlFree(cur->URL);
cur->value = xmlStrdup(replace);
cur->URL = xmlStrdup(replace);
return(0);
}
if (cur->next == NULL)
break;
cur = cur->next;
}
}
if (xmlDebugCatalogs)
xmlGenericError(xmlGenericErrorContext,
"Adding element %s to catalog\n", type);
if (cur == NULL)
catal->children = xmlNewCatalogEntry(typ, orig, replace,
NULL, catal->prefer, NULL);
else
cur->next = xmlNewCatalogEntry(typ, orig, replace,
NULL, catal->prefer, NULL);
if (doregister) {
cur = xmlHashLookup(xmlCatalogXMLFiles, catal->URL);
if (cur != NULL)
cur->children = catal->children;
}
return(0);
}
/**
* xmlDelXMLCatalog:
* @catal: top of an XML catalog
* @value: the value to remove from the catalog
*
* Remove entries in the XML catalog where the value or the URI
* is equal to @value
*
* Returns the number of entries removed if successful, -1 otherwise
*/
static int
xmlDelXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *value) {
xmlCatalogEntryPtr cur;
int ret = 0;
if ((catal == NULL) ||
((catal->type != XML_CATA_CATALOG) &&
(catal->type != XML_CATA_BROKEN_CATALOG)))
return(-1);
if (value == NULL)
return(-1);
if (catal->children == NULL) {
xmlFetchXMLCatalogFile(catal);
}
/*
* Scan the children
*/
cur = catal->children;
while (cur != NULL) {
if (((cur->name != NULL) && (xmlStrEqual(value, cur->name))) ||
(xmlStrEqual(value, cur->value))) {
if (xmlDebugCatalogs) {
if (cur->name != NULL)
xmlGenericError(xmlGenericErrorContext,
"Removing element %s from catalog\n", cur->name);
else
xmlGenericError(xmlGenericErrorContext,
"Removing element %s from catalog\n", cur->value);
}
cur->type = XML_CATA_REMOVED;
}
cur = cur->next;
}
return(ret);
}
/**
* xmlCatalogXMLResolve:
* @catal: a catalog list
* @pubID: the public ID string
* @sysID: the system ID string
*
* Do a complete resolution lookup of an External Identifier for a
* list of catalog entries.
*
* Implements (or tries to) 7.1. External Identifier Resolution
* from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
*
* Returns the URI of the resource or NULL if not found
*/
static xmlChar *
xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
const xmlChar *sysID) {
xmlChar *ret = NULL;
xmlCatalogEntryPtr cur;
int haveDelegate = 0;
int haveNext = 0;
/*
* protection against loops
*/
if (catal->depth > MAX_CATAL_DEPTH) {
xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION,
"Detected recursion in catalog %s\n",
catal->name, NULL, NULL);
return(NULL);
}
catal->depth++;
/*
* First tries steps 2/ 3/ 4/ if a system ID is provided.
*/
if (sysID != NULL) {
xmlCatalogEntryPtr rewrite = NULL;
int lenrewrite = 0, len;
cur = catal;
haveDelegate = 0;
while (cur != NULL) {
switch (cur->type) {
case XML_CATA_SYSTEM:
if (xmlStrEqual(sysID, cur->name)) {
if (xmlDebugCatalogs)
xmlGenericError(xmlGenericErrorContext,
"Found system match %s\n", cur->name);
catal->depth--;
return(xmlStrdup(cur->URL));
}
break;
case XML_CATA_REWRITE_SYSTEM:
len = xmlStrlen(cur->name);
if ((len > lenrewrite) &&
(!xmlStrncmp(sysID, cur->name, len))) {
lenrewrite = len;
rewrite = cur;
}
break;
case XML_CATA_DELEGATE_SYSTEM:
if (!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))
haveDelegate++;
break;
case XML_CATA_NEXT_CATALOG:
haveNext++;
break;
default:
break;
}
cur = cur->next;
}
if (rewrite != NULL) {
if (xmlDebugCatalogs)
xmlGenericError(xmlGenericErrorContext,
"Using rewriting rule %s\n", rewrite->name);
ret = xmlStrdup(rewrite->URL);
if (ret != NULL)
ret = xmlStrcat(ret, &sysID[lenrewrite]);
catal->depth--;
return(ret);
}
if (haveDelegate) {
const xmlChar *delegates[MAX_DELEGATE];
int nbList = 0, i;
/*
* Assume the entries have been sorted by decreasing substring
* matches when the list was produced.
*/
cur = catal;
while (cur != NULL) {
if ((cur->type == XML_CATA_DELEGATE_SYSTEM) &&
(!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))) {
for (i = 0;i < nbList;i++)
if (xmlStrEqual(cur->URL, delegates[i]))
break;
if (i < nbList) {
cur = cur->next;
continue;
}
if (nbList < MAX_DELEGATE)
delegates[nbList++] = cur->URL;
if (cur->children == NULL) {
xmlFetchXMLCatalogFile(cur);
}
if (cur->children != NULL) {
if (xmlDebugCatalogs)
xmlGenericError(xmlGenericErrorContext,
"Trying system delegate %s\n", cur->URL);
ret = xmlCatalogListXMLResolve(
cur->children, NULL, sysID);
if (ret != NULL) {
catal->depth--;
return(ret);
}
}
}
cur = cur->next;
}
/*
* Apply the cut algorithm explained in 4/
*/
catal->depth--;
return(XML_CATAL_BREAK);
}
}
/*
* Then tries 5/ 6/ if a public ID is provided
*/
if (pubID != NULL) {
cur = catal;
haveDelegate = 0;
while (cur != NULL) {
switch (cur->type) {
case XML_CATA_PUBLIC:
if (xmlStrEqual(pubID, cur->name)) {
if (xmlDebugCatalogs)
xmlGenericError(xmlGenericErrorContext,
"Found public match %s\n", cur->name);
catal->depth--;
return(xmlStrdup(cur->URL));
}
break;
case XML_CATA_DELEGATE_PUBLIC:
if (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)) &&
(cur->prefer == XML_CATA_PREFER_PUBLIC))
haveDelegate++;
break;
case XML_CATA_NEXT_CATALOG:
if (sysID == NULL)
haveNext++;
break;
default:
break;
}
cur = cur->next;
}
if (haveDelegate) {
const xmlChar *delegates[MAX_DELEGATE];
int nbList = 0, i;
/*
* Assume the entries have been sorted by decreasing substring
* matches when the list was produced.
*/
cur = catal;
while (cur != NULL) {
if ((cur->type == XML_CATA_DELEGATE_PUBLIC) &&
(cur->prefer == XML_CATA_PREFER_PUBLIC) &&
(!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)))) {
for (i = 0;i < nbList;i++)
if (xmlStrEqual(cur->URL, delegates[i]))
break;
if (i < nbList) {
cur = cur->next;
continue;
}
if (nbList < MAX_DELEGATE)
delegates[nbList++] = cur->URL;
if (cur->children == NULL) {
xmlFetchXMLCatalogFile(cur);
}
if (cur->children != NULL) {
if (xmlDebugCatalogs)
xmlGenericError(xmlGenericErrorContext,
"Trying public delegate %s\n", cur->URL);
ret = xmlCatalogListXMLResolve(
cur->children, pubID, NULL);
if (ret != NULL) {
catal->depth--;
return(ret);
}
}
}
cur = cur->next;
}
/*
* Apply the cut algorithm explained in 4/
*/
catal->depth--;
return(XML_CATAL_BREAK);
}
}
if (haveNext) {
cur = catal;
while (cur != NULL) {
if (cur->type == XML_CATA_NEXT_CATALOG) {
if (cur->children == NULL) {
xmlFetchXMLCatalogFile(cur);
}
if (cur->children != NULL) {
ret = xmlCatalogListXMLResolve(cur->children, pubID, sysID);
if (ret != NULL) {
catal->depth--;
return(ret);
}
}
}
cur = cur->next;
}
}
catal->depth--;
return(NULL);
}
/**
* xmlCatalogXMLResolveURI:
* @catal: a catalog list
* @URI: the URI
* @sysID: the system ID string
*
* Do a complete resolution lookup of an External Identifier for a
* list of catalog entries.
*
* Implements (or tries to) 7.2.2. URI Resolution
* from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
*
* Returns the URI of the resource or NULL if not found
*/
static xmlChar *
xmlCatalogXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
xmlChar *ret = NULL;
xmlCatalogEntryPtr cur;
int haveDelegate = 0;
int haveNext = 0;
xmlCatalogEntryPtr rewrite = NULL;
int lenrewrite = 0, len;
if (catal == NULL)
return(NULL);
if (URI == NULL)
return(NULL);
/*
* First tries steps 2/ 3/ 4/ if a system ID is provided.
*/
cur = catal;
haveDelegate = 0;
while (cur != NULL) {
switch (cur->type) {
case XML_CATA_URI:
if (xmlStrEqual(URI, cur->name)) {
if (xmlDebugCatalogs)
xmlGenericError(xmlGenericErrorContext,
"Found URI match %s\n", cur->name);
return(xmlStrdup(cur->URL));
}
break;
case XML_CATA_REWRITE_URI:
len = xmlStrlen(cur->name);
if ((len > lenrewrite) &&
(!xmlStrncmp(URI, cur->name, len))) {
lenrewrite = len;
rewrite = cur;
}
break;
case XML_CATA_DELEGATE_URI:
if (!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name)))
haveDelegate++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -