我正在尝试编写一个函数,该函数将在xml文件中找到具有指定名称的节点。 问题是该函数永远不会找到指定的节点。
xmlNodePtr findNodeByName(xmlNodePtr rootnode, const xmlChar * nodename)
{
xmlNodePtr node = rootnode;
if(node == NULL){
log_err("Document is empty!");
return NULL;
}
while(node != NULL){
if(!xmlStrcmp(node->name, nodename)){
return node;
}
else if(node->children != NULL){
node = node->children;
xmlNodePtr intNode = findNodeByName(node, nodename);
if(intNode != NULL){
return intNode;
}
}
node = node->next;
}
return NULL;
}
我可以在调试器中看到函数确实深入到子节点但仍然返回NULL。
提前致谢。
答案 0 :(得分:8)
else if(node->children != NULL) {
node = node->children;
xmlNodePtr intNode = findNodeByName(node, nodename);
if (intNode != NULL) {
return intNode;
}
}
这应该是:
else if (node->children != NULL) {
xmlNodePtr intNode = findNodeByName(node->children, nodename);
if(intNode != NULL) {
return intNode;
}
}
并且工作正常
答案 1 :(得分:4)
你的功能是正确的。添加调试行以查看它在您的情况下不起作用的原因。例如:
printf("xmlStrcmp(%s, %s)==%d\n", node->name, nodename,
xmlStrcmp(node->name, nodename));
但你真的不需要那个功能。您可以使用xmlXPathEval。
答案 2 :(得分:-1)
当@jarekczek提到XPath时,他意味着使用XPath而不是你的功能。
使用XPath,您的功能将变为:
xmlNodeSetPtr findNodesByName(xmlDocPtr doc, xmlNodePtr rootnode, const xmlChar* nodename) {
// Create xpath evaluation context
xmlXPathContextPtr xpathCtx = xmlXPathNewContext(doc);
if(xpathCtx == NULL) {
fprintf(stderr,"Error: unable to create new XPath context\n");
return NULL;
}
// The prefix './/' means the nodes will be selected from the current node
const xmlChar* xpathExpr = xmlStrncatNew(".//", nodename, -1);
xmlXPathObjectPtr xpathObj = xmlXPathNodeEval(rootnode, xpathExpr, xpathCtx);
if(xpathObj == NULL) {
fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", xpathExpr);
xmlXPathFreeContext(xpathCtx);
return NULL;
}
xmlXPathFreeContext(xpathCtx);
return xpathObj->nodesetval;
}
注意:此函数返回与'nodename'匹配的所有节点。如果您只想要第一个节点,则可以将return xpathObj->nodesetval;
替换为:
if (xpathObj->nodesetval->nodeNr > 0) {
return xpathObj->nodesetval->nodeTab[0];
} else {
return NULL;
}
您还可以将[1]
附加到XPath查询以优化查询。