这是我的C ++代码,用于执行以下操作:
我对步骤1-2如何工作非常满意,但是我觉得我可能执行得很差。我主要担心的是,我必须映射标签,即使已经匹配,例如id,当真正定义地图时,如果它不同,例如描述,那么它就是好的。
我的代码:
#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
}
}
}
}
示例输入文件:
<data>
<entry>
<id>1</id>
<content>Description</content>
<web_address>www.google.com</web_address>
<location>England</location>
<unrelated>Test</unrelated>
<not_needed>Test</not_needed>
</entry>
..
</data>
答案 0 :(得分:1)
我对第3点和第4点有两个不同的改进:
作为tagMap
的密钥使用枚举,例如
enum Tags { Tag_ID, Tag_Description, ... }
这避免了字符串比较。
定义一个抽象的基类Tag
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 */ }
};
现在您可以使用标签列表。 std::list<std::unique_ptr<Tag>> tagMap { 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());
}
}