📄 catalog.c.svn-base
字号:
/* * 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); /* * add all the catalog entries */ cur = catal; while (cur != NULL) { 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_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; } /* * 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 voidxmlCatalogConvertEntry(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 */intxmlConvertSGMLCatalog(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 */xmlDocPtrxmlParseCatalogFile(const char *filename) { xmlDocPtr ret; xmlParserCtxtPtr ctxt; char *directory = NULL; xmlParserInputPtr inputStream; xmlParserInputBufferPtr buf; ctxt = xmlNewParserCtxt(); if (ctxt == NULL) { if (xmlDefaultSAXHandler.error != NULL) { xmlDefaultSAXHandler.error(NULL, "out of memory\n"); } 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; 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 int fd;#else FILE *fd;#endif int len; long size;#ifdef HAVE_STAT struct stat info;#endif xmlChar *content; if (filename == NULL) return (NULL);#ifdef HAVE_STAT if (stat(filename, &info) < 0) return (NULL);#endif#ifdef HAVE_STAT if ((fd = open(filename, O_RDONLY)) < 0)#else if ((fd = fopen(filename, "rb")) == NULL)#endif { return (NULL); }#ifdef HAVE_STAT size = info.st_size;#else if (fseek(fd, 0, SEEK_END) || (size = ftell(fd)) == EOF || fseek(fd, 0, SEEK_SET)) { /* File operations denied? ok, just close and return failure */ fclose(fd); return (NULL); }#endif content = xmlMallocAtomic(size + 10); if (content == NULL) { xmlCatalogErrMemory("allocating catalog data"); return (NULL); }#ifdef HAVE_STAT len = read(fd, content, size);#else len = fread(content, 1, size, fd);#endif if (len < 0) { xmlFree(content); return (NULL); }#ifdef HAVE_STAT close(fd);#else fclose(fd);#endif content[len] = 0; return(content);}/************************************************************************ * * * The XML Catalog parser * * * ************************************************************************/static xmlCatalogEntryPtrxmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename);static voidxmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer, xmlCatalogEntryPtr parent);static xmlChar *xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID, const xmlChar *sysID);static xmlChar *xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI);/** * xmlGetXMLCatalogEntryType: * @name: the name * * lookup the internal type associated to an XML catalog entry name * * Returns the type associated with that name */static xmlCatalogEntryTypexmlGetXMLCatalogEntryType(const xmlChar *name) { xmlCatalogEntryType type = XML_CATA_NONE; if (xmlStrEqual(name, (const xmlChar *) "system")) type = XML_CATA_SYSTEM; else if (xmlStrEqual(name, (const xmlChar *) "public")) type = XML_CATA_PUBLIC; else if (xmlStrEqual(name, (const xmlChar *) "rewriteSystem")) type = XML_CATA_REWRITE_SYSTEM; else if (xmlStrEqual(name, (const xmlChar *) "delegatePublic")) type = XML_CATA_DELEGATE_PUBLIC; else if (xmlStrEqual(name, (const xmlChar *) "delegateSystem")) type = XML_CATA_DELEGATE_SYSTEM; else if (xmlStrEqual(name, (const xmlChar *) "uri")) type = XML_CATA_URI; else if (xmlStrEqual(name, (const xmlChar *) "rewriteURI")) type = XML_CATA_REWRITE_URI; else if (xmlStrEqual(name, (const xmlChar *) "delegateURI")) type = XML_CATA_DELEGATE_URI; else if (xmlStrEqual(name, (const xmlChar *) "nextCatalog")) type = XML_CATA_NEXT_CATALOG; else if (xmlStrEqual(name, (const xmlChar *) "catalog")) type = XML_CATA_CATALOG; return(type);}/** * xmlParseXMLCatalogOneNode: * @cur: the XML node * @type: the type of Catalog entry * @name: the name of the node * @attrName: the attribute holding the value * @uriAttrName: the attribute holding the URI-Reference * @prefer: the PUBLIC vs. SYSTEM current preference value * * Finishes the examination of an XML tree node of a catalog and build
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -