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

📄 xpointer.c.svn-base

📁 这是一个用于解析xml文件的类库。使用这个类库
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
	NEXT;    }    *cur = 0;    if ((level != 0) && (CUR == 0)) {	xmlFree(buffer);	XP_ERROR(XPTR_SYNTAX_ERROR);    }    if (xmlStrEqual(name, (xmlChar *) "xpointer")) {	const xmlChar *left = CUR_PTR;	CUR_PTR = buffer;	/*	 * To evaluate an xpointer scheme element (4.3) we need:	 *   context initialized to the root	 *   context position initalized to 1	 *   context size initialized to 1	 */	ctxt->context->node = (xmlNodePtr)ctxt->context->doc;	ctxt->context->proximityPosition = 1;	ctxt->context->contextSize = 1;	xmlXPathEvalExpr(ctxt);	CUR_PTR=left;    } else if (xmlStrEqual(name, (xmlChar *) "element")) {	const xmlChar *left = CUR_PTR;	xmlChar *name2;	CUR_PTR = buffer;	if (buffer[0] == '/') {	    xmlXPathRoot(ctxt);	    xmlXPtrEvalChildSeq(ctxt, NULL);	} else {	    name2 = xmlXPathParseName(ctxt);	    if (name2 == NULL) {		CUR_PTR = left;		xmlFree(buffer);		XP_ERROR(XPATH_EXPR_ERROR);	    }	    xmlXPtrEvalChildSeq(ctxt, name2);	}	CUR_PTR = left;#ifdef XPTR_XMLNS_SCHEME    } else if (xmlStrEqual(name, (xmlChar *) "xmlns")) {	const xmlChar *left = CUR_PTR;	xmlChar *prefix;	xmlChar *URI;	xmlURIPtr value;	CUR_PTR = buffer;        prefix = xmlXPathParseNCName(ctxt);	if (prefix == NULL) {	    xmlFree(buffer);	    xmlFree(name);	    XP_ERROR(XPTR_SYNTAX_ERROR);	}	SKIP_BLANKS;	if (CUR != '=') {	    xmlFree(prefix);	    xmlFree(buffer);	    xmlFree(name);	    XP_ERROR(XPTR_SYNTAX_ERROR);	}	NEXT;	SKIP_BLANKS;	/* @@ check escaping in the XPointer WD */	value = xmlParseURI((const char *)ctxt->cur);	if (value == NULL) {	    xmlFree(prefix);	    xmlFree(buffer);	    xmlFree(name);	    XP_ERROR(XPTR_SYNTAX_ERROR);	}	URI = xmlSaveUri(value);	xmlFreeURI(value);	if (URI == NULL) {	    xmlFree(prefix);	    xmlFree(buffer);	    xmlFree(name);	    XP_ERROR(XPATH_MEMORY_ERROR);	}		xmlXPathRegisterNs(ctxt->context, prefix, URI);	CUR_PTR = left;	xmlFree(URI);	xmlFree(prefix);#endif /* XPTR_XMLNS_SCHEME */    } else {        xmlXPtrErr(ctxt, XML_XPTR_UNKNOWN_SCHEME,		   "unsupported scheme '%s'\n", name);    }    xmlFree(buffer);    xmlFree(name);}/** * xmlXPtrEvalFullXPtr: * @ctxt:  the XPointer Parser context * @name:  the preparsed Scheme for the first XPtrPart * * FullXPtr ::= XPtrPart (S? XPtrPart)* * * As the specs says: * ----------- * When multiple XPtrParts are provided, they must be evaluated in * left-to-right order. If evaluation of one part fails, the nexti * is evaluated. The following conditions cause XPointer part failure: * * - An unknown scheme * - A scheme that does not locate any sub-resource present in the resource * - A scheme that is not applicable to the media type of the resource * * The XPointer application must consume a failed XPointer part and * attempt to evaluate the next one, if any. The result of the first * XPointer part whose evaluation succeeds is taken to be the fragment * located by the XPointer as a whole. If all the parts fail, the result * for the XPointer as a whole is a sub-resource error. * ----------- * * Parse and evaluate a Full XPtr i.e. possibly a cascade of XPath based * expressions or other schemes. */static voidxmlXPtrEvalFullXPtr(xmlXPathParserContextPtr ctxt, xmlChar *name) {    if (name == NULL)    name = xmlXPathParseName(ctxt);    if (name == NULL)	XP_ERROR(XPATH_EXPR_ERROR);    while (name != NULL) {	xmlXPtrEvalXPtrPart(ctxt, name);	/* in case of syntax error, break here */	if (ctxt->error != XPATH_EXPRESSION_OK)	    return;	/*	 * If the returned value is a non-empty nodeset	 * or location set, return here.	 */	if (ctxt->value != NULL) {	    xmlXPathObjectPtr obj = ctxt->value;	    switch (obj->type) {		case XPATH_LOCATIONSET: {		    xmlLocationSetPtr loc = ctxt->value->user;		    if ((loc != NULL) && (loc->locNr > 0))			return;		    break;		}		case XPATH_NODESET: {		    xmlNodeSetPtr loc = ctxt->value->nodesetval;		    if ((loc != NULL) && (loc->nodeNr > 0))			return;		    break;		}		default:		    break;	    }	    /*	     * Evaluating to improper values is equivalent to	     * a sub-resource error, clean-up the stack	     */	    do {		obj = valuePop(ctxt);		if (obj != NULL) {		    xmlXPathFreeObject(obj);		}	    } while (obj != NULL);	}	/*	 * Is there another XPointer part.	 */	SKIP_BLANKS;	name = xmlXPathParseName(ctxt);    }}/** * xmlXPtrEvalChildSeq: * @ctxt:  the XPointer Parser context * @name:  a possible ID name of the child sequence * *  ChildSeq ::= '/1' ('/' [0-9]*)* *             | Name ('/' [0-9]*)+ * * Parse and evaluate a Child Sequence. This routine also handle the * case of a Bare Name used to get a document ID. */static voidxmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name) {    /*     * XPointer don't allow by syntax to address in mutirooted trees     * this might prove useful in some cases, warn about it.     */    if ((name == NULL) && (CUR == '/') && (NXT(1) != '1')) {        xmlXPtrErr(ctxt, XML_XPTR_CHILDSEQ_START,		   "warning: ChildSeq not starting by /1\n", NULL);    }    if (name != NULL) {	valuePush(ctxt, xmlXPathNewString(name));	xmlFree(name);	xmlXPathIdFunction(ctxt, 1);	CHECK_ERROR;    }    while (CUR == '/') {	int child = 0;	NEXT;        	while ((CUR >= '0') && (CUR <= '9')) {	    child = child * 10 + (CUR - '0');	    NEXT;	}	xmlXPtrGetChildNo(ctxt, child);    }}/** * xmlXPtrEvalXPointer: * @ctxt:  the XPointer Parser context * *  XPointer ::= Name *             | ChildSeq *             | FullXPtr * * Parse and evaluate an XPointer */static voidxmlXPtrEvalXPointer(xmlXPathParserContextPtr ctxt) {    if (ctxt->valueTab == NULL) {	/* Allocate the value stack */	ctxt->valueTab = (xmlXPathObjectPtr *) 			 xmlMalloc(10 * sizeof(xmlXPathObjectPtr));	if (ctxt->valueTab == NULL) {	    xmlXPtrErrMemory("allocating evaluation context");	    return;	}	ctxt->valueNr = 0;	ctxt->valueMax = 10;	ctxt->value = NULL;    }    SKIP_BLANKS;    if (CUR == '/') {	xmlXPathRoot(ctxt);        xmlXPtrEvalChildSeq(ctxt, NULL);    } else {	xmlChar *name;	name = xmlXPathParseName(ctxt);	if (name == NULL)	    XP_ERROR(XPATH_EXPR_ERROR);	if (CUR == '(') {	    xmlXPtrEvalFullXPtr(ctxt, name);	    /* Short evaluation */	    return;	} else {	    /* this handle both Bare Names and Child Sequences */	    xmlXPtrEvalChildSeq(ctxt, name);	}    }    SKIP_BLANKS;    if (CUR != 0)	XP_ERROR(XPATH_EXPR_ERROR);}/************************************************************************ *									* *			General routines				* *									* ************************************************************************/void xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs);void xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs);void xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs);void xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs);void xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs);void xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs);void xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs);/** * xmlXPtrNewContext: * @doc:  the XML document * @here:  the node that directly contains the XPointer being evaluated or NULL * @origin:  the element from which a user or program initiated traversal of *           the link, or NULL. * * Create a new XPointer context * * Returns the xmlXPathContext just allocated. */xmlXPathContextPtrxmlXPtrNewContext(xmlDocPtr doc, xmlNodePtr here, xmlNodePtr origin) {    xmlXPathContextPtr ret;    ret = xmlXPathNewContext(doc);    if (ret == NULL)	return(ret);    ret->xptr = 1;    ret->here = here;    ret->origin = origin;    xmlXPathRegisterFunc(ret, (xmlChar *)"range-to",	                 xmlXPtrRangeToFunction);    xmlXPathRegisterFunc(ret, (xmlChar *)"range",	                 xmlXPtrRangeFunction);    xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside",	                 xmlXPtrRangeInsideFunction);    xmlXPathRegisterFunc(ret, (xmlChar *)"string-range",	                 xmlXPtrStringRangeFunction);    xmlXPathRegisterFunc(ret, (xmlChar *)"start-point",	                 xmlXPtrStartPointFunction);    xmlXPathRegisterFunc(ret, (xmlChar *)"end-point",	                 xmlXPtrEndPointFunction);    xmlXPathRegisterFunc(ret, (xmlChar *)"here",	                 xmlXPtrHereFunction);    xmlXPathRegisterFunc(ret, (xmlChar *)" origin",	                 xmlXPtrOriginFunction);    return(ret);}/** * xmlXPtrEval: * @str:  the XPointer expression * @ctx:  the XPointer context * * Evaluate the XPath Location Path in the given context. * * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. *         the caller has to free the object. */xmlXPathObjectPtrxmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {    xmlXPathParserContextPtr ctxt;    xmlXPathObjectPtr res = NULL, tmp;    xmlXPathObjectPtr init = NULL;    int stack = 0;    xmlXPathInit();    if ((ctx == NULL) || (str == NULL))	return(NULL);    ctxt = xmlXPathNewParserContext(str, ctx);    ctxt->xptr = 1;    xmlXPtrEvalXPointer(ctxt);    if ((ctxt->value != NULL) &&	(ctxt->value->type != XPATH_NODESET) &&	(ctxt->value->type != XPATH_LOCATIONSET)) {        xmlXPtrErr(ctxt, XML_XPTR_EVAL_FAILED,		"xmlXPtrEval: evaluation failed to return a node set\n",		   NULL);    } else {	res = valuePop(ctxt);    }    do {        tmp = valuePop(ctxt);	if (tmp != NULL) {	    if (tmp != init) {		if (tmp->type == XPATH_NODESET) {		    /*		     * Evaluation may push a root nodeset which is unused		     */		    xmlNodeSetPtr set; 		    set = tmp->nodesetval;		    if ((set->nodeNr != 1) ||			(set->nodeTab[0] != (xmlNodePtr) ctx->doc))			stack++;		} else		    stack++;    	    }	    xmlXPathFreeObject(tmp);        }    } while (tmp != NULL);    if (stack != 0) {        xmlXPtrErr(ctxt, XML_XPTR_EXTRA_OBJECTS,		   "xmlXPtrEval: object(s) left on the eval stack\n",		   NULL);    }    if (ctxt->error != XPATH_EXPRESSION_OK) {	xmlXPathFreeObject(res);	res = NULL;    }            xmlXPathFreeParserContext(ctxt);    return(res);}/** * xmlXPtrBuildRangeNodeList: * @range:  a range object * * Build a node list tree copy of the range * * Returns an xmlNodePtr list or NULL. *         the caller has to free the node tree. */static xmlNodePtrxmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {    /* pointers to generated nodes */    xmlNodePtr list = NULL, last = NULL, parent = NULL, tmp;    /* pointers to traversal nodes */    xmlNodePtr start, cur, end;    int index1, index2;    if (range == NULL)	return(NULL);    if (range->type != XPATH_RANGE)	return(NULL);    start = (xmlNodePtr) range->user;    if (start == NULL)	return(NULL);    end = range->user2;    if (end == NULL)	return(xmlCopyNode(start, 1));    cur = start;    index1 = range->index;    index2 = range->index2;    while (cur != NULL) {	if (cur == end) {	    if (cur->type == XML_TEXT_NODE) {		const xmlChar *content = cur->content;		int len;		if (content == NULL) {		    tmp = xmlNewTextLen(NULL, 0);		} else {		    len = index2;		    if ((cur == start) && (index1 > 1)) {			content += (index1 - 1);			len -= (index1 - 1);			index1 = 0;		    } else {			len = index2;		    }		    tmp = xmlNewTextLen(content, len);		}		/* single sub text node selection */		if (list == NULL)		    return(tmp);		/* prune and return full set */		if (last != NULL)		    xmlAddNextSibling(last, tmp);		else 		    xmlAddChild(parent, tmp);		return(list);	    } else {		tmp = xmlCopyNode(cur, 0);		if (list == NULL)		    list = tmp;		else {		    if (last != NULL)			xmlAddNextSibling(last, tmp);		    else			xmlAddChild(parent, tmp);		}		last = NULL;		parent = tmp;		if (index2 > 1) {		    end = xmlXPtrGetNthChild(cur, index2 - 1);		    index2 = 0;		}		if ((cur == start) && (index1 > 1)) {		    cur = xmlXPtrGetNthChild(cur, index1 - 1);		    index1 = 0;		} else {		    cur = cur->children;		}		/*		 * Now gather the remaining nodes from cur to end		 */		continue; /* while */	    }	} else if ((cur == start) &&		   (list == NULL) /* looks superfluous but ... */ ) {	    if ((cur->type == XML_TEXT_NODE) ||		(cur->type == XML_CDATA_SECTION_NODE)) {		const xmlChar *content = cur->content;		if (content == NULL) {		    tmp = xmlNewTextLen(NULL, 0);		} else {		    if (index1 > 1) {			content += (index1 - 1);		    }		    tmp = xmlNewText(content);		}		last = list = tmp;	    } else {		if ((cur == start) && (index1 > 1)) {		    tmp = xmlCopyNode(cur, 0);		    list = tmp;		    parent = tmp;		    last = NULL;		    cur = xmlXPtrGetNthChild(cur, index1 - 1);		    index1 = 0;		    /*		     * Now gather the remaining nodes from cur to end		     */		    continue; /* while */		}

⌨️ 快捷键说明

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