📄 catalog.c
字号:
case SGML_CATA_SGMLDECL:
fprintf(out, "SGMLDECL "); break;
default:
return;
}
switch (entry->type) {
case SGML_CATA_ENTITY:
case SGML_CATA_PENTITY:
case SGML_CATA_DOCTYPE:
case SGML_CATA_LINKTYPE:
case SGML_CATA_NOTATION:
fprintf(out, "%s", (const char *) entry->name); break;
case SGML_CATA_PUBLIC:
case SGML_CATA_SYSTEM:
case SGML_CATA_SGMLDECL:
case SGML_CATA_DOCUMENT:
case SGML_CATA_CATALOG:
case SGML_CATA_BASE:
case SGML_CATA_DELEGATE:
fprintf(out, "\"%s\"", entry->name); break;
default:
break;
}
switch (entry->type) {
case SGML_CATA_ENTITY:
case SGML_CATA_PENTITY:
case SGML_CATA_DOCTYPE:
case SGML_CATA_LINKTYPE:
case SGML_CATA_NOTATION:
case SGML_CATA_PUBLIC:
case SGML_CATA_SYSTEM:
case SGML_CATA_DELEGATE:
fprintf(out, " \"%s\"", entry->value); break;
default:
break;
}
fprintf(out, "\n");
}
/**
* xmlDumpXMLCatalogNode:
* @catal: top catalog entry
* @catalog: pointer to the xml tree
* @doc: the containing document
* @ns: the current namespace
* @cgroup: group node for group members
*
* Serializes a Catalog entry, called by xmlDumpXMLCatalog and recursively
* for group entries
*/
static void xmlDumpXMLCatalogNode(xmlCatalogEntryPtr catal, xmlNodePtr catalog,
xmlDocPtr doc, xmlNsPtr ns, xmlCatalogEntryPtr cgroup) {
xmlNodePtr node;
xmlCatalogEntryPtr cur;
/*
* add all the catalog entries
*/
cur = catal;
while (cur != NULL) {
if (cur->group == cgroup) {
switch (cur->type) {
case XML_CATA_REMOVED:
break;
case XML_CATA_BROKEN_CATALOG:
case XML_CATA_CATALOG:
if (cur == catal) {
cur = cur->children;
continue;
}
break;
case XML_CATA_NEXT_CATALOG:
node = xmlNewDocNode(doc, ns, BAD_CAST "nextCatalog", NULL);
xmlSetProp(node, BAD_CAST "catalog", cur->value);
xmlAddChild(catalog, node);
break;
case XML_CATA_NONE:
break;
case XML_CATA_GROUP:
node = xmlNewDocNode(doc, ns, BAD_CAST "group", NULL);
xmlSetProp(node, BAD_CAST "id", cur->name);
if (cur->value != NULL) {
xmlNsPtr xns;
xns = xmlSearchNsByHref(doc, node, XML_XML_NAMESPACE);
if (xns != NULL)
xmlSetNsProp(node, xns, BAD_CAST "base",
cur->value);
}
switch (cur->prefer) {
case XML_CATA_PREFER_NONE:
break;
case XML_CATA_PREFER_PUBLIC:
xmlSetProp(node, BAD_CAST "prefer", BAD_CAST "public");
break;
case XML_CATA_PREFER_SYSTEM:
xmlSetProp(node, BAD_CAST "prefer", BAD_CAST "system");
break;
}
xmlDumpXMLCatalogNode(cur->next, node, doc, ns, cur);
xmlAddChild(catalog, node);
break;
case XML_CATA_PUBLIC:
node = xmlNewDocNode(doc, ns, BAD_CAST "public", NULL);
xmlSetProp(node, BAD_CAST "publicId", cur->name);
xmlSetProp(node, BAD_CAST "uri", cur->value);
xmlAddChild(catalog, node);
break;
case XML_CATA_SYSTEM:
node = xmlNewDocNode(doc, ns, BAD_CAST "system", NULL);
xmlSetProp(node, BAD_CAST "systemId", cur->name);
xmlSetProp(node, BAD_CAST "uri", cur->value);
xmlAddChild(catalog, node);
break;
case XML_CATA_REWRITE_SYSTEM:
node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteSystem", NULL);
xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name);
xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value);
xmlAddChild(catalog, node);
break;
case XML_CATA_DELEGATE_PUBLIC:
node = xmlNewDocNode(doc, ns, BAD_CAST "delegatePublic", NULL);
xmlSetProp(node, BAD_CAST "publicIdStartString", cur->name);
xmlSetProp(node, BAD_CAST "catalog", cur->value);
xmlAddChild(catalog, node);
break;
case XML_CATA_DELEGATE_SYSTEM:
node = xmlNewDocNode(doc, ns, BAD_CAST "delegateSystem", NULL);
xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name);
xmlSetProp(node, BAD_CAST "catalog", cur->value);
xmlAddChild(catalog, node);
break;
case XML_CATA_URI:
node = xmlNewDocNode(doc, ns, BAD_CAST "uri", NULL);
xmlSetProp(node, BAD_CAST "name", cur->name);
xmlSetProp(node, BAD_CAST "uri", cur->value);
xmlAddChild(catalog, node);
break;
case XML_CATA_REWRITE_URI:
node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteURI", NULL);
xmlSetProp(node, BAD_CAST "uriStartString", cur->name);
xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value);
xmlAddChild(catalog, node);
break;
case XML_CATA_DELEGATE_URI:
node = xmlNewDocNode(doc, ns, BAD_CAST "delegateURI", NULL);
xmlSetProp(node, BAD_CAST "uriStartString", cur->name);
xmlSetProp(node, BAD_CAST "catalog", cur->value);
xmlAddChild(catalog, node);
break;
case SGML_CATA_SYSTEM:
case SGML_CATA_PUBLIC:
case SGML_CATA_ENTITY:
case SGML_CATA_PENTITY:
case SGML_CATA_DOCTYPE:
case SGML_CATA_LINKTYPE:
case SGML_CATA_NOTATION:
case SGML_CATA_DELEGATE:
case SGML_CATA_BASE:
case SGML_CATA_CATALOG:
case SGML_CATA_DOCUMENT:
case SGML_CATA_SGMLDECL:
break;
}
}
cur = cur->next;
}
}
static int
xmlDumpXMLCatalog(FILE *out, xmlCatalogEntryPtr catal) {
int ret;
xmlDocPtr doc;
xmlNsPtr ns;
xmlDtdPtr dtd;
xmlNodePtr catalog;
xmlOutputBufferPtr buf;
/*
* Rebuild a catalog
*/
doc = xmlNewDoc(NULL);
if (doc == NULL)
return(-1);
dtd = xmlNewDtd(doc, BAD_CAST "catalog",
BAD_CAST "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN",
BAD_CAST "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd");
xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd);
ns = xmlNewNs(NULL, XML_CATALOGS_NAMESPACE, NULL);
if (ns == NULL) {
xmlFreeDoc(doc);
return(-1);
}
catalog = xmlNewDocNode(doc, ns, BAD_CAST "catalog", NULL);
if (catalog == NULL) {
xmlFreeNs(ns);
xmlFreeDoc(doc);
return(-1);
}
catalog->nsDef = ns;
xmlAddChild((xmlNodePtr) doc, catalog);
xmlDumpXMLCatalogNode(catal, catalog, doc, ns, NULL);
/*
* reserialize it
*/
buf = xmlOutputBufferCreateFile(out, NULL);
if (buf == NULL) {
xmlFreeDoc(doc);
return(-1);
}
ret = xmlSaveFormatFileTo(buf, doc, NULL, 1);
/*
* Free it
*/
xmlFreeDoc(doc);
return(ret);
}
#endif /* LIBXML_OUTPUT_ENABLED */
/************************************************************************
* *
* Converting SGML Catalogs to XML *
* *
************************************************************************/
/**
* xmlCatalogConvertEntry:
* @entry: the entry
* @catal: pointer to the catalog being converted
*
* Convert one entry from the catalog
*/
static void
xmlCatalogConvertEntry(xmlCatalogEntryPtr entry, xmlCatalogPtr catal) {
if ((entry == NULL) || (catal == NULL) || (catal->sgml == NULL) ||
(catal->xml == NULL))
return;
switch (entry->type) {
case SGML_CATA_ENTITY:
entry->type = XML_CATA_PUBLIC;
break;
case SGML_CATA_PENTITY:
entry->type = XML_CATA_PUBLIC;
break;
case SGML_CATA_DOCTYPE:
entry->type = XML_CATA_PUBLIC;
break;
case SGML_CATA_LINKTYPE:
entry->type = XML_CATA_PUBLIC;
break;
case SGML_CATA_NOTATION:
entry->type = XML_CATA_PUBLIC;
break;
case SGML_CATA_PUBLIC:
entry->type = XML_CATA_PUBLIC;
break;
case SGML_CATA_SYSTEM:
entry->type = XML_CATA_SYSTEM;
break;
case SGML_CATA_DELEGATE:
entry->type = XML_CATA_DELEGATE_PUBLIC;
break;
case SGML_CATA_CATALOG:
entry->type = XML_CATA_CATALOG;
break;
default:
xmlHashRemoveEntry(catal->sgml, entry->name,
(xmlHashDeallocator) xmlFreeCatalogEntry);
return;
}
/*
* Conversion successful, remove from the SGML catalog
* and add it to the default XML one
*/
xmlHashRemoveEntry(catal->sgml, entry->name, NULL);
entry->parent = catal->xml;
entry->next = NULL;
if (catal->xml->children == NULL)
catal->xml->children = entry;
else {
xmlCatalogEntryPtr prev;
prev = catal->xml->children;
while (prev->next != NULL)
prev = prev->next;
prev->next = entry;
}
}
/**
* xmlConvertSGMLCatalog:
* @catal: the catalog
*
* Convert all the SGML catalog entries as XML ones
*
* Returns the number of entries converted if successful, -1 otherwise
*/
int
xmlConvertSGMLCatalog(xmlCatalogPtr catal) {
if ((catal == NULL) || (catal->type != XML_SGML_CATALOG_TYPE))
return(-1);
if (xmlDebugCatalogs) {
xmlGenericError(xmlGenericErrorContext,
"Converting SGML catalog to XML\n");
}
xmlHashScan(catal->sgml,
(xmlHashScanner) xmlCatalogConvertEntry,
&catal);
return(0);
}
/************************************************************************
* *
* Helper function *
* *
************************************************************************/
/**
* xmlCatalogUnWrapURN:
* @urn: an "urn:publicid:" to unwrap
*
* Expand the URN into the equivalent Public Identifier
*
* Returns the new identifier or NULL, the string must be deallocated
* by the caller.
*/
static xmlChar *
xmlCatalogUnWrapURN(const xmlChar *urn) {
xmlChar result[2000];
unsigned int i = 0;
if (xmlStrncmp(urn, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1))
return(NULL);
urn += sizeof(XML_URN_PUBID) - 1;
while (*urn != 0) {
if (i > sizeof(result) - 4)
break;
if (*urn == '+') {
result[i++] = ' ';
urn++;
} else if (*urn == ':') {
result[i++] = '/';
result[i++] = '/';
urn++;
} else if (*urn == ';') {
result[i++] = ':';
result[i++] = ':';
urn++;
} else if (*urn == '%') {
if ((urn[1] == '2') && (urn[2] == 'B'))
result[i++] = '+';
else if ((urn[1] == '3') && (urn[2] == 'A'))
result[i++] = ':';
else if ((urn[1] == '2') && (urn[2] == 'F'))
result[i++] = '/';
else if ((urn[1] == '3') && (urn[2] == 'B'))
result[i++] = ';';
else if ((urn[1] == '2') && (urn[2] == '7'))
result[i++] = '\'';
else if ((urn[1] == '3') && (urn[2] == 'F'))
result[i++] = '?';
else if ((urn[1] == '2') && (urn[2] == '3'))
result[i++] = '#';
else if ((urn[1] == '2') && (urn[2] == '5'))
result[i++] = '%';
else {
result[i++] = *urn;
urn++;
continue;
}
urn += 3;
} else {
result[i++] = *urn;
urn++;
}
}
result[i] = 0;
return(xmlStrdup(result));
}
/**
* xmlParseCatalogFile:
* @filename: the filename
*
* parse an XML file and build a tree. It's like xmlParseFile()
* except it bypass all catalog lookups.
*
* Returns the resulting document tree or NULL in case of error
*/
xmlDocPtr
xmlParseCatalogFile(const char *filename) {
xmlDocPtr ret;
xmlParserCtxtPtr ctxt;
char *directory = NULL;
xmlParserInputPtr inputStream;
xmlParserInputBufferPtr buf;
ctxt = xmlNewParserCtxt();
if (ctxt == NULL) {
#ifdef LIBXML_SAX1_ENABLED
if (xmlDefaultSAXHandler.error != NULL) {
xmlDefaultSAXHandler.error(NULL, "out of memory\n");
}
#endif
return(NULL);
}
buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
if (buf == NULL) {
xmlFreeParserCtxt(ctxt);
return(NULL);
}
inputStream = xmlNewInputStream(ctxt);
if (inputStream == NULL) {
xmlFreeParserCtxt(ctxt);
return(NULL);
}
inputStream->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
inputStream->buf = buf;
inputStream->base = inputStream->buf->buffer->content;
inputStream->cur = inputStream->buf->buffer->content;
inputStream->end =
&inputStream->buf->buffer->content[inputStream->buf->buffer->use];
inputPush(ctxt, inputStream);
if ((ctxt->directory == NULL) && (directory == NULL))
directory = xmlParserGetDirectory(filename);
if ((ctxt->directory == NULL) && (directory != NULL))
ctxt->directory = directory;
ctxt->valid = 0;
ctxt->validate = 0;
ctxt->loadsubset = 0;
ctxt->pedantic = 0;
ctxt->dictNames = 1;
xmlParseDocument(ctxt);
if (ctxt->wellFormed)
ret = ctxt->myDoc;
else {
ret = NULL;
xmlFreeDoc(ctxt->myDoc);
ctxt->myDoc = NULL;
}
xmlFreeParserCtxt(ctxt);
return(ret);
}
/**
* xmlLoadFileContent:
* @filename: a file path
*
* Load a file content into memory.
*
* Returns a pointer to the 0 terminated string or NULL in case of error
*/
static xmlChar *
xmlLoadFileContent(const char *filename)
{
#ifdef HAVE_STAT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -