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

📄 xinclude.c

📁 xml开源解析代码.版本为libxml2-2.6.29,可支持GB3212.网络消息发送XML时很有用.
💻 C
📖 第 1 页 / 共 5 页
字号:
    /*     * read the attributes     */    href = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_HREF);    if (href == NULL) {	href = xmlStrdup(BAD_CAST ""); /* @@@@ href is now optional */	if (href == NULL) 	    return(-1);    }    parse = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE);    if (parse != NULL) {	if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))	    xml = 1;	else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))	    xml = 0;	else {	    xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,	                   XML_XINCLUDE_PARSE_VALUE,			   "invalid value %s for 'parse'\n", parse);	    if (href != NULL)		xmlFree(href);	    if (parse != NULL)		xmlFree(parse);	    return(-1);	}    }    /*     * compute the URI     */    base = xmlNodeGetBase(ctxt->doc, cur);    if (base == NULL) {	URI = xmlBuildURI(href, ctxt->doc->URL);    } else {	URI = xmlBuildURI(href, base);    }    if (URI == NULL) {	xmlChar *escbase;	xmlChar *eschref;	/*	 * Some escaping may be needed	 */	escbase = xmlURIEscape(base);	eschref = xmlURIEscape(href);	URI = xmlBuildURI(eschref, escbase);	if (escbase != NULL)	    xmlFree(escbase);	if (eschref != NULL)	    xmlFree(eschref);    }    if (URI == NULL) {	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 	               XML_XINCLUDE_HREF_URI, "failed build URL\n", NULL);	if (parse != NULL)	    xmlFree(parse);	if (href != NULL)	    xmlFree(href);	if (base != NULL)	    xmlFree(base);	return(-1);    }#ifdef DEBUG_XINCLUDE    xmlGenericError(xmlGenericErrorContext, "parse: %s\n",	    xml ? "xml": "text");    xmlGenericError(xmlGenericErrorContext, "URI: %s\n", URI);#endif    /*     * Save the base for this include (saving the current one)     */    oldBase = ctxt->base;    ctxt->base = base;    if (xml) {	ret = xmlXIncludeLoadDoc(ctxt, URI, nr);	/* xmlXIncludeGetFragment(ctxt, cur, URI); */    } else {	ret = xmlXIncludeLoadTxt(ctxt, URI, nr);    }    /*     * Restore the original base before checking for fallback     */    ctxt->base = oldBase;        if (ret < 0) {	xmlNodePtr children;	/*	 * Time to try a fallback if availble	 */#ifdef DEBUG_XINCLUDE	xmlGenericError(xmlGenericErrorContext, "error looking for fallback\n");#endif	children = cur->children;	while (children != NULL) {	    if ((children->type == XML_ELEMENT_NODE) &&		(children->ns != NULL) &&		(xmlStrEqual(children->name, XINCLUDE_FALLBACK)) &&		((xmlStrEqual(children->ns->href, XINCLUDE_NS)) ||		 (xmlStrEqual(children->ns->href, XINCLUDE_OLD_NS)))) {		ret = xmlXIncludeLoadFallback(ctxt, children, nr);		if (ret == 0) 		    break;	    }	    children = children->next;	}    }    if (ret < 0) {	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 	               XML_XINCLUDE_NO_FALLBACK,		       "could not load %s, and no fallback was found\n",		       URI);    }    /*     * Cleanup     */    if (URI != NULL)	xmlFree(URI);    if (parse != NULL)	xmlFree(parse);    if (href != NULL)	xmlFree(href);    if (base != NULL)	xmlFree(base);    return(0);}/** * xmlXIncludeIncludeNode: * @ctxt: an XInclude context * @nr: the node number * * Inplement the infoset replacement for the given node * * Returns 0 if substitution succeeded, -1 if some processing failed */static intxmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {    xmlNodePtr cur, end, list, tmp;    if (ctxt == NULL)	return(-1);    if ((nr < 0) || (nr >= ctxt->incNr))	return(-1);    cur = ctxt->incTab[nr]->ref;    if (cur == NULL)	return(-1);    /*     * If we stored an XPointer a late computation may be needed     */    if ((ctxt->incTab[nr]->inc == NULL) &&	(ctxt->incTab[nr]->xptr != NULL)) {	ctxt->incTab[nr]->inc =	    xmlXIncludeCopyXPointer(ctxt, ctxt->doc, ctxt->doc,		                    ctxt->incTab[nr]->xptr);	xmlXPathFreeObject(ctxt->incTab[nr]->xptr);	ctxt->incTab[nr]->xptr = NULL;    }    list = ctxt->incTab[nr]->inc;    ctxt->incTab[nr]->inc = NULL;    /*     * Check against the risk of generating a multi-rooted document     */    if ((cur->parent != NULL) &&	(cur->parent->type != XML_ELEMENT_NODE)) {	int nb_elem = 0;	tmp = list;	while (tmp != NULL) {	    if (tmp->type == XML_ELEMENT_NODE)		nb_elem++;	    tmp = tmp->next;	}	if (nb_elem > 1) {	    xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, 	                   XML_XINCLUDE_MULTIPLE_ROOT,		       "XInclude error: would result in multiple root nodes\n",			   NULL);	    return(-1);	}    }    if (ctxt->parseFlags & XML_PARSE_NOXINCNODE) {	/*	 * Add the list of nodes	 */	while (list != NULL) {	    end = list;	    list = list->next;	    xmlAddPrevSibling(cur, end);	}	xmlUnlinkNode(cur);	xmlFreeNode(cur);    } else {	/*	 * Change the current node as an XInclude start one, and add an	 * XInclude end one	 */	cur->type = XML_XINCLUDE_START;	end = xmlNewDocNode(cur->doc, cur->ns, cur->name, NULL);	if (end == NULL) {	    xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,	                   XML_XINCLUDE_BUILD_FAILED,			   "failed to build node\n", NULL);	    return(-1);	}	end->type = XML_XINCLUDE_END;	xmlAddNextSibling(cur, end);	/*	 * Add the list of nodes	 */	while (list != NULL) {	    cur = list;	    list = list->next;	    xmlAddPrevSibling(end, cur);	}    }        return(0);}/** * xmlXIncludeTestNode: * @ctxt: the XInclude processing context * @node: an XInclude node * * test if the node is an XInclude node * * Returns 1 true, 0 otherwise */static intxmlXIncludeTestNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {    if (node == NULL)	return(0);    if (node->type != XML_ELEMENT_NODE)	return(0);    if (node->ns == NULL)	return(0);    if ((xmlStrEqual(node->ns->href, XINCLUDE_NS)) ||        (xmlStrEqual(node->ns->href, XINCLUDE_OLD_NS))) {	if (xmlStrEqual(node->ns->href, XINCLUDE_OLD_NS)) {	    if (ctxt->legacy == 0) {#if 0 /* wait for the XML Core Working Group to get something stable ! */		xmlXIncludeWarn(ctxt, node, XML_XINCLUDE_DEPRECATED_NS,	               "Deprecated XInclude namespace found, use %s",		                XINCLUDE_NS);#endif	        ctxt->legacy = 1;	    }	}	if (xmlStrEqual(node->name, XINCLUDE_NODE)) {	    xmlNodePtr child = node->children;	    int nb_fallback = 0;	    while (child != NULL) {		if ((child->type == XML_ELEMENT_NODE) &&		    (child->ns != NULL) &&		    ((xmlStrEqual(child->ns->href, XINCLUDE_NS)) ||		     (xmlStrEqual(child->ns->href, XINCLUDE_OLD_NS)))) {		    if (xmlStrEqual(child->name, XINCLUDE_NODE)) {			xmlXIncludeErr(ctxt, node,			               XML_XINCLUDE_INCLUDE_IN_INCLUDE,				       "%s has an 'include' child\n",				       XINCLUDE_NODE);			return(0);		    }		    if (xmlStrEqual(child->name, XINCLUDE_FALLBACK)) {			nb_fallback++;		    }		}		child = child->next;	    }	    if (nb_fallback > 1) {		xmlXIncludeErr(ctxt, node, XML_XINCLUDE_FALLBACKS_IN_INCLUDE,			       "%s has multiple fallback children\n",		               XINCLUDE_NODE);		return(0);	    }	    return(1);	}	if (xmlStrEqual(node->name, XINCLUDE_FALLBACK)) {	    if ((node->parent == NULL) ||		(node->parent->type != XML_ELEMENT_NODE) ||		(node->parent->ns == NULL) ||		((!xmlStrEqual(node->parent->ns->href, XINCLUDE_NS)) &&		 (!xmlStrEqual(node->parent->ns->href, XINCLUDE_OLD_NS))) ||		(!xmlStrEqual(node->parent->name, XINCLUDE_NODE))) {		xmlXIncludeErr(ctxt, node,		               XML_XINCLUDE_FALLBACK_NOT_IN_INCLUDE,			       "%s is not the child of an 'include'\n",			       XINCLUDE_FALLBACK);	    }	}    }    return(0);}/** * xmlXIncludeDoProcess: * @ctxt: the XInclude processing context * @doc: an XML document * @tree: the top of the tree to process * * Implement the XInclude substitution on the XML document @doc * * Returns 0 if no substitution were done, -1 if some processing failed *    or the number of substitutions done. */static intxmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree) {    xmlNodePtr cur;    int ret = 0;    int i, start;    if ((doc == NULL) || (tree == NULL))	return(-1);    if (ctxt == NULL)	return(-1);    if (doc->URL != NULL) {	ret = xmlXIncludeURLPush(ctxt, doc->URL);	if (ret < 0)	    return(-1);    }    start = ctxt->incNr;    /*     * First phase: lookup the elements in the document     */    cur = tree;    if (xmlXIncludeTestNode(ctxt, cur) == 1)	xmlXIncludePreProcessNode(ctxt, cur);    while ((cur != NULL) && (cur != tree->parent)) {	/* TODO: need to work on entities -> stack */	if ((cur->children != NULL) &&	    (cur->children->type != XML_ENTITY_DECL) &&	    (cur->children->type != XML_XINCLUDE_START) &&	    (cur->children->type != XML_XINCLUDE_END)) {	    cur = cur->children;	    if (xmlXIncludeTestNode(ctxt, cur))		xmlXIncludePreProcessNode(ctxt, cur);	} else if (cur->next != NULL) {	    cur = cur->next;	    if (xmlXIncludeTestNode(ctxt, cur))		xmlXIncludePreProcessNode(ctxt, cur);	} else {	    if (cur == tree)	        break;	    do {		cur = cur->parent;		if ((cur == NULL) || (cur == tree->parent))		    break; /* do */		if (cur->next != NULL) {		    cur = cur->next;		    if (xmlXIncludeTestNode(ctxt, cur))			xmlXIncludePreProcessNode(ctxt, cur);		    break; /* do */		}	    } while (cur != NULL);	}    }    /*     * Second Phase : collect the infosets fragments     */    for (i = start;i < ctxt->incNr; i++) {        xmlXIncludeLoadNode(ctxt, i);	ret++;    }    /*     * Third phase: extend the original document infoset.     *     * Originally we bypassed the inclusion if there were any errors     * encountered on any of the XIncludes.  A bug was raised (bug     * 132588) requesting that we output the XIncludes without error,     * so the check for inc!=NULL || xptr!=NULL was put in.  This may     * give some other problems in the future, but for now it seems to     * work ok.     *     */    for (i = ctxt->incBase;i < ctxt->incNr; i++) {	if ((ctxt->incTab[i]->inc != NULL) ||		(ctxt->incTab[i]->xptr != NULL) ||		(ctxt->incTab[i]->emptyFb != 0))	/* (empty fallback) */	    xmlXIncludeIncludeNode(ctxt, i);    }    if (doc->URL != NULL)	xmlXIncludeURLPop(ctxt);    return(ret);}/** * xmlXIncludeSetFlags: * @ctxt:  an XInclude processing context * @flags: a set of xmlParserOption used for parsing XML includes * * Set the flags used for further processing of XML resources. * * Returns 0 in case of success and -1 in case of error. */intxmlXIncludeSetFlags(xmlXIncludeCtxtPtr ctxt, int flags) {    if (ctxt == NULL)        return(-1);    ctxt->parseFlags = flags;    return(0);} /** * xmlXIncludeProcessFlagsData: * @doc: an XML document * @flags: a set of xmlParserOption used for parsing XML includes * @data: application data that will be passed to the parser context *        in the _private field of the parser context(s) * * Implement the XInclude substitution on the XML document @doc * * Returns 0 if no substitution were done, -1 if some processing failed *    or the number of substitutions done. */intxmlXIncludeProcessFlagsData(xmlDocPtr doc, int flags, void *data) {    xmlXIncludeCtxtPtr ctxt;    xmlNodePtr tree;    int ret = 0;    if (doc == NULL)	return(-1);    tree = xmlDocGetRootElement(doc);    if (tree == NULL)	return(-1);    ctxt = xmlXIncludeNewContext(doc);    if (ctxt == NULL)	return(-1);    ctxt->_private = data;    ctxt->base = xmlStrdup((xmlChar *)doc->URL);    xmlXIncludeSetFlags(ctxt, flags);    ret = xmlXIncludeDoProcess(ctxt, doc, tree);    if ((ret >= 0) && (ctxt->nbErrors > 0))	ret = -1;    xmlXIncludeFreeContext(ctxt);    return(ret);}/** * xmlXIncludeProcessFlags: * @doc: an XML document * @flags: a set of xmlParserOption used for parsing XML includes * * Implement the XInclude substitution on the XML document @doc * * Returns 0 if no substitution were done, -1 if some processing failed *    or the number of substitutions done. */intxmlXIncludeProcessFlags(xmlDocPtr doc, int flags) {    return xmlXIncludeProcessFlagsData(doc, flags, NULL);}/** * xmlXIncludeProcess: * @doc: an XML document * * Implement the XInclude substitution on the XML document @doc * * Returns 0 if no substitution were done, -1 if some processing failed *    or the number of substitutions done. */intxmlXIncludeProcess(xmlDocPtr doc) {    return(xmlXIncludeProcessFlags(doc, 0));}/** * xmlXIncludeProcessTreeFlags: * @tree: a node in an XML document * @flags: a set of xmlParserOption used for parsing XML includes * * Implement the XInclude substitution for the given subtree * * Returns 0 if no substitution were done, -1 if some processing failed *    or the number of substitutions done. */intxmlXIncludeProcessTreeFlags(xmlNodePtr tree, int flags) {    xmlXIncludeCtxtPtr ctxt;    int ret = 0;    if ((tree == NULL) || (tree->doc =

⌨️ 快捷键说明

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