0

我想分享一下我最近在尝试使用 RapidXML 在 C++ 中进行 XML 解析时偶然发现的这个奇怪但有趣的情况。

我想编写一个递归函数来搜索并返回给定节点的子节点中的特定节点。我的第一次尝试是:

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

2 回答 2

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;
}
于 2011-03-28T21:27:50.053 回答
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");
于 2014-11-24T13:37:12.067 回答