2012-10-23 105 views
2

我正在嘗試編寫一個函數,該函數將在xml文件中查找具有指定名稱的節點。 問題是該函數從未找到指定的節點。使用libxml2查找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。

在此先感謝。

+1

是否有您沒有使用XPath API的原因? – apmasell

+0

不,沒有理由:)我剛開始使用libxml2,所以我只是在玩它。 – SneakyMummin

回答

2

您的功能是正確的。添加一個調試行,看看爲什麼它不起作用。例如:

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

但是你並不真的需要這個功能。您可以使用xmlXPathEval

+0

好吧,我要嘗試XPath API,然後......只要我的功能正常工作;)。謝謝 – SneakyMummin

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

,它工作正常

0

當@jarekczek mentionned的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; 
} 

注:該函數返回的所有節點匹配的 '節點名稱'。如果你只想要第一個節點,您可以通過更換return xpathObj->nodesetval;

if (xpathObj->nodesetval->nodeNr > 0) { 
    return xpathObj->nodesetval->nodeTab[0]; 
} else { 
    return NULL; 
} 

你還可以追加[1]的XPath查詢,以優化查詢。

+0

不應該代碼片段也有xmlFree(xpathExpr),以避免從xmlStrncatNew內存泄漏? –

相關問題