2011-03-28 1 views
0

저는이 이상하지만 흥미로운 상황을 공유하고 싶습니다. 최근에 C++에서 XML 구문 분석에 RapidXML을 사용하려고 시도했습니다.RapidXML/C++ 클래스 포인터 부작용으로 구문 분석 할 때 재귀 문제가 발생했습니다.

특정 노드의 하위 노드 중에서 특정 노드를 검색하고 반환하는 재귀 함수를 작성하려고합니다. 내 첫 번째 시도했다 :

xml_node<>* get_child(xml_node<> *inputNode, string sNodeFilter) 
{ 
    // cycles every child 
    for (xml_node<> *nodeChild = inputNode->first_node(); nodeChild; nodeChild = nodeChild->next_sibling()) 
    { 
     if (nodeChild->name() == sNodeFilter) 
     { 
      cout << "node name " << nodeChild->name() << "\n"; 
      cout << "nodeChild " << nodeChild << endl; 
      // returns the desired child 
      return nodeChild; 
     } 
     get_child(nodeChild, sNodeFilter); 
    } 
} 

첫 번째 아이들과 함께 제대로 작동 우연히,하지만 당신은 당신의 XML 파일에 깊이 중첩 된 노드를 검색 할 경우, 노드가 발견된다 (필자는 COUT의 참조)하지만, return 문 다음에 for 순환은 재귀의 호출 스택으로 인해 하나 (또는 ​​더) 더 많은 시간을 실행 한 다음 종료되고 포인터가 손실됩니다.

그래서 내가 임시 변수와 그것을 해결하기 위해 시도,이 방법 :

xml_node<>* get_child(xml_node<> *inputNode, string sNodeFilter) 
{ 
    xml_node<> *outputNode; 
    // cycles every child 
    for (xml_node<> *nodeChild = inputNode->first_node(); nodeChild; nodeChild = nodeChild->next_sibling()) 
    { 
     if (nodeChild->name() == sNodeFilter) 
     { 
      cout << "node name " << nodeChild->name() << "\n"; 
      cout << "nodeChild " << nodeChild << endl; 
      outputNode = nodeChild; 
      cout << "outputNode " << outputNode << endl; 
      // returns the desired child 
      return outputNode; 
     } 
     get_child(nodeChild, sNodeFilter); 
    } 
} 

그러나 아무것도 변경되지 않습니다 ..

불행하게도 RapidXML에 노드

클래스 포인터이다 이러한 상황 측면 - 너무 효과은 올바른 결과를 이끌어 내지 못하게합니다.

누구나이 상황을 발견했거나 다른 방법으로이 문제를 해결 했습니까?

답변

4

재귀를 통해 아이를 찾을 때 돌려 주십시오. 당신이 아이를 찾을 수없는 경우, 나는이 직접 질문에 대답하지 않습니다 알고 0

xml_node<>* get_child(xml_node<> *inputNode, string sNodeFilter) 
{ 
    // cycles every child 
    for (xml_node<> *nodeChild = inputNode->first_node(); nodeChild; nodeChild = nodeChild->next_sibling()) 
    { 
     if (nodeChild->name() == sNodeFilter) 
     { 
      cout << "node name " << nodeChild->name() << "\n"; 
      cout << "nodeChild " << nodeChild << endl; 
      // returns the desired child 
      return nodeChild; 
     } 
     xml_node<> * x = get_child(nodeChild, sNodeFilter); 
     if (x) 
      return x; 
    } 
    return 0; 
} 
+0

나는 그것에 대해 너무 많이 생각했습니다. 당신의 솔루션이 작동합니다. :) – ascanio

1

반환,하지만 난 그것을 다른 사람을 도울 수 있기를 바랍니다 : 당신이 할 때

이 기능은 유용 어떤 부모 노드 아래에 주어진 이름을 가진 모든 노드를 재귀 적으로 검색하십시오. 그것은 결과 벡터를 반환 사용의

vector<xml_node<>*> find_nodes(xml_node<>* parent, const char* name) { 
    vector<xml_node<>*> ret; 
    if (parent != 0) { 
     if (strcmp(parent->name(), name) == 0) { 
      ret.push_back(parent); 
     } 
     for (xml_node<>* it = parent->first_node(); it != 0; it = it->next_sibling()) { 
      vector<xml_node<>*> tmp = find_nodes(it, name); 
      ret.insert(ret.end(), tmp.begin(), tmp.end()); 
     } 
    } 
    return ret; 
} 

예 : 그것은 또한 전체 문서와 함께 작동

vector<xml_node<>*> nodes = find_nodes(some_node, "link"); 

을!

xml_document<> doc; 
doc.parse<0>(str); // parse some string 

vector<xml_node<>*> nodes = find_nodes(&doc, "link"); 
관련 문제