避免C+的冗余映射+;程序 这是我的C++代码,它的意思是做如下:< /P> 比较一组XML文件,看看它们之间有什么不同 如果节点是新的,则转储它(在B.xml中,但不是在A.xml中) 扫描该节点并使用map将标记与信息类型关联 根据数据的类型处理数据
我对第1-2步的工作方式很满意,但是第3-4步我觉得我可能执行得很差。我主要关心的是,即使已经匹配了标记(如id),我也必须映射标记,而实际上,只有当映射不同(如描述)时,才最好定义一个映射 我的代码:避免C+的冗余映射+;程序 这是我的C++代码,它的意思是做如下:< /P> 比较一组XML文件,看看它们之间有什么不同 如果节点是新的,则转储它(在B.xml中,但不是在A.xml中) 扫描该节点并使用map将标记与信息类型关联 根据数据的类型处理数据,c++,xml,c++11,xml-parsing,C++,Xml,C++11,Xml Parsing,我对第1-2步的工作方式很满意,但是第3-4步我觉得我可能执行得很差。我主要关心的是,即使已经匹配了标记(如id),我也必须映射标记,而实际上,只有当映射不同(如描述)时,才最好定义一个映射 我的代码: #include "pugi/pugixml.hpp" #include <iostream> #include <string> #include <map> int main() { // This map relates the type
#include "pugi/pugixml.hpp"
#include <iostream>
#include <string>
#include <map>
int main()
{
// This map relates the type of content to the tag name in the XML file
const std::map<std::string, std::string> tagMap {
{"id", "id"}, {"description", "content"}, {"url", "web_address"}, {"location", "location"}
};
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 added nodes
for (auto& eb: mapb) {
// Loop through Tag map to see if we can find tags named "id, content, web_address or location" in the node returned
for (auto& kv : tagMap) {
// For each result, assign the value of that tag to the type of content
// For example: description = Testing!
kv.first = eb.second.child_value(kv.second.c_str());
// If it's an ID...
if (kv.first == "id") {
// Do work on ID value (i.e check if it's unique)
}
if (kv.first == "description") {
// Do work on Description data (I.e Trim it)
}
if (kv.first == "url") {
// Do work on URL data (I.e validate it)
}
if (kv.first == "location") {
// Do work on location data
}
}
}
}
#包括“pugi/pugixml.hpp”
#包括
#包括
#包括
int main()
{
//此映射将内容类型与XML文件中的标记名相关联
const std::map标记映射{
{“id”,“id”},{“description”,“content”},{“url”,“web_address”},{“location”,“location”}
};
pugi::xml_文档doca,docb;
标准::map mapa,mapb;
用于(自动和节点:doca.child(“数据”).children(“条目”)){
const char*id=node.child_值(“id”);
mapa[id]=节点;
}
用于(自动和节点:docb.child(“数据”).children(“条目”)){
const char*idcs=node.child_值(“id”);
如果(!mapa.erase(idcs)){
mapb[idcs]=节点;
}
}
//对于添加的节点
用于(自动和eb:mapb){
//循环遍历标记映射,查看是否可以在返回的节点中找到名为“id、内容、web\u地址或位置”的标记
用于(自动和kv:tagMap){
//对于每个结果,将该标记的值指定给内容类型
//例如:描述=测试!
kv.first=eb.second.child_值(kv.second.c_str());
//如果是身份证。。。
如果(千伏第一==“id”){
//处理ID值(即检查其是否唯一)
}
如果(kv.first==“说明”){
//处理描述数据(即修剪)
}
如果(kv.first==“url”){
//处理URL数据(即验证它)
}
如果(kv.first==“位置”){
//处理位置数据
}
}
}
}
输入文件示例:
1.
描述
www.google.com
英格兰
试验
试验
..
我对您的第3点和第4点有两种不同的改进:
标记映射的键
使用枚举,例如
enum Tags { Tag_ID, Tag_Description, ... }
这避免了字符串比较
标记
class Tag {
public:
virtual const char* getTagname() const = 0;
virtual void processNode(const std::string& value) = 0;
};
然后为每个标记实现一个子类
class IdTag : public Tag {
public:
const char* getTagname() const { return "Id"; }
void processNode(const std::string& value) { /* Do something */ }
};
现在您可以使用标记列表<代码>标准::列表标记映射{new IdTag(),new DescriptionTag(),…}代码>
您的新循环:
// For added nodes
for (auto& eb: mapb) {
// Loop through Tag map to see if we can find tags named "id, content, web_address or location" in the node returned
for (auto& kv : tagMap) {
kv->processNode(eb.second.child_value(kv->getTagname());
}
}
我投票结束这个问题,因为这个问题属于@Barry,我刚被告知把它移到这里谢谢你的回答。关于您的示例,我不了解的是,如何将枚举与内容关联起来。例如,定义“content”是一个标记已经足够公平了,但是我如何说content标记是一个描述呢?您可以使用与代码中相同的循环。枚举只是替换字符串。