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

XPathクエリに追加[1]して、クエリを最適化することもできます。

于 2017-05-24T09:39:57.583 に答える