3

我正在尝试编写一个函数,该函数将在 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。

提前致谢。

4

3 回答 3

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;
    }
}

它工作正常

于 2014-11-07T12:05:46.053 回答
3

你的功能是正确的。添加调试行以查看为什么它在您的情况下不起作用。例如:

    printf("xmlStrcmp(%s, %s)==%d\n", node->name, nodename,
        xmlStrcmp(node->name, nodename));

但你并不真的需要那个功能。您可以使用xmlXPathEval

于 2012-10-23T06:20:01.630 回答
-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 查询以优化您的查询。

于 2017-05-24T09:39:57.583 回答