2011-03-28 14 views
0

我想分享一下当我试图在C++中使用RapidXML进行XML解析时偶然发现的奇怪但有趣的情况。使用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 2011-03-28 21:46:46

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");