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

📄 xpath.c

📁 Vovida 社区开源的 SIP 协议源码
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif    int i;    xmlNodeSetPtr ret;    xmlXPathTraversalFunction next = NULL;    xmlNodePtr cur = NULL;    if (ctxt->context->nodelist == NULL) {	if (ctxt->context->node == NULL) {	    fprintf(xmlXPathDebug,	     "xmlXPathNodeCollectAndTest %s:%d : nodelist and node are NULL\n",	            __FILE__, __LINE__);	    return(NULL);	}        STRANGE        return(NULL);    }#ifdef DEBUG_STEP    fprintf(xmlXPathDebug, "new step : ");#endif    switch (axis) {        case AXIS_ANCESTOR:#ifdef DEBUG_STEP	    fprintf(xmlXPathDebug, "axis 'ancestors' ");#endif	    next = xmlXPathNextAncestor; break;        case AXIS_ANCESTOR_OR_SELF:#ifdef DEBUG_STEP	    fprintf(xmlXPathDebug, "axis 'ancestors-or-self' ");#endif	    next = xmlXPathNextAncestorOrSelf; break;        case AXIS_ATTRIBUTE:#ifdef DEBUG_STEP	    fprintf(xmlXPathDebug, "axis 'attributes' ");#endif	    next = (xmlXPathTraversalFunction) xmlXPathNextAttribute; break;	    break;        case AXIS_CHILD:#ifdef DEBUG_STEP	    fprintf(xmlXPathDebug, "axis 'child' ");#endif	    next = xmlXPathNextChild; break;        case AXIS_DESCENDANT:#ifdef DEBUG_STEP	    fprintf(xmlXPathDebug, "axis 'descendant' ");#endif	    next = xmlXPathNextDescendant; break;        case AXIS_DESCENDANT_OR_SELF:#ifdef DEBUG_STEP	    fprintf(xmlXPathDebug, "axis 'descendant-or-self' ");#endif	    next = xmlXPathNextDescendantOrSelf; break;        case AXIS_FOLLOWING:#ifdef DEBUG_STEP	    fprintf(xmlXPathDebug, "axis 'following' ");#endif	    next = xmlXPathNextFollowing; break;        case AXIS_FOLLOWING_SIBLING:#ifdef DEBUG_STEP	    fprintf(xmlXPathDebug, "axis 'following-siblings' ");#endif	    next = xmlXPathNextFollowingSibling; break;        case AXIS_NAMESPACE:#ifdef DEBUG_STEP	    fprintf(xmlXPathDebug, "axis 'namespace' ");#endif	    next = (xmlXPathTraversalFunction) xmlXPathNextNamespace; break;	    break;        case AXIS_PARENT:#ifdef DEBUG_STEP	    fprintf(xmlXPathDebug, "axis 'parent' ");#endif	    next = xmlXPathNextParent; break;        case AXIS_PRECEDING:#ifdef DEBUG_STEP	    fprintf(xmlXPathDebug, "axis 'preceding' ");#endif	    next = xmlXPathNextPreceding; break;        case AXIS_PRECEDING_SIBLING:#ifdef DEBUG_STEP	    fprintf(xmlXPathDebug, "axis 'preceding-sibling' ");#endif	    next = xmlXPathNextPrecedingSibling; break;        case AXIS_SELF:#ifdef DEBUG_STEP	    fprintf(xmlXPathDebug, "axis 'self' ");#endif	    next = xmlXPathNextSelf; break;    }    if (next == NULL) return(NULL);    ret = xmlXPathNodeSetCreate(NULL);#ifdef DEBUG_STEP    fprintf(xmlXPathDebug, " context contains %d nodes\n",            ctxt->context->nodelist->nodeNr);    switch (test) {	case NODE_TEST_NONE:	    fprintf(xmlXPathDebug, "           searching for none !!!\n");	    break;	case NODE_TEST_TYPE:	    fprintf(xmlXPathDebug, "           searching for type %d\n", type);	    break;	case NODE_TEST_PI:	    fprintf(xmlXPathDebug, "           searching for PI !!!\n");	    break;	case NODE_TEST_ALL:	    fprintf(xmlXPathDebug, "           searching for *\n");	    break;	case NODE_TEST_NS:	    fprintf(xmlXPathDebug, "           searching for namespace %s\n",	            prefix);	    break;	case NODE_TEST_NAME:	    fprintf(xmlXPathDebug, "           searching for name %s\n", name);	    if (prefix != NULL)		fprintf(xmlXPathDebug, "           with namespace %s\n",		        prefix);	    break;    }    fprintf(xmlXPathDebug, "Testing : ");#endif    for (i = 0;i < ctxt->context->nodelist->nodeNr; i++) {        ctxt->context->node = ctxt->context->nodelist->nodeTab[i];	cur = NULL;	do {	    cur = next(ctxt, cur);	    if (cur == NULL) break;#ifdef DEBUG_STEP            t++;            fprintf(xmlXPathDebug, " %s", cur->name);#endif	    switch (test) {                case NODE_TEST_NONE:		    STRANGE		    return(NULL);                case NODE_TEST_TYPE:		    if ((cur->type == type) ||		        ((type == XML_ELEMENT_NODE) && 			 ((cur->type == XML_DOCUMENT_NODE) ||			  (cur->type == XML_HTML_DOCUMENT_NODE)))) {#ifdef DEBUG_STEP                        n++;#endif		        xmlXPathNodeSetAdd(ret, cur);		    }		    break;                case NODE_TEST_PI:		    if (cur->type == XML_PI_NODE) {		        if ((name != NULL) &&			    (xmlStrcmp(name, cur->name)))			    break;#ifdef DEBUG_STEP			n++;#endif			xmlXPathNodeSetAdd(ret, cur);		    }		    break;                case NODE_TEST_ALL:		    if ((cur->type == XML_ELEMENT_NODE) ||		        (cur->type == XML_ATTRIBUTE_NODE)) {			/* !!! || (cur->type == XML_TEXT_NODE)) { */#ifdef DEBUG_STEP                        n++;#endif		        xmlXPathNodeSetAdd(ret, cur);		    }		    break;                case NODE_TEST_NS: {		    TODO /* namespace search */		    break;		}                case NODE_TEST_NAME:		    switch (cur->type) {		        case XML_ELEMENT_NODE:			    if (!xmlStrcmp(name, cur->name) && 				(((prefix == NULL) ||				  ((cur->ns != NULL) && 				   (!xmlStrcmp(prefix, cur->ns->href)))))) {#ifdef DEBUG_STEP			    n++;#endif				xmlXPathNodeSetAdd(ret, cur);			    }			    break;		        case XML_ATTRIBUTE_NODE: {			    xmlAttrPtr attr = (xmlAttrPtr) cur;			    if (!xmlStrcmp(name, attr->name)) {#ifdef DEBUG_STEP			    n++;#endif				xmlXPathNodeSetAdd(ret, cur);			    }			    break;			}			default:			    break;		    }	            break;		    	    }	} while (cur != NULL);    }#ifdef DEBUG_STEP    fprintf(xmlXPathDebug,            "\nExamined %d nodes, found %d nodes at that step\n", t, n);#endif    return(ret);}/************************************************************************ *									* *		Implicit tree core function library			* *									* ************************************************************************//** * xmlXPathRoot: * @ctxt:  the XPath Parser context * * Initialize the context to the root of the document */voidxmlXPathRoot(xmlXPathParserContextPtr ctxt) {    if (ctxt->context->nodelist != NULL)        xmlXPathFreeNodeSet(ctxt->context->nodelist);    ctxt->context->node = (xmlNodePtr) ctxt->context->doc;    ctxt->context->nodelist = xmlXPathNodeSetCreate(ctxt->context->node);}/************************************************************************ *									* *		The explicit core function library			* *http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html#corelib	* *									* ************************************************************************//** * xmlXPathLastFunction: * @ctxt:  the XPath Parser context * * Implement the last() XPath function * The last function returns the number of nodes in the context node list. */voidxmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) {    CHECK_ARITY(0);    if ((ctxt->context->nodelist == NULL) ||        (ctxt->context->node == NULL) ||        (ctxt->context->nodelist->nodeNr == 0)) {	valuePush(ctxt, xmlXPathNewFloat((double) 0));    } else {	valuePush(ctxt, 	          xmlXPathNewFloat((double) ctxt->context->nodelist->nodeNr));    }}/** * xmlXPathPositionFunction: * @ctxt:  the XPath Parser context * * Implement the position() XPath function * The position function returns the position of the context node in the * context node list. The first position is 1, and so the last positionr * will be equal to last(). */voidxmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) {    int i;    CHECK_ARITY(0);    if ((ctxt->context->nodelist == NULL) ||        (ctxt->context->node == NULL) ||        (ctxt->context->nodelist->nodeNr == 0)) {	valuePush(ctxt, xmlXPathNewFloat((double) 0));    }    for (i = 0; i < ctxt->context->nodelist->nodeNr;i++) {        if (ctxt->context->node == ctxt->context->nodelist->nodeTab[i]) {	    valuePush(ctxt, xmlXPathNewFloat((double) i + 1));	    return;	}    }    valuePush(ctxt, xmlXPathNewFloat((double) 0));}/** * xmlXPathCountFunction: * @ctxt:  the XPath Parser context * * Implement the count() XPath function */voidxmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) {    xmlXPathObjectPtr cur;    CHECK_ARITY(1);    CHECK_TYPE(XPATH_NODESET);    cur = valuePop(ctxt);    valuePush(ctxt, xmlXPathNewFloat((double) cur->nodesetval->nodeNr));    xmlXPathFreeObject(cur);}/** * xmlXPathIdFunction: * @ctxt:  the XPath Parser context * * Implement the id() XPath function * The id function selects elements by their unique ID * (see [5.2.1 Unique IDs]). When the argument to id is of type node-set, * then the result is the union of the result of applying id to the * string value of each of the nodes in the argument node-set. When the * argument to id is of any other type, the argument is converted to a * string as if by a call to the string function; the string is split * into a whitespace-separated list of tokens (whitespace is any sequence * of characters matching the production S); the result is a node-set * containing the elements in the same document as the context node that * have a unique ID equal to any of the tokens in the list. */voidxmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) {    const xmlChar *tokens;    const xmlChar *cur;    xmlChar *ID;    xmlAttrPtr attr;    xmlNodePtr elem = NULL;    xmlXPathObjectPtr ret, obj;    CHECK_ARITY(1);    obj = valuePop(ctxt);    if (obj == NULL) ERROR(XPATH_INVALID_OPERAND);    if (obj->type == XPATH_NODESET) {        TODO /* ID function in case of NodeSet */    }    if (obj->type != XPATH_STRING) {        valuePush(ctxt, obj);	xmlXPathStringFunction(ctxt, 1);	obj = valuePop(ctxt);	if (obj->type != XPATH_STRING) {	    xmlXPathFreeObject(obj);	    return;	}    }    tokens = obj->stringval;    ret = xmlXPathNewNodeSet(NULL);    valuePush(ctxt, ret);    if (tokens == NULL) {	xmlXPathFreeObject(obj);        return;    }    cur = tokens;        while (IS_BLANK(*cur)) cur++;    while (*cur != 0) {	while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||	       (*cur == '.') || (*cur == '-') ||	       (*cur == '_') || (*cur == ':') || 	       (IS_COMBINING(*cur)) ||	       (IS_EXTENDER(*cur)))	       cur++;	if ((!IS_BLANK(*cur)) && (*cur != 0)) break;        ID = xmlStrndup(tokens, cur - tokens);	attr = xmlGetID(ctxt->context->doc, ID);	if (attr != NULL) {	    elem = attr->parent;            xmlXPathNodeSetAdd(ret->nodesetval, elem);        }	if (ID != NULL)	    xmlFree(ID);	while (IS_BLANK(*cur)) cur++;	tokens = cur;    }    xmlXPathFreeObject(obj);    return;}/** * xmlXPathLocalPartFunction: * @ctxt:  the XPath Parser context * * Implement the local-part() XPath function * The local-part function returns a string containing the local part * of the name of the node in the argument node-set that is first in * document order. If the node-set is empty or the first node has no * name, an empty string is returned. If the argument is omitted it * defaults to the context node. */voidxmlXPathLocalPartFunction(xmlXPathParserContextPtr ctxt, int nargs) {    xmlXPathObjectPtr cur;    CHECK_ARITY(1);    CHECK_TYPE(XPATH_NODESET);    cur = valuePop(ctxt);    if (cur->nodesetval->nodeNr == 0) {	valuePush(ctxt, xmlXPathNewCString(""));    } else {	int i = 0; /* Should be first in document order !!!!! */	valuePush(ctxt, xmlXPathNewString(cur->nodesetval->nodeTab[i]->name));    }    xmlXPathFreeObject(cur);}/** * xmlXPathNamespaceFunction: * @ctxt:  the XPath Parser context * * Implement the namespace() XPath function * The namespace function returns a string containing the namespace URI * of the expanded name of the node in the argument node-set that is * first in document order. If the node-set is empty, the first node has * no name, or the expanded name has no namespace URI, an empty string * is returned. If the argument is omitted it defaults to the context node. */voidxmlXPathNamespaceFunction(xmlXPathParserContextPtr ctxt, int nargs) {    xmlXPathObjectPtr cur;    if (nargs == 0) {        valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));	nargs = 1;    }    CHECK_ARITY(1);    CHECK_TYPE(XPATH_NODESET);    cur = valuePop(ctxt);    if (cur->nodesetval->nodeNr == 0) {	valuePush(ctxt, xmlXPathNewCString(""));    } else {	int i = 0; /* Should be first in document order !!!!! */	if (cur->nodesetval->nodeTab[i]->ns == NULL)	    valuePush(ctxt, xmlXPathNewCString(""));	else	    valuePush(ctxt, xmlXPathNewString(		      cur->nodesetval->nodeTab[i]->ns->href));    }    xmlXPathFreeObject(cur);}/** * xmlXPathNameFunction: * @ctxt:  the XPath Parser context * * Implement the name() XPath function * The name function returns a string containing a QName representing * the name of the node in the argument node-set that is first in documenti * order. The QName must represent the name with respect to the namespace * declarations in effect on the node whose name is being represented. * Typically, this will be the form in which the name occurred in the XML * source. This need not be the case if there are namespace declarations * in effect on the node that associate multiple prefixes with the same * namespace. However, an implementation may include information about * the original prefix in its representation of nodes; in this case, an * implementation can ensure that the returned string is always the same * as the QName used in the XML source. If the argument it omitted it * defaults to the context node. * Libxml keep the original prefix so the "real qualified name" used is * returned. */voidxmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {    xmlXPathObjectPtr cur;    CHECK_ARITY(1);    CHECK_TYPE(XPATH_NODESET);    cur = valuePop(ctxt);    if (cur->nodesetval->nodeNr == 0) {	valuePush(ctxt, xmlXPathNewCString(""));    } else {	int i = 0; /* Should be first

⌨️ 快捷键说明

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