]> git.sesse.net Git - xml-template/blob - c++0x/simple.cpp
Fix namespace support for t:id in C++0x.
[xml-template] / c++0x / simple.cpp
1 #include <stdio.h>
2 #include <string.h>
3 #include <libxml/parser.h>
4
5 #include <string>
6 #include <utility>
7 #include <unordered_map>
8
9 using namespace std;
10
11 class Directive {
12  public:
13         virtual void process(xmlNode *node, bool clean) = 0;
14 };
15
16 class Replace : public Directive {
17  public:
18         Replace(const string &str) : str(str) {}
19         virtual void process(xmlNode *node, bool clean) {
20                 node->children = xmlNewTextLen(reinterpret_cast<const xmlChar *>(str.data()), str.size());
21         }
22
23  private:
24         const string str;
25 };
26
27 class Substitute : public Directive {
28  public:
29         Substitute(const unordered_map<string, Directive*> &substitution_map)
30                 : substitution_map(substitution_map) {}
31
32         virtual void process(xmlNode *node, bool clean) {
33                 for (xmlNode *child = node->children; child != NULL; child = child->next) {
34                         bool processed = false;
35
36                         if (child->type == XML_ELEMENT_NODE) {
37                                 // Find the ID, if any.
38                                 string id;
39                                 for (xmlAttr *attr = child->properties; attr != NULL; attr = attr->next) {
40                                         if (strcmp(reinterpret_cast<const char *>(attr->ns->href), "http://template.sesse.net/") == 0 &&
41                                             strcmp(reinterpret_cast<const char *>(attr->name), "id") == 0) {
42                                                 id = reinterpret_cast<const char *>(xmlNodeGetContent(attr->children));
43                                         }
44                                 }
45
46                                 // Check all substitutions to see if we found anything appropriate.
47                                 for (auto it : substitution_map) {
48                                         if (it.first == reinterpret_cast<const char *>(child->name) ||
49                                             (!id.empty() && it.first == ("#" + id))) {
50                                                 it.second->process(child, clean);
51                                                 processed = true;
52                                                 break;
53                                         }
54                                 }
55                         }
56                         
57                         if (!processed) {
58                                 process(child, clean);
59                         }
60                 }
61         }
62
63  private:
64         const unordered_map<string, Directive*> &substitution_map;
65 };
66
67 int main(int argc, char **argv)
68 {
69         LIBXML_TEST_VERSION
70
71         unordered_map<string, Directive*> master_map;
72         master_map.insert(make_pair("title", new Replace("A very basic example")));
73         master_map.insert(make_pair("#hello", new Replace("Hello world!")));
74
75         xmlDocPtr doc = xmlParseFile(argv[1]);
76         Substitute(master_map).process(xmlDocGetRootElement(doc), false);
77         xmlSaveFile("out.xml", doc);
78
79         xmlCleanupParser();
80         xmlMemoryDump();
81         return(0);
82 }