Added the part about section 7.2 on URI resolution, fixed a side effect in
* include/libxml/catalog.h catalog.c xmlIO.c HTMLparser.c:
Added the part about section 7.2 on URI resolution,
fixed a side effect in the HTML parser, look complete
and ready to rock except the URI/SystemID part!
Daniel
diff --git a/catalog.c b/catalog.c
index 06b2b53..fba077b 100644
--- a/catalog.c
+++ b/catalog.c
@@ -319,7 +319,6 @@
static xmlCatalogEntryPtr
xmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename);
-
static xmlCatalogEntryPtr
xmlParseXMLCatalog(const xmlChar *value, xmlCatalogPrefer prefer,
const char *file);
@@ -329,6 +328,9 @@
static xmlChar *
xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
const xmlChar *sysID);
+static xmlChar *
+xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI);
+
static xmlCatalogEntryType
xmlGetXMLCatalogEntryType(const xmlChar *name) {
@@ -1105,6 +1107,127 @@
}
/**
+ * 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->value));
+ }
+ 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++;
+ 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->value);
+ if (ret != NULL)
+ ret = xmlStrcat(ret, &URI[lenrewrite]);
+ return(ret);
+ }
+ if (haveDelegate) {
+ /*
+ * 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(URI, cur->name, xmlStrlen(cur->name)))) {
+ if (cur->children == NULL) {
+ xmlFetchXMLCatalogFile(cur);
+ }
+ if (cur->children != NULL) {
+ if (xmlDebugCatalogs)
+ xmlGenericError(xmlGenericErrorContext,
+ "Trying URI delegate %s\n", cur->value);
+ ret = xmlCatalogListXMLResolveURI(cur->children, URI);
+ if (ret != NULL)
+ return(ret);
+ }
+ }
+ cur = cur->next;
+ }
+ /*
+ * Apply the cut algorithm explained in 4/
+ */
+ 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 = xmlCatalogListXMLResolveURI(cur->children, URI);
+ if (ret != NULL)
+ return(ret);
+ }
+ }
+ cur = cur->next;
+ }
+ }
+
+ return(NULL);
+}
+
+/**
* xmlCatalogListXMLResolve:
* @catal: a catalog list
* @pubId: the public ID string
@@ -1181,6 +1304,59 @@
return(ret);
}
+/**
+ * xmlCatalogListXMLResolveURI:
+ * @catal: a catalog list
+ * @URI: the URI
+ *
+ * Do a complete resolution lookup of an URI for a list of catalogs
+ *
+ * Implements (or tries to) 7.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 *
+xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
+ xmlChar *ret = NULL;
+ xmlChar *urnID = NULL;
+
+ if (catal == NULL)
+ return(NULL);
+ if (URI == NULL)
+ return(NULL);
+
+ if (!xmlStrncmp(URI, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
+ urnID = xmlCatalogUnWrapURN(URI);
+ if (xmlDebugCatalogs) {
+ if (urnID == NULL)
+ xmlGenericError(xmlGenericErrorContext,
+ "URN ID %s expanded to NULL\n", URI);
+ else
+ xmlGenericError(xmlGenericErrorContext,
+ "URN ID expanded to %s\n", urnID);
+ }
+ ret = xmlCatalogListXMLResolve(catal, urnID, NULL);
+ if (urnID != NULL)
+ xmlFree(urnID);
+ return(ret);
+ }
+ while (catal != NULL) {
+ if (catal->type == XML_CATA_CATALOG) {
+ if (catal->children == NULL) {
+ xmlFetchXMLCatalogFile(catal);
+ }
+ if (catal->children != NULL) {
+ ret = xmlCatalogXMLResolveURI(catal->children, URI);
+ if (ret != NULL)
+ return(ret);
+ }
+ }
+ catal = catal->next;
+ }
+ return(ret);
+}
+
/************************************************************************
* *
* The SGML Catalog parser *
@@ -1947,6 +2123,32 @@
}
/**
+ * xmlCatalogResolveURI:
+ * @pubId: the URI
+ *
+ * Do a complete resolution lookup of an URI
+ *
+ * Returns the URI of the resource or NULL if not found, it must be freed
+ * by the caller.
+ */
+xmlChar *
+xmlCatalogResolveURI(const xmlChar *URI) {
+ if (!xmlCatalogInitialized)
+ xmlInitializeCatalog();
+
+ if (xmlDefaultXMLCatalogList != NULL) {
+ return(xmlCatalogListXMLResolveURI(xmlDefaultXMLCatalogList, URI));
+ } else {
+ const xmlChar *ret;
+
+ ret = xmlCatalogSGMLResolve(NULL, URI);
+ if (ret != NULL)
+ return(xmlStrdup(ret));
+ }
+ return(NULL);
+}
+
+/**
* xmlCatalogDump:
* @out: the file.
*
@@ -2202,4 +2404,27 @@
return(xmlCatalogListXMLResolve(catal, pubID, sysID));
}
+/**
+ * xmlCatalogLocalResolveURI:
+ * @catalogs: a document's list of catalogs
+ * @pubId: the URI
+ *
+ * Do a complete resolution lookup of an URI using a
+ * document's private catalog list
+ *
+ * Returns the URI of the resource or NULL if not found, it must be freed
+ * by the caller.
+ */
+xmlChar *
+xmlCatalogLocalResolveURI(void *catalogs, const xmlChar *URI) {
+ xmlCatalogEntryPtr catal;
+
+ if (!xmlCatalogInitialized)
+ xmlInitializeCatalog();
+ catal = (xmlCatalogEntryPtr) catalogs;
+ if (catal == NULL)
+ return(NULL);
+ return(xmlCatalogListXMLResolveURI(catal, URI));
+}
+
#endif /* LIBXML_CATALOG_ENABLED */