⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 catalog.c.svn-base

📁 这是一个用于解析xml文件的类库。使用这个类库
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
 * a Catalog entry from it. * * Returns the new Catalog entry node or NULL in case of error. */static xmlCatalogEntryPtrxmlParseXMLCatalogOneNode(xmlNodePtr cur, xmlCatalogEntryType type,			  const xmlChar *name, const xmlChar *attrName,			  const xmlChar *uriAttrName, xmlCatalogPrefer prefer) {    int ok = 1;    xmlChar *uriValue;    xmlChar *nameValue = NULL;    xmlChar *base = NULL;    xmlChar *URL = NULL;    xmlCatalogEntryPtr ret = NULL;    if (attrName != NULL) {	nameValue = xmlGetProp(cur, attrName);	if (nameValue == NULL) {	    xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR,			  "%s entry lacks '%s'\n", name, attrName, NULL);	    ok = 0;	}    }    uriValue = xmlGetProp(cur, uriAttrName);    if (uriValue == NULL) {	xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR,		"%s entry lacks '%s'\n", name, uriAttrName, NULL);	ok = 0;    }    if (!ok) {	if (nameValue != NULL)	    xmlFree(nameValue);	if (uriValue != NULL)	    xmlFree(uriValue);	return(NULL);    }    base = xmlNodeGetBase(cur->doc, cur);    URL = xmlBuildURI(uriValue, base);    if (URL != NULL) {	if (xmlDebugCatalogs > 1) {	    if (nameValue != NULL)		xmlGenericError(xmlGenericErrorContext,			"Found %s: '%s' '%s'\n", name, nameValue, URL);	    else		xmlGenericError(xmlGenericErrorContext,			"Found %s: '%s'\n", name, URL);	}	ret = xmlNewCatalogEntry(type, nameValue, uriValue, URL, prefer);    } else {	xmlCatalogErr(ret, cur, XML_CATALOG_ENTRY_BROKEN,		"%s entry '%s' broken ?: %s\n", name, uriAttrName, uriValue);    }    if (nameValue != NULL)	xmlFree(nameValue);    if (uriValue != NULL)	xmlFree(uriValue);    if (base != NULL)	xmlFree(base);    if (URL != NULL)	xmlFree(URL);    return(ret);}/** * xmlParseXMLCatalogNode: * @cur:  the XML node * @prefer:  the PUBLIC vs. SYSTEM current preference value * @parent:  the parent Catalog entry * * Examines an XML tree node of a catalog and build * a Catalog entry from it adding it to its parent. The examination can * be recursive. */static voidxmlParseXMLCatalogNode(xmlNodePtr cur, xmlCatalogPrefer prefer,	               xmlCatalogEntryPtr parent){    xmlChar *uri = NULL;    xmlChar *URL = NULL;    xmlChar *base = NULL;    xmlCatalogEntryPtr entry = NULL;    if (cur == NULL)        return;    if (xmlStrEqual(cur->name, BAD_CAST "group")) {        xmlChar *prop;        prop = xmlGetProp(cur, BAD_CAST "prefer");        if (prop != NULL) {            if (xmlStrEqual(prop, BAD_CAST "system")) {                prefer = XML_CATA_PREFER_SYSTEM;            } else if (xmlStrEqual(prop, BAD_CAST "public")) {                prefer = XML_CATA_PREFER_PUBLIC;            } else {		xmlCatalogErr(parent, cur, XML_CATALOG_PREFER_VALUE,                              "Invalid value for prefer: '%s'\n",			      prop, NULL, NULL);            }            xmlFree(prop);        }	/*	 * Recurse to propagate prefer to the subtree	 * (xml:base handling is automated)	 */        xmlParseXMLCatalogNodeList(cur->children, prefer, parent);    } else if (xmlStrEqual(cur->name, BAD_CAST "public")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_PUBLIC,		BAD_CAST "public", BAD_CAST "publicId", BAD_CAST "uri", prefer);    } else if (xmlStrEqual(cur->name, BAD_CAST "system")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_SYSTEM,		BAD_CAST "system", BAD_CAST "systemId", BAD_CAST "uri", prefer);    } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteSystem")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_SYSTEM,		BAD_CAST "rewriteSystem", BAD_CAST "systemIdStartString",		BAD_CAST "rewritePrefix", prefer);    } else if (xmlStrEqual(cur->name, BAD_CAST "delegatePublic")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_PUBLIC,		BAD_CAST "delegatePublic", BAD_CAST "publicIdStartString",		BAD_CAST "catalog", prefer);    } else if (xmlStrEqual(cur->name, BAD_CAST "delegateSystem")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_SYSTEM,		BAD_CAST "delegateSystem", BAD_CAST "systemIdStartString",		BAD_CAST "catalog", prefer);    } else if (xmlStrEqual(cur->name, BAD_CAST "uri")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_URI,		BAD_CAST "uri", BAD_CAST "name",		BAD_CAST "uri", prefer);    } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteURI")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_URI,		BAD_CAST "rewriteURI", BAD_CAST "uriStartString",		BAD_CAST "rewritePrefix", prefer);    } else if (xmlStrEqual(cur->name, BAD_CAST "delegateURI")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_URI,		BAD_CAST "delegateURI", BAD_CAST "uriStartString",		BAD_CAST "catalog", prefer);    } else if (xmlStrEqual(cur->name, BAD_CAST "nextCatalog")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_NEXT_CATALOG,		BAD_CAST "nextCatalog", NULL,		BAD_CAST "catalog", prefer);    }    if ((entry != NULL) && (parent != NULL)) {	entry->parent = parent;	if (parent->children == NULL)	    parent->children = entry;	else {	    xmlCatalogEntryPtr prev;	    prev = parent->children;	    while (prev->next != NULL)		prev = prev->next;	    prev->next = entry;	}    }    if (base != NULL)	xmlFree(base);    if (uri != NULL)	xmlFree(uri);    if (URL != NULL)	xmlFree(URL);}/** * xmlParseXMLCatalogNodeList: * @cur:  the XML node list of siblings * @prefer:  the PUBLIC vs. SYSTEM current preference value * @parent:  the parent Catalog entry * * Examines a list of XML sibling nodes of a catalog and build * a list of Catalog entry from it adding it to the parent. * The examination will recurse to examine node subtrees. */static voidxmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer,	                   xmlCatalogEntryPtr parent) {    while (cur != NULL) {	if ((cur->ns != NULL) && (cur->ns->href != NULL) &&	    (xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {	    xmlParseXMLCatalogNode(cur, prefer, parent);	}	cur = cur->next;    }    /* TODO: sort the list according to REWRITE lengths and prefer value */}/** * xmlParseXMLCatalogFile: * @prefer:  the PUBLIC vs. SYSTEM current preference value * @filename:  the filename for the catalog * * Parses the catalog file to extract the XML tree and then analyze the * tree to build a list of Catalog entries corresponding to this catalog *  * Returns the resulting Catalog entries list */static xmlCatalogEntryPtrxmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename) {    xmlDocPtr doc;    xmlNodePtr cur;    xmlChar *prop;    xmlCatalogEntryPtr parent = NULL;    if (filename == NULL)        return(NULL);    doc = xmlParseCatalogFile((const char *) filename);    if (doc == NULL) {	if (xmlDebugCatalogs)	    xmlGenericError(xmlGenericErrorContext,		    "Failed to parse catalog %s\n", filename);	return(NULL);    }    if (xmlDebugCatalogs)	xmlGenericError(xmlGenericErrorContext,		"%d Parsing catalog %s\n", xmlGetThreadId(), filename);    cur = xmlDocGetRootElement(doc);    if ((cur != NULL) && (xmlStrEqual(cur->name, BAD_CAST "catalog")) &&	(cur->ns != NULL) && (cur->ns->href != NULL) &&	(xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {	parent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,				    (const xmlChar *)filename, NULL, prefer);        if (parent == NULL) {	    xmlFreeDoc(doc);	    return(NULL);	}	prop = xmlGetProp(cur, BAD_CAST "prefer");	if (prop != NULL) {	    if (xmlStrEqual(prop, BAD_CAST "system")) {		prefer = XML_CATA_PREFER_SYSTEM;	    } else if (xmlStrEqual(prop, BAD_CAST "public")) {		prefer = XML_CATA_PREFER_PUBLIC;	    } else {		xmlCatalogErr(NULL, cur, XML_CATALOG_PREFER_VALUE,			      "Invalid value for prefer: '%s'\n",			      prop, NULL, NULL);	    }	    xmlFree(prop);	}	cur = cur->children;	xmlParseXMLCatalogNodeList(cur, prefer, parent);    } else {	xmlCatalogErr(NULL, (xmlNodePtr) doc, XML_CATALOG_NOT_CATALOG,		      "File %s is not an XML Catalog\n",		      filename, NULL, NULL);	xmlFreeDoc(doc);	return(NULL);    }    xmlFreeDoc(doc);    return(parent);}/** * xmlFetchXMLCatalogFile: * @catal:  an existing but incomplete catalog entry * * Fetch and parse the subcatalog referenced by an entry *  * Returns 0 in case of success, -1 otherwise */static intxmlFetchXMLCatalogFile(xmlCatalogEntryPtr catal) {    xmlCatalogEntryPtr doc;    if (catal == NULL) 	return(-1);    if (catal->URL == NULL)	return(-1);    if (catal->children != NULL)	return(-1);    /*     * lock the whole catalog for modification     */    xmlRMutexLock(xmlCatalogMutex);    if (catal->children != NULL) {	/* Okay someone else did it in the meantime */	xmlRMutexUnlock(xmlCatalogMutex);	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 intxmlAddXMLCatalog(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);    else	cur->next = xmlNewCatalogEntry(typ, orig, replace,		                       NULL, catal->prefer);    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 intxmlDelXMLCatalog(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++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -