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

📄 xinclude.c.svn-base

📁 这是一个用于解析xml文件的类库。使用这个类库
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
/* * xinclude.c : Code to implement XInclude processing * * World Wide Web Consortium W3C Last Call Working Draft 10 November 2003 * http://www.w3.org/TR/2003/WD-xinclude-20031110 * * See Copyright for the status of this software. * * daniel@veillard.com */#define IN_LIBXML#include "libxml.h"#include <string.h>#include <libxml/xmlmemory.h>#include <libxml/tree.h>#include <libxml/parser.h>#include <libxml/uri.h>#include <libxml/xpointer.h>#include <libxml/parserInternals.h>#include <libxml/xmlerror.h>#include <libxml/encoding.h>#include <libxml/globals.h>#ifdef LIBXML_XINCLUDE_ENABLED#include <libxml/xinclude.h>#define XINCLUDE_MAX_DEPTH 40/* #define DEBUG_XINCLUDE */#ifdef DEBUG_XINCLUDE#ifdef LIBXML_DEBUG_ENABLED#include <libxml/debugXML.h>#endif#endif/************************************************************************ *									* *			XInclude context handling			* *									* ************************************************************************//* * An XInclude context */typedef xmlChar *xmlURL;typedef struct _xmlXIncludeRef xmlXIncludeRef;typedef xmlXIncludeRef *xmlXIncludeRefPtr;struct _xmlXIncludeRef {    xmlChar              *URI; /* the fully resolved resource URL */    xmlChar         *fragment; /* the fragment in the URI */    xmlDocPtr		  doc; /* the parsed document */    xmlNodePtr            ref; /* the node making the reference in the source */    xmlNodePtr            inc; /* the included copy */    int                   xml; /* xml or txt */    int                 count; /* how many refs use that specific doc */    xmlXPathObjectPtr    xptr; /* the xpointer if needed */    int		      emptyFb; /* flag to show fallback empty */};struct _xmlXIncludeCtxt {    xmlDocPtr             doc; /* the source document */    int               incBase; /* the first include for this document */    int                 incNr; /* number of includes */    int                incMax; /* size of includes tab */    xmlXIncludeRefPtr *incTab; /* array of included references */    int                 txtNr; /* number of unparsed documents */    int                txtMax; /* size of unparsed documents tab */    xmlNodePtr        *txtTab; /* array of unparsed text nodes */    xmlURL         *txturlTab; /* array of unparsed text URLs */    xmlChar *             url; /* the current URL processed */    int                 urlNr; /* number of URLs stacked */    int                urlMax; /* size of URL stack */    xmlChar *         *urlTab; /* URL stack */    int              nbErrors; /* the number of errors detected */    int                legacy; /* using XINCLUDE_OLD_NS */    int            parseFlags; /* the flags used for parsing XML documents */};static intxmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree);/************************************************************************ *									* * 			XInclude error handler				* *									* ************************************************************************//** * xmlXIncludeErrMemory: * @extra:  extra information * * Handle an out of memory condition */static voidxmlXIncludeErrMemory(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node,                     const char *extra){    if (ctxt != NULL)	ctxt->nbErrors++;    __xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,                    XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0,		    extra, NULL, NULL, 0, 0,		    "Memory allocation failed : %s\n", extra);}/** * xmlXIncludeErr: * @ctxt: the XInclude context * @node: the context node * @msg:  the error message * @extra:  extra information * * Handle an XInclude error */static voidxmlXIncludeErr(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,               const char *msg, const xmlChar *extra){    if (ctxt != NULL)	ctxt->nbErrors++;    __xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,                    error, XML_ERR_ERROR, NULL, 0,		    (const char *) extra, NULL, NULL, 0, 0,		    msg, (const char *) extra);}#if 0/** * xmlXIncludeWarn: * @ctxt: the XInclude context * @node: the context node * @msg:  the error message * @extra:  extra information * * Emit an XInclude warning. */static voidxmlXIncludeWarn(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,               const char *msg, const xmlChar *extra){    __xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,                    error, XML_ERR_WARNING, NULL, 0,		    (const char *) extra, NULL, NULL, 0, 0,		    msg, (const char *) extra);}#endif/** * xmlXIncludeGetProp: * @ctxt:  the XInclude context * @cur:  the node * @name:  the attribute name * * Get an XInclude attribute * * Returns the value (to be freed) or NULL if not found */static xmlChar *xmlXIncludeGetProp(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur,                   const xmlChar *name) {    xmlChar *ret;    ret = xmlGetNsProp(cur, XINCLUDE_NS, name);    if (ret != NULL)        return(ret);    if (ctxt->legacy != 0) {	ret = xmlGetNsProp(cur, XINCLUDE_OLD_NS, name);	if (ret != NULL)	    return(ret);    }    ret = xmlGetProp(cur, name);    return(ret);}/** * xmlXIncludeFreeRef: * @ref: the XInclude reference * * Free an XInclude reference */static voidxmlXIncludeFreeRef(xmlXIncludeRefPtr ref) {    if (ref == NULL)	return;#ifdef DEBUG_XINCLUDE    xmlGenericError(xmlGenericErrorContext, "Freeing ref\n");#endif    if (ref->doc != NULL) {#ifdef DEBUG_XINCLUDE	xmlGenericError(xmlGenericErrorContext, "Freeing doc %s\n", ref->URI);#endif	xmlFreeDoc(ref->doc);    }    if (ref->URI != NULL)	xmlFree(ref->URI);    if (ref->fragment != NULL)	xmlFree(ref->fragment);    if (ref->xptr != NULL)	xmlXPathFreeObject(ref->xptr);    xmlFree(ref);}/** * xmlXIncludeNewRef: * @ctxt: the XInclude context * @URI:  the resource URI * * Creates a new reference within an XInclude context * * Returns the new set */static xmlXIncludeRefPtrxmlXIncludeNewRef(xmlXIncludeCtxtPtr ctxt, const xmlChar *URI,	          xmlNodePtr ref) {    xmlXIncludeRefPtr ret;#ifdef DEBUG_XINCLUDE    xmlGenericError(xmlGenericErrorContext, "New ref %s\n", URI);#endif    ret = (xmlXIncludeRefPtr) xmlMalloc(sizeof(xmlXIncludeRef));    if (ret == NULL) {        xmlXIncludeErrMemory(ctxt, ref, "growing XInclude context");	return(NULL);    }    memset(ret, 0, sizeof(xmlXIncludeRef));    if (URI == NULL)	ret->URI = NULL;    else	ret->URI = xmlStrdup(URI);    ret->fragment = NULL;    ret->ref = ref;    ret->doc = 0;    ret->count = 0;    ret->xml = 0;    ret->inc = NULL;    if (ctxt->incMax == 0) {	ctxt->incMax = 4;        ctxt->incTab = (xmlXIncludeRefPtr *) xmlMalloc(ctxt->incMax *					      sizeof(ctxt->incTab[0]));        if (ctxt->incTab == NULL) {	    xmlXIncludeErrMemory(ctxt, ref, "growing XInclude context");	    xmlXIncludeFreeRef(ret);	    return(NULL);	}    }    if (ctxt->incNr >= ctxt->incMax) {	ctxt->incMax *= 2;        ctxt->incTab = (xmlXIncludeRefPtr *) xmlRealloc(ctxt->incTab,	             ctxt->incMax * sizeof(ctxt->incTab[0]));        if (ctxt->incTab == NULL) {	    xmlXIncludeErrMemory(ctxt, ref, "growing XInclude context");	    xmlXIncludeFreeRef(ret);	    return(NULL);	}    }    ctxt->incTab[ctxt->incNr++] = ret;    return(ret);}/** * xmlXIncludeNewContext: * @doc:  an XML Document * * Creates a new XInclude context * * Returns the new set */xmlXIncludeCtxtPtrxmlXIncludeNewContext(xmlDocPtr doc) {    xmlXIncludeCtxtPtr ret;#ifdef DEBUG_XINCLUDE    xmlGenericError(xmlGenericErrorContext, "New context\n");#endif    if (doc == NULL)	return(NULL);    ret = (xmlXIncludeCtxtPtr) xmlMalloc(sizeof(xmlXIncludeCtxt));    if (ret == NULL) {	xmlXIncludeErrMemory(NULL, (xmlNodePtr) doc,	                     "creating XInclude context");	return(NULL);    }    memset(ret, 0, sizeof(xmlXIncludeCtxt));    ret->doc = doc;    ret->incNr = 0;    ret->incBase = 0;    ret->incMax = 0;    ret->incTab = NULL;    ret->nbErrors = 0;    return(ret);}/** * xmlXIncludeURLPush: * @ctxt:  the parser context * @value:  the url * * Pushes a new url on top of the url stack * * Returns -1 in case of error, the index in the stack otherwise */static intxmlXIncludeURLPush(xmlXIncludeCtxtPtr ctxt,	           const xmlChar *value){    if (ctxt->urlNr > XINCLUDE_MAX_DEPTH) {	xmlXIncludeErr(ctxt, NULL, XML_XINCLUDE_RECURSION,	               "detected a recursion in %s\n", value);	return(-1);    }    if (ctxt->urlTab == NULL) {	ctxt->urlMax = 4;	ctxt->urlNr = 0;	ctxt->urlTab = (xmlChar * *) xmlMalloc(		        ctxt->urlMax * sizeof(ctxt->urlTab[0]));        if (ctxt->urlTab == NULL) {	    xmlXIncludeErrMemory(ctxt, NULL, "adding URL");            return (-1);        }    }    if (ctxt->urlNr >= ctxt->urlMax) {        ctxt->urlMax *= 2;        ctxt->urlTab =            (xmlChar * *) xmlRealloc(ctxt->urlTab,                                      ctxt->urlMax *                                      sizeof(ctxt->urlTab[0]));        if (ctxt->urlTab == NULL) {	    xmlXIncludeErrMemory(ctxt, NULL, "adding URL");            return (-1);        }    }    ctxt->url = ctxt->urlTab[ctxt->urlNr] = xmlStrdup(value);    return (ctxt->urlNr++);}/** * xmlXIncludeURLPop: * @ctxt: the parser context * * Pops the top URL from the URL stack */static voidxmlXIncludeURLPop(xmlXIncludeCtxtPtr ctxt){    xmlChar * ret;    if (ctxt->urlNr <= 0)        return;    ctxt->urlNr--;    if (ctxt->urlNr > 0)        ctxt->url = ctxt->urlTab[ctxt->urlNr - 1];    else        ctxt->url = NULL;    ret = ctxt->urlTab[ctxt->urlNr];    ctxt->urlTab[ctxt->urlNr] = 0;    if (ret != NULL)	xmlFree(ret);}/** * xmlXIncludeFreeContext: * @ctxt: the XInclude context * * Free an XInclude context */voidxmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) {    int i;#ifdef DEBUG_XINCLUDE    xmlGenericError(xmlGenericErrorContext, "Freeing context\n");#endif    if (ctxt == NULL)	return;    while (ctxt->urlNr > 0)	xmlXIncludeURLPop(ctxt);    if (ctxt->urlTab != NULL)	xmlFree(ctxt->urlTab);    for (i = 0;i < ctxt->incNr;i++) {	if (ctxt->incTab[i] != NULL)	    xmlXIncludeFreeRef(ctxt->incTab[i]);    }    for (i = 0;i < ctxt->txtNr;i++) {	if (ctxt->txturlTab[i] != NULL)	    xmlFree(ctxt->txturlTab[i]);    }    if (ctxt->incTab != NULL)	xmlFree(ctxt->incTab);    if (ctxt->txtTab != NULL)	xmlFree(ctxt->txtTab);    if (ctxt->txturlTab != NULL)	xmlFree(ctxt->txturlTab);    xmlFree(ctxt);}/** * xmlXIncludeParseFile: * @ctxt:  the XInclude context * @URL:  the URL or file path *  * parse a document for XInclude */static xmlDocPtrxmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {    xmlDocPtr ret;    xmlParserCtxtPtr pctxt;    char *directory = NULL;    xmlParserInputPtr inputStream;    xmlInitParser();    pctxt = xmlNewParserCtxt();    if (pctxt == NULL) {	xmlXIncludeErrMemory(ctxt, NULL, "cannot allocate parser context");	return(NULL);    }    /*     * try to ensure that new documents included are actually     * built with the same dictionary as the including document.     */    if ((ctxt->doc != NULL) && (ctxt->doc->dict != NULL) &&        (pctxt->dict != NULL)) {	xmlDictFree(pctxt->dict);	pctxt->dict = ctxt->doc->dict;	xmlDictReference(pctxt->dict);    }    xmlCtxtUseOptions(pctxt, ctxt->parseFlags | XML_PARSE_DTDLOAD);        inputStream = xmlLoadExternalEntity(URL, NULL, pctxt);    if (inputStream == NULL) {	xmlFreeParserCtxt(pctxt);	return(NULL);    }    inputPush(pctxt, inputStream);    if ((pctxt->directory == NULL) && (directory == NULL))        directory = xmlParserGetDirectory(URL);    if ((pctxt->directory == NULL) && (directory != NULL))        pctxt->directory = (char *) xmlStrdup((xmlChar *) directory);    pctxt->loadsubset = XML_DETECT_IDS;    xmlParseDocument(pctxt);    if (pctxt->wellFormed) {        ret = pctxt->myDoc;    }    else {        ret = NULL;	if (pctxt->myDoc != NULL)	    xmlFreeDoc(pctxt->myDoc);        pctxt->myDoc = NULL;    }    xmlFreeParserCtxt(pctxt);        return(ret);}/** * xmlXIncludeAddNode: * @ctxt:  the XInclude context * @cur:  the new node *  * Add a new node to process to an XInclude context */static intxmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {    xmlXIncludeRefPtr ref;    xmlURIPtr uri;

⌨️ 快捷键说明

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