如何使用C++解析指定XML数据并将关联信息存入std::unordered_map
解决方案
你可以使用轻量的C++ XML解析库pugixml来完成需求,不建议手动用正则匹配XML结构,避免特殊字符、属性顺序变化导致解析出错。
步骤说明
- 第一步:引入pugixml库,它是单头文件无依赖的库,直接将pugixml.hpp、pugixml.cpp加入项目即可使用。
- 第二步:遍历所有
<way>节点,每处理一个way时先提取它的id,再收集该节点下所有<tag>的k、v属性,拼接成目标字符串的公共部分。 - 第三步:遍历当前way下所有
<nd>节点,取出ref属性的整数值,找到uMapID_feats中对应的条目,将拼接好的字符串赋值给它。
完整代码示例
#include <iostream> #include <unordered_map> #include <string> #include "pugixml.hpp" int main() { // 你的预定义映射 std::unordered_map<int, std::string> uMapID_feats{}; // 这里省略你预先填充所有ref ID的逻辑 // 加载XML文件 pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file("你的文件路径.osm"); if (!result) { std::cerr << "XML加载失败: " << result.description() << std::endl; return -1; } // 遍历所有way节点 for (pugi::xml_node way_node : doc.child("create").children("way")) { // 提取way的id std::string way_id = way_node.attribute("id").as_string(); std::string value_str = way_id; // 先收集所有tag的k,再收集所有v(匹配你给出的示例格式) std::string k_list, v_list; for (pugi::xml_node tag_node : way_node.children("tag")) { if (!k_list.empty()) k_list += ","; k_list += tag_node.attribute("k").as_string(); if (!v_list.empty()) v_list += ","; v_list += tag_node.attribute("v").as_string(); } if (!k_list.empty()) { value_str += "," + k_list + "," + v_list; } // 遍历当前way下所有nd节点,更新映射 for (pugi::xml_node nd_node : way_node.children("nd")) { int ref_id = nd_node.attribute("ref").as_int(); // 只更新映射中已存在的ID if (uMapID_feats.count(ref_id)) { uMapID_feats[ref_id] = value_str; } } } // 测试输出示例 if (uMapID_feats.count(-106862)) { std::cout << "-106862对应的值: " << uMapID_feats[-106862] << std::endl; } return 0; }
注意事项
- 如果你需要调整tag的拼接顺序,比如改为
k1,v1,k2,v2的格式,只需要修改收集tag部分的代码即可。 - 如果同一个ref ID出现在多个way节点下,代码默认会用最后遍历到的way的信息覆盖旧值,你可以根据业务需求判断要不要跳过已赋值的条目。
- 如果ref的数值超出int范围,可以把映射的key改为
long long类型避免溢出。
内容的提问来源于stack exchange,提问作者Megan Darcy
相关产品推荐
相关产品推荐

