2012-10-23 2 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를 사용하기 시작 했으므로 libxml2 만 사용하고 있습니다. – SneakyMummin

답변

2

사용자의 기능이 정확합니다. 자신의 경우에 작동하지 않는 이유를 보려면 디버깅 줄을 추가하십시오. 예 :

하지만 실제로는 그 기능이 필요하지 않습니다. xmlXPathEval을 사용할 수 있습니다.

else if (node->children != NULL) { 
    xmlNodePtr intNode = findNodeByName(node->children, nodename); 
    if(intNode != NULL) { 
     return intNode; 
    } 
} 

을 그리고 @jarekczek는 XPath를 했나요 때, 그는 함수 대신 XPath를 사용하는 것을 의미

+0

좋아, 이제 XPath API를 사용해 보겠다. 기능을 사용하자마자. 감사합니다 – SneakyMummin

5
else if(node->children != NULL) { 
    node = node->children; 
    xmlNodePtr intNode = findNodeByName(node, nodename); 
    if (intNode != NULL) { 
     return intNode; 
    } 
} 

이 있어야한다.

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

참고 :이 기능은 '노드 이름'모든 노드 매칭을 반환합니다. 또한 쿼리를 최적화하기 위해 XPath 쿼리에 [1]를 추가 할 수

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

: 당신이 첫 번째 노드를 원한다면, 당신은에 의해 return xpathObj->nodesetval;을 대체 할 수있다.

0

잘 작동 :

+0

xmlStrncatNew에서 메모리 누수를 피하기 위해 코드 스 니펫에도 xmlFree (xpathExpr)가 없어야합니까? –

관련 문제