0

我以一种非常糟糕的方式使用 rapidXML 获取配置文件的值。

xml_document<> doc;
doc.parse<parse_full>(buffer);
int a = atoi(doc.first_node("master")->first_node("profile")->first_node("width")->value());

如果节点不存在“first_node”返回0,那么“->value()”会崩溃。返回一个新的 xml_node 将修复崩溃,但是内存泄漏呢?

这是 rapidXML 与新旧返回的功能:

    xml_node<Ch> *first_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const
    {
        if (name)
        {
            if (name_size == 0)
                name_size = internal::measure(name);
            for (xml_node<Ch> *child = m_first_node; child; child = child->next_sibling())
                if (internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive))
                    return child;
            return new xml_node<Ch>(node_document);
            //return 0;
        }
        else
            return m_first_node;
    }
4

2 回答 2

0

您应该使用异常,例如:

int a;
try
{
    xml_document<> doc;
    doc.parse<parse_full>(buffer);
    a = atoi(doc.first_node("master")->first_node("profile")->first_node("width")->value());
}
catch(NodeNotExists &ex)
{
    // process error condition
}

此外,如果不想更改 rapidxml 代码,请使用如下包装函数:

template<typename T>
T* notnull(T* arg)
{
    if (arg == 0)
        throw NodeNotExists();
    return arg;
}
于 2012-11-06T15:13:19.740 回答
0

扩展仇恨引擎的答案,我创建了一类静态辅助函数来通过包装节点值访问来处理这种情况。在这里查看我的答案。您可以在此基础上进行扩展或追求更多类似 xpath 样式的节点访问(我不相信目前是 RapidXML 内置的,但其他人则这样做)。

编辑:您可以创建一个包装器函数,它采用简单的类似 xpath 的路径,并将其与我的一个包装器结合起来,得到类似...

int a = GetNodeInt(GetFirstNodePath(doc, "master/profile/width"), 0);

GetNodeInt 和 GetFirstNodePath 的定义如下...

    int GetNodeInt(rapidxml::xml_base<>* node, int DefaultValue)
    {
        int temp;
        try
        {
            if (node == 0) return DefaultValue;
            if (sscanf(node->value(), "%d", &temp) != 1) return DefaultValue;
            return temp;
        }
        catch (...) { return DefaultValue; }
    }

    // Find node with simple path from current node such as "first/second/third"
    rapidxml::xml_node<>* GetFirstNodePath(rapidxml::xml_node<>* root, const char *path)
    {
        xml_node<>* node = root;
        char* last = (char*)path; // only using this pointer to read
        char* cur = last;
        if (cur == 0 || root == 0) return 0;
        while (node)
        {
            if (*cur == '/' || *cur == 0)
            {
                if (cur != last) node = node->first_node(last,cur-last);
                if (*cur == 0) break;
                last = cur + 1;
            }
            ++cur;
        }
        return node;
    }

现在这段代码还没有经过彻底的测试,但给了你大致的想法。

于 2013-10-24T15:48:41.870 回答