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

📄 xpath.c

📁 libxml,在UNIX/LINUX下非常重要的一个库,为XML相关应用提供方便.目前上载的是最新版本,若要取得最新版本,请参考里面的readme.
💻 C
📖 第 1 页 / 共 5 页
字号:
		    fprintf(output, "'name' "); break;	    }	    switch (type) {                case NODE_TYPE_NODE:		    fprintf(output, "'node' "); break;                case NODE_TYPE_COMMENT:		    fprintf(output, "'comment' "); break;                case NODE_TYPE_TEXT:		    fprintf(output, "'text' "); break;                case NODE_TYPE_PI:		    fprintf(output, "'PI' "); break;	    }	    if (prefix != NULL)		fprintf(output, "%s:", prefix);	    if (name != NULL)		fprintf(output, "%s", (const char *) name);	    break;        }	case XPATH_OP_VALUE: {	    xmlXPathObjectPtr object = (xmlXPathObjectPtr) op->value4;	    fprintf(output, "ELEM ");	    xmlXPathDebugDumpObject(output, object, 0);	    goto finish;	}	case XPATH_OP_VARIABLE: {	    const xmlChar *prefix = op->value5;	    const xmlChar *name = op->value4;	    if (prefix != NULL)		fprintf(output, "VARIABLE %s:%s", prefix, name);	    else		fprintf(output, "VARIABLE %s", name);	    break;	}	case XPATH_OP_FUNCTION: {	    int nbargs = op->value;	    const xmlChar *prefix = op->value5;	    const xmlChar *name = op->value4;	    if (prefix != NULL)		fprintf(output, "FUNCTION %s:%s(%d args)",			prefix, name, nbargs);	    else		fprintf(output, "FUNCTION %s(%d args)", name, nbargs);	    break;	}        case XPATH_OP_ARG: fprintf(output, "ARG"); break;        case XPATH_OP_PREDICATE: fprintf(output, "PREDICATE"); break;        case XPATH_OP_FILTER: fprintf(output, "FILTER"); break;#ifdef LIBXML_XPTR_ENABLED        case XPATH_OP_RANGETO: fprintf(output, "RANGETO"); break;#endif	default:        fprintf(output, "UNKNOWN %d\n", op->op); return;    }    fprintf(output, "\n");finish:    if (op->ch1 >= 0)	xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch1], depth + 1);    if (op->ch2 >= 0)	xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch2], depth + 1);}/** * xmlXPathDebugDumpCompExpr: * @output:  the FILE * for the output * @comp:  the precompiled XPath expression * @depth:  the indentation level. * * Dumps the tree of the compiled XPath expression. */voidxmlXPathDebugDumpCompExpr(FILE *output, xmlXPathCompExprPtr comp,	                  int depth) {    int i;    char shift[100];    if ((output == NULL) || (comp == NULL)) return;    for (i = 0;((i < depth) && (i < 25));i++)        shift[2 * i] = shift[2 * i + 1] = ' ';    shift[2 * i] = shift[2 * i + 1] = 0;    fprintf(output, shift);    if (comp == NULL) {	fprintf(output, "Compiled Expression is NULL\n");	return;    }    fprintf(output, "Compiled Expression : %d elements\n",	    comp->nbStep);    i = comp->last;    xmlXPathDebugDumpStepOp(output, comp, &comp->steps[i], depth + 1);}#endif /* LIBXML_DEBUG_ENABLED *//************************************************************************ *									* * 		Parser stacks related functions and macros		* *									* ************************************************************************//** * valuePop: * @ctxt: an XPath evaluation context * * Pops the top XPath object from the value stack * * Returns the XPath object just removed */extern xmlXPathObjectPtrvaluePop(xmlXPathParserContextPtr ctxt){    xmlXPathObjectPtr ret;    if ((ctxt == NULL) || (ctxt->valueNr <= 0))        return (0);    ctxt->valueNr--;    if (ctxt->valueNr > 0)        ctxt->value = ctxt->valueTab[ctxt->valueNr - 1];    else        ctxt->value = NULL;    ret = ctxt->valueTab[ctxt->valueNr];    ctxt->valueTab[ctxt->valueNr] = 0;    return (ret);}/** * valuePush: * @ctxt:  an XPath evaluation context * @value:  the XPath object * * Pushes a new XPath object on top of the value stack * * returns the number of items on the value stack */extern intvaluePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value){    if ((ctxt == NULL) || (value == NULL)) return(-1);    if (ctxt->valueNr >= ctxt->valueMax) {        xmlXPathObjectPtr *tmp;        tmp = (xmlXPathObjectPtr *) xmlRealloc(ctxt->valueTab,                                             2 * ctxt->valueMax *                                             sizeof(ctxt->valueTab[0]));        if (tmp == NULL) {            xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");            return (0);        }        ctxt->valueMax *= 2;	ctxt->valueTab = tmp;    }    ctxt->valueTab[ctxt->valueNr] = value;    ctxt->value = value;    return (ctxt->valueNr++);}/** * xmlXPathPopBoolean: * @ctxt:  an XPath parser context * * Pops a boolean from the stack, handling conversion if needed. * Check error with #xmlXPathCheckError. * * Returns the boolean */intxmlXPathPopBoolean (xmlXPathParserContextPtr ctxt) {    xmlXPathObjectPtr obj;    int ret;    obj = valuePop(ctxt);    if (obj == NULL) {	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);	return(0);    }    if (obj->type != XPATH_BOOLEAN)	ret = xmlXPathCastToBoolean(obj);    else        ret = obj->boolval;    xmlXPathFreeObject(obj);    return(ret);}/** * xmlXPathPopNumber: * @ctxt:  an XPath parser context * * Pops a number from the stack, handling conversion if needed. * Check error with #xmlXPathCheckError. * * Returns the number */doublexmlXPathPopNumber (xmlXPathParserContextPtr ctxt) {    xmlXPathObjectPtr obj;    double ret;    obj = valuePop(ctxt);    if (obj == NULL) {	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);	return(0);    }    if (obj->type != XPATH_NUMBER)	ret = xmlXPathCastToNumber(obj);    else        ret = obj->floatval;    xmlXPathFreeObject(obj);    return(ret);}/** * xmlXPathPopString: * @ctxt:  an XPath parser context * * Pops a string from the stack, handling conversion if needed. * Check error with #xmlXPathCheckError. * * Returns the string */xmlChar *xmlXPathPopString (xmlXPathParserContextPtr ctxt) {    xmlXPathObjectPtr obj;    xmlChar * ret;    obj = valuePop(ctxt);    if (obj == NULL) {	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);	return(NULL);    }    ret = xmlXPathCastToString(obj);	/* this does required strdup */    /* TODO: needs refactoring somewhere else */    if (obj->stringval == ret)	obj->stringval = NULL;    xmlXPathFreeObject(obj);    return(ret);}/** * xmlXPathPopNodeSet: * @ctxt:  an XPath parser context * * Pops a node-set from the stack, handling conversion if needed. * Check error with #xmlXPathCheckError. * * Returns the node-set */xmlNodeSetPtrxmlXPathPopNodeSet (xmlXPathParserContextPtr ctxt) {    xmlXPathObjectPtr obj;    xmlNodeSetPtr ret;    if (ctxt == NULL) return(NULL);    if (ctxt->value == NULL) {	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);	return(NULL);    }    if (!xmlXPathStackIsNodeSet(ctxt)) {	xmlXPathSetTypeError(ctxt);	return(NULL);    }    obj = valuePop(ctxt);    ret = obj->nodesetval;#if 0    /* to fix memory leak of not clearing obj->user */    if (obj->boolval && obj->user != NULL)        xmlFreeNodeList((xmlNodePtr) obj->user);#endif    xmlXPathFreeNodeSetList(obj);    return(ret);}/** * xmlXPathPopExternal: * @ctxt:  an XPath parser context * * Pops an external object from the stack, handling conversion if needed. * Check error with #xmlXPathCheckError. * * Returns the object */void *xmlXPathPopExternal (xmlXPathParserContextPtr ctxt) {    xmlXPathObjectPtr obj;    void * ret;    if ((ctxt == NULL) || (ctxt->value == NULL)) {	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);	return(NULL);    }    if (ctxt->value->type != XPATH_USERS) {	xmlXPathSetTypeError(ctxt);	return(NULL);    }    obj = valuePop(ctxt);    ret = obj->user;    xmlXPathFreeObject(obj);    return(ret);}/* * Macros for accessing the content. Those should be used only by the parser, * and not exported. * * Dirty macros, i.e. one need to make assumption on the context to use them * *   CUR_PTR return the current pointer to the xmlChar to be parsed. *   CUR     returns the current xmlChar value, i.e. a 8 bit value *           in ISO-Latin or UTF-8. *           This should be used internally by the parser *           only to compare to ASCII values otherwise it would break when *           running with UTF-8 encoding. *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only *           to compare on ASCII based substring. *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined *           strings within the parser. *   CURRENT Returns the current char value, with the full decoding of *           UTF-8 if we are using this mode. It returns an int. *   NEXT    Skip to the next character, this does the proper decoding *           in UTF-8 mode. It also pop-up unfinished entities on the fly. *           It returns the pointer to the current xmlChar. */#define CUR (*ctxt->cur)#define SKIP(val) ctxt->cur += (val)#define NXT(val) ctxt->cur[(val)]#define CUR_PTR ctxt->cur#define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l)#define COPY_BUF(l,b,i,v)                                              \    if (l == 1) b[i++] = (xmlChar) v;                                  \    else i += xmlCopyChar(l,&b[i],v)#define NEXTL(l)  ctxt->cur += l#define SKIP_BLANKS 							\    while (IS_BLANK_CH(*(ctxt->cur))) NEXT#define CURRENT (*ctxt->cur)#define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)#ifndef DBL_DIG#define DBL_DIG 16#endif#ifndef DBL_EPSILON#define DBL_EPSILON 1E-9#endif#define UPPER_DOUBLE 1E9#define LOWER_DOUBLE 1E-5#define INTEGER_DIGITS DBL_DIG#define FRACTION_DIGITS (DBL_DIG + 1)#define EXPONENT_DIGITS (3 + 2)/** * xmlXPathFormatNumber: * @number:     number to format * @buffer:     output buffer * @buffersize: size of output buffer * * Convert the number into a string representation. */static voidxmlXPathFormatNumber(double number, char buffer[], int buffersize){    switch (xmlXPathIsInf(number)) {    case 1:	if (buffersize > (int)sizeof("Infinity"))	    snprintf(buffer, buffersize, "Infinity");	break;    case -1:	if (buffersize > (int)sizeof("-Infinity"))	    snprintf(buffer, buffersize, "-Infinity");	break;    default:	if (xmlXPathIsNaN(number)) {	    if (buffersize > (int)sizeof("NaN"))		snprintf(buffer, buffersize, "NaN");	} else if (number == 0 && xmlXPathGetSign(number) != 0) {	    snprintf(buffer, buffersize, "0");	} else if (number == ((int) number)) {	    char work[30];	    char *ptr, *cur;	    int res, value = (int) number;            ptr = &buffer[0];	    if (value < 0) {		*ptr++ = '-';		value = -value;	    }	    if (value == 0) {		*ptr++ = '0';	    } else {		cur = &work[0];		while (value != 0) {		    res = value % 10;		    value = value / 10;		    *cur++ = '0' + res;		}		cur--;		while ((cur >= &work[0]) && (ptr - buffer < buffersize)) {		    *ptr++ = *cur--;		}	    }	    if (ptr - buffer < buffersize) {		*ptr = 0;	    } else if (buffersize > 0) {		ptr--;		*ptr = 0;	    }	} else {	    /* 3 is sign, decimal point, and terminating zero */	    char work[DBL_DIG + EXPONENT_DIGITS + 3];	    int integer_place, fraction_place;	    char *ptr;	    char *after_fraction;	    double absolute_value;	    int size;	    absolute_value = fabs(number);	    /*	     * First choose format - scientific or regular floating point.	     * In either case, result is in work, and after_fraction points	     * just past the fractional part.	    */	    if ( ((absolute_value > UPPER_DOUBLE) ||		  (absolute_value < LOWER_DOUBLE)) &&		 (absolute_value != 0.0) ) {		/* Use scientific notation */		integer_place = DBL_DIG + EXPONENT_DIGITS + 1;		fraction_place = DBL_DIG - 1;		snprintf(work, sizeof(work),"%*.*e",			 integer_place, fraction_place, number);		after_fraction = strchr(work + DBL_DIG, 'e');	    }	    else {		/* Use regular notation */		if (absolute_value > 0.0)		    integer_place = 1 + (int)log10(absolute_value);		else		    integer_place = 0;		fraction_place = (integer_place > 0)		    ? DBL_DIG - integer_place		    : DBL_DIG;		size = snprintf(work, sizeof(work), "%0.*f",				fraction_place, number);		after_fraction = work + size;	    }	    /* Remove fractional trailing zeroes */	    ptr = after_fraction;	    while (*(--ptr) == '0')		;	    if (*ptr != '.')	        ptr++;	    while ((*ptr++ = *after_fraction++) != 0);	    /* Finally copy result back to caller */	    size = strlen(work) + 1;	    if (size > buffersize) {		work[buffersize - 1] = 0;		size = buffersize;	    }	    memmove(buffer, work, size);	}	break;    }}/************************************************************************ *									* *			Routines to handle NodeSets			* *									* ************************************************************************//** * xmlXPathOrderDocElems: * @doc:  an input document * * Call this routine to speed up XPath computation on static documents. * This stamps all the element nodes with the document order * Like for line information, the order is kept in the element->content * field, the value stored is actually - the node number (starting at -1) * to be able to differentiate from line numbers. * * Returns the number of elements found in the document or -1 in case *    of error. */longxmlXPathOrderDocElems(xmlDocPtr doc) {    long count = 0;    xmlNodePtr cur;    if (doc == NULL)	return(-1);    cur = doc->children;    while (cur != NULL) {

⌨️ 快捷键说明

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