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

📄 xpath.c.svn-base

📁 这是一个用于解析xml文件的类库。使用这个类库
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
xmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) {    int depth1, depth2;    int attr1 = 0, attr2 = 0;    xmlNodePtr attrNode1 = NULL, attrNode2 = NULL;    xmlNodePtr cur, root;    if ((node1 == NULL) || (node2 == NULL))	return(-2);    /*     * a couple of optimizations which will avoid computations in most cases     */    if (node1->type == XML_ATTRIBUTE_NODE) {	attr1 = 1;	attrNode1 = node1;	node1 = node1->parent;    }    if (node2->type == XML_ATTRIBUTE_NODE) {	attr2 = 1;	attrNode2 = node2;	node2 = node2->parent;    }    if (node1 == node2) {	if (attr1 == attr2) {	    /* not required, but we keep attributes in order */	    if (attr1 != 0) {	        cur = attrNode2->prev;		while (cur != NULL) {		    if (cur == attrNode1)		        return (1);		    cur = cur->prev;		}		return (-1);	    }	    return(0);	}	if (attr2 == 1)	    return(1);	return(-1);    }    if ((node1->type == XML_NAMESPACE_DECL) ||        (node2->type == XML_NAMESPACE_DECL))	return(1);    if (node1 == node2->prev)	return(1);    if (node1 == node2->next)	return(-1);    /*     * Speedup using document order if availble.     */    if ((node1->type == XML_ELEMENT_NODE) &&	(node2->type == XML_ELEMENT_NODE) &&	(0 > (long) node1->content) &&	(0 > (long) node2->content) &&	(node1->doc == node2->doc)) {	long l1, l2;	l1 = -((long) node1->content);	l2 = -((long) node2->content);	if (l1 < l2)	    return(1);	if (l1 > l2)	    return(-1);    }    /*     * compute depth to root     */    for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {	if (cur == node1)	    return(1);	depth2++;    }    root = cur;    for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {	if (cur == node2)	    return(-1);	depth1++;    }    /*     * Distinct document (or distinct entities :-( ) case.     */    if (root != cur) {	return(-2);    }    /*     * get the nearest common ancestor.     */    while (depth1 > depth2) {	depth1--;	node1 = node1->parent;    }    while (depth2 > depth1) {	depth2--;	node2 = node2->parent;    }    while (node1->parent != node2->parent) {	node1 = node1->parent;	node2 = node2->parent;	/* should not happen but just in case ... */	if ((node1 == NULL) || (node2 == NULL))	    return(-2);    }    /*     * Find who's first.     */    if (node1 == node2->prev)	return(1);    if (node1 == node2->next)	return(-1);    /*     * Speedup using document order if availble.     */    if ((node1->type == XML_ELEMENT_NODE) &&	(node2->type == XML_ELEMENT_NODE) &&	(0 > (long) node1->content) &&	(0 > (long) node2->content) &&	(node1->doc == node2->doc)) {	long l1, l2;	l1 = -((long) node1->content);	l2 = -((long) node2->content);	if (l1 < l2)	    return(1);	if (l1 > l2)	    return(-1);    }    for (cur = node1->next;cur != NULL;cur = cur->next)	if (cur == node2)	    return(1);    return(-1); /* assume there is no sibling list corruption */}/** * xmlXPathNodeSetSort: * @set:  the node set * * Sort the node set in document order */voidxmlXPathNodeSetSort(xmlNodeSetPtr set) {    int i, j, incr, len;    xmlNodePtr tmp;    if (set == NULL)	return;    /* Use Shell's sort to sort the node-set */    len = set->nodeNr;    for (incr = len / 2; incr > 0; incr /= 2) {	for (i = incr; i < len; i++) {	    j = i - incr;	    while (j >= 0) {		if (xmlXPathCmpNodes(set->nodeTab[j],				     set->nodeTab[j + incr]) == -1) {		    tmp = set->nodeTab[j];		    set->nodeTab[j] = set->nodeTab[j + incr];		    set->nodeTab[j + incr] = tmp;		    j -= incr;		} else		    break;	    }	}    }}#define XML_NODESET_DEFAULT	10/** * xmlXPathNodeSetDupNs: * @node:  the parent node of the namespace XPath node * @ns:  the libxml namespace declaration node. * * Namespace node in libxml don't match the XPath semantic. In a node set * the namespace nodes are duplicated and the next pointer is set to the * parent node in the XPath semantic. * * Returns the newly created object. */static xmlNodePtrxmlXPathNodeSetDupNs(xmlNodePtr node, xmlNsPtr ns) {    xmlNsPtr cur;    if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL))	return(NULL);    if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))	return((xmlNodePtr) ns);    /*     * Allocate a new Namespace and fill the fields.     */    cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));    if (cur == NULL) {        xmlXPathErrMemory(NULL, "duplicating namespace\n");	return(NULL);    }    memset(cur, 0, sizeof(xmlNs));    cur->type = XML_NAMESPACE_DECL;    if (ns->href != NULL)	cur->href = xmlStrdup(ns->href);     if (ns->prefix != NULL)	cur->prefix = xmlStrdup(ns->prefix);     cur->next = (xmlNsPtr) node;    return((xmlNodePtr) cur);}/** * xmlXPathNodeSetFreeNs: * @ns:  the XPath namespace node found in a nodeset. * * Namespace nodes in libxml don't match the XPath semantic. In a node set * the namespace nodes are duplicated and the next pointer is set to the * parent node in the XPath semantic. Check if such a node needs to be freed */voidxmlXPathNodeSetFreeNs(xmlNsPtr ns) {    if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL))	return;    if ((ns->next != NULL) && (ns->next->type != XML_NAMESPACE_DECL)) {	if (ns->href != NULL)	    xmlFree((xmlChar *)ns->href);	if (ns->prefix != NULL)	    xmlFree((xmlChar *)ns->prefix);	xmlFree(ns);    }}/** * xmlXPathNodeSetCreate: * @val:  an initial xmlNodePtr, or NULL * * Create a new xmlNodeSetPtr of type double and of value @val * * Returns the newly created object. */xmlNodeSetPtrxmlXPathNodeSetCreate(xmlNodePtr val) {    xmlNodeSetPtr ret;    ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));    if (ret == NULL) {        xmlXPathErrMemory(NULL, "creating nodeset\n");	return(NULL);    }    memset(ret, 0 , (size_t) sizeof(xmlNodeSet));    if (val != NULL) {        ret->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *					     sizeof(xmlNodePtr));	if (ret->nodeTab == NULL) {	    xmlXPathErrMemory(NULL, "creating nodeset\n");	    xmlFree(ret);	    return(NULL);	}	memset(ret->nodeTab, 0 ,	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));        ret->nodeMax = XML_NODESET_DEFAULT;	if (val->type == XML_NAMESPACE_DECL) {	    xmlNsPtr ns = (xmlNsPtr) val;	    ret->nodeTab[ret->nodeNr++] =		xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);	} else	    ret->nodeTab[ret->nodeNr++] = val;    }    return(ret);}/** * xmlXPathNodeSetContains: * @cur:  the node-set * @val:  the node * * checks whether @cur contains @val * * Returns true (1) if @cur contains @val, false (0) otherwise */intxmlXPathNodeSetContains (xmlNodeSetPtr cur, xmlNodePtr val) {    int i;    if (val->type == XML_NAMESPACE_DECL) {	for (i = 0; i < cur->nodeNr; i++) {	    if (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) {		xmlNsPtr ns1, ns2;		ns1 = (xmlNsPtr) val;		ns2 = (xmlNsPtr) cur->nodeTab[i];		if (ns1 == ns2)		    return(1);		if ((ns1->next != NULL) && (ns2->next == ns1->next) &&	            (xmlStrEqual(ns1->prefix, ns2->prefix)))		    return(1);	    }	}    } else {	for (i = 0; i < cur->nodeNr; i++) {	    if (cur->nodeTab[i] == val)		return(1);	}    }    return(0);}/** * xmlXPathNodeSetAddNs: * @cur:  the initial node set * @node:  the hosting node * @ns:  a the namespace node * * add a new namespace node to an existing NodeSet */voidxmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {    int i;    if ((ns == NULL) || (node == NULL) || (ns->type != XML_NAMESPACE_DECL) ||	(node->type != XML_ELEMENT_NODE))	return;    /* @@ with_ns to check whether namespace nodes should be looked at @@ */    /*     * prevent duplicates     */    for (i = 0;i < cur->nodeNr;i++) {        if ((cur->nodeTab[i] != NULL) &&	    (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) &&	    (((xmlNsPtr)cur->nodeTab[i])->next == (xmlNsPtr) node) &&	    (xmlStrEqual(ns->prefix, ((xmlNsPtr)cur->nodeTab[i])->prefix)))	    return;    }    /*     * grow the nodeTab if needed     */    if (cur->nodeMax == 0) {        cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *					     sizeof(xmlNodePtr));	if (cur->nodeTab == NULL) {	    xmlXPathErrMemory(NULL, "growing nodeset\n");	    return;	}	memset(cur->nodeTab, 0 ,	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));        cur->nodeMax = XML_NODESET_DEFAULT;    } else if (cur->nodeNr == cur->nodeMax) {        xmlNodePtr *temp;        cur->nodeMax *= 2;	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *				      sizeof(xmlNodePtr));	if (temp == NULL) {	    xmlXPathErrMemory(NULL, "growing nodeset\n");	    return;	}	cur->nodeTab = temp;    }    cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns);}/** * xmlXPathNodeSetAdd: * @cur:  the initial node set * @val:  a new xmlNodePtr * * add a new xmlNodePtr to an existing NodeSet */voidxmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {    int i;    if (val == NULL) return;#if 0    if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' '))	return;	/* an XSLT fake node */#endif    /* @@ with_ns to check whether namespace nodes should be looked at @@ */    /*     * prevent duplcates     */    for (i = 0;i < cur->nodeNr;i++)        if (cur->nodeTab[i] == val) return;    /*     * grow the nodeTab if needed     */    if (cur->nodeMax == 0) {        cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *					     sizeof(xmlNodePtr));	if (cur->nodeTab == NULL) {	    xmlXPathErrMemory(NULL, "growing nodeset\n");	    return;	}	memset(cur->nodeTab, 0 ,	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));        cur->nodeMax = XML_NODESET_DEFAULT;    } else if (cur->nodeNr == cur->nodeMax) {        xmlNodePtr *temp;        cur->nodeMax *= 2;	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *				      sizeof(xmlNodePtr));	if (temp == NULL) {	    xmlXPathErrMemory(NULL, "growing nodeset\n");	    return;	}	cur->nodeTab = temp;    }    if (val->type == XML_NAMESPACE_DECL) {	xmlNsPtr ns = (xmlNsPtr) val;	cur->nodeTab[cur->nodeNr++] = 	    xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);    } else	cur->nodeTab[cur->nodeNr++] = val;}/** * xmlXPathNodeSetAddUnique: * @cur:  the initial node set * @val:  a new xmlNodePtr * * add a new xmlNodePtr to an existing NodeSet, optimized version * when we are sure the node is not already in the set. */voidxmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {    if (val == NULL) return;#if 0    if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' '))	return;	/* an XSLT fake node */#endif    /* @@ with_ns to check whether namespace nodes should be looked at @@ */    /*     * grow the nodeTab if needed     */    if (cur->nodeMax == 0) {        cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *					     sizeof(xmlNodePtr));	if (cur->nodeTab == NULL) {	    xmlXPathErrMemory(NULL, "growing nodeset\n");	    return;	}	memset(cur->nodeTab, 0 ,	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));        cur->nodeMax = XML_NODESET_DEFAULT;    } else if (cur->nodeNr == cur->nodeMax) {        xmlNodePtr *temp;        cur->nodeMax *= 2;	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *				      sizeof(xmlNodePtr));	if (temp == NULL) {	    xmlXPathErrMemory(NULL, "growing nodeset\n");	    return;	}	cur->nodeTab = temp;    }    if (val->type == XML_NAMESPACE_DECL) {	xmlNsPtr ns = (xmlNsPtr) val;	cur->nodeTab[cur->nodeNr++] = 	    xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);    } else	cur->nodeTab[cur->nodeNr++] = val;}/** * xmlXPathNodeSetMerge: * @val1:  the first NodeSet or NULL * @val2:  the second NodeSet * * Merges two nodesets, all nodes from @val2 are added to @val1 * if @val1 is NULL, a new set is created and copied from @val2 * * Returns @val1 once extended or NULL in case of error. */xmlNodeSetPtrxmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {    int i, j, initNr, skip;    if (val2 == NULL) return(val1);    if (val1 == NULL) {	val1 = xmlXPathNodeSetCreate(NULL);    }    /* @@ with_ns to check whether namespace nodes should be looked at @@ */    initNr = val1->nodeNr;    for (i = 0;i < val2->nodeNr;i++) {	/*	 * check against duplicates	 */	skip = 0;	for (j = 0; j < initNr; j++) {	    if (val1->nodeTab[j] == val2->nodeTab[i]) {		skip = 1;		break;	    } else if ((val1->nodeTab[j]->type == XML_NAMESPACE_DECL) &&		       (val2->nodeTab[i]->type == XML_NAMESPACE_DECL)) {

⌨️ 快捷键说明

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