使用 pugiXML 根据 std::map 重命名节点

2022-01-10 00:00:00 xml xml-parsing c++ c++11 pugixml

我是 C++ 新手,但我正在尝试定义一组标准的节点名称,然后映射到它们.

I'm new to C++ but I am trying to define a standard set of node names and then map to them.

例如我的标准导入/输出模式是这样的:

For example my standard import / output schema is this:

<data>
<entry>
<id>1</id>
<description>Test</description>
</entry>
</data>

但是有时我的 XML 导入会被命名不同,所以我想创建一个映射,以便它仍然以上述格式输出,即使输入文件具有此命名约定:

However sometimes my XML import will be named differently so I want to create a map so it still outputs in the above format, even if the input file has this naming convention:

<data>
<entry>
<id>1</id>
<content>Test</content>
</entry>
</data>

此代码是我根据文档和获得的帮助得出的最佳猜测,但我一直在尝试完成它:

This code is my best guess based on the documentation and help I've got, but I have got stuck in trying to complete it:

#include "pugi/pugixml.hpp"

#include <iostream>
#include <string>
#include <map>

int main()
{

    // Define mappings, default left - map on the right
    const std::map<std::string, std::string> tagmaps
    {
          {"id", "id"}
        , {"description", "content"}
    };

    pugi::xml_document doca, docb;
    std::map<std::string, pugi::xml_node> mapa, mapb;

    for (auto& node: doca.child("data").children("entry")) {
        const char* id = node.child_value("id");
        mapa[id] = node;
    }

    for (auto& node: docb.child("data").children("entry")) {
        const char* idcs = node.child_value("id");
        if (!mapa.erase(idcs)) {
            mapb[idcs] = node;
        }
    }

    for (auto& eb: mapb) {
        // change node name if mapping found
        if((found = tagmaps.find(n.name())) != tagmaps.end()) {
            n.set_name(found->second.c_str());
        }

    }

}

此代码理想情况下允许 xml 以任何一种方式格式化,但始终输出相同.任何帮助将非常感激.上面的代码给了我以下错误:

This code would ideally allow the xml to be formatted either way but always output the same. Any help would be really appreciated. The code above gives me the following errors:

src/main.cpp:34:13: error: use of undeclared identifier 'found'
        if((found = tagmaps.find(n.name())) != tagmaps.end()) {
            ^
src/main.cpp:34:34: error: use of undeclared identifier 'n'
        if((found = tagmaps.find(n.name())) != tagmaps.end()) {
                                 ^
src/main.cpp:35:13: error: use of undeclared identifier 'n'
            n.set_name(found->second.c_str());
            ^
src/main.cpp:35:24: error: use of undeclared identifier 'found'
            n.set_name(found->second.c_str());
                       ^

推荐答案

变量 foundn 永远不会被声明.在该循环之前将这些变量声明为适当的类型,以便该部分代码如下所示:

The variables found and n are never declared. Declare those variables as the appropriate type before that loop so that section of code looks like:

稍微改动了代码,if语句在设置后应该检查found的值.

changed the code slightly, the if statement should check the value of found after it has been set.

pugi::xml_node found, n;

for (auto& eb: mapb) {
    // change node name if mapping found
    found = tagmaps.find(n.name());
    if((found != tagmaps.end()) {
        n.set_name(found->second.c_str());
    }
}

另外,我认为 n 应该设置为循环内的特定节点(目前它没有值).考虑将 n 重命名为其他名称,以明确该变量应包含的内容.

Also, I presume n should be set to a particular node inside the loop (at the moment it has no value). Consider renaming n to something else to make it apparent what this variable should be holding.

相关文章