]> git.sesse.net Git - xml-template/commitdiff
Add a very preliminary C++0x version. It cannot even do simple.xml correctly yet.
authorsgunderson@bigfoot.com <>
Wed, 21 Sep 2011 19:17:02 +0000 (21:17 +0200)
committersgunderson@bigfoot.com <>
Wed, 21 Sep 2011 19:17:02 +0000 (21:17 +0200)
c++0x/Makefile [new file with mode: 0644]
c++0x/simple.cpp [new file with mode: 0644]

diff --git a/c++0x/Makefile b/c++0x/Makefile
new file mode 100644 (file)
index 0000000..979a60f
--- /dev/null
@@ -0,0 +1,6 @@
+CXX=g++
+CXXFLAGS=-std=gnu++0x -g -Wall $(shell xml2-config --cflags)
+
+simple: simple.o
+       $(CXX) -o $@ $< $(shell xml2-config --libs)
+
diff --git a/c++0x/simple.cpp b/c++0x/simple.cpp
new file mode 100644 (file)
index 0000000..a5e7894
--- /dev/null
@@ -0,0 +1,87 @@
+#include <stdio.h>
+#include <string.h>
+#include <libxml/parser.h>
+
+#include <string>
+#include <utility>
+#include <unordered_map>
+
+using namespace std;
+
+class Directive {
+ public:
+       virtual void process(xmlNode *node, bool clean) = 0;
+};
+
+class Replace : public Directive {
+ public:
+       Replace(const string &str) : str(str) {}
+       virtual void process(xmlNode *node, bool clean) {
+               node->children = xmlNewTextLen(reinterpret_cast<const xmlChar *>(str.data()), str.size());
+       }
+
+ private:
+       const string str;
+};
+
+class Substitute : public Directive {
+ public:
+       Substitute(const unordered_map<string, Directive*> &substitution_map)
+               : substitution_map(substitution_map) {}
+
+       virtual void process(xmlNode *node, bool clean) {
+               for (xmlNode *child = node->children; child != NULL; child = child->next) {
+                       bool processed = false;
+
+                       if (child->type == XML_ELEMENT_NODE) {
+                               xmlElement *elem = reinterpret_cast<xmlElement *>(child);
+
+                               // Find the ID, if any.
+                               string id;
+#if 0
+                               for (xmlAttribute *attr = elem->attributes; attr != NULL; attr = attr->nexth) {
+                                       // FIXME: namespace
+                                       if (strcmp(reinterpret_cast<const char *>(attr->name), "id") != 0) {
+                                               continue;
+                                       }
+                                       id = xmlNodeGetContent(attr->content);
+                               }
+#endif
+
+                               // Check all substitutions to see if we found anything appropriate.
+                               for (auto it : substitution_map) {
+                                       if (it.first == reinterpret_cast<const char *>(child->name) ||
+                                           (!id.empty() && ("#" + it.first) == id)) {
+                                               it.second->process(child, clean);
+                                               processed = true;
+                                               break;
+                                       }
+                               }
+                       }
+                       
+                       if (!processed) {
+                               process(child, clean);
+                       }
+               }
+       }
+
+ private:
+       const unordered_map<string, Directive*> &substitution_map;
+};
+
+int main(int argc, char **argv)
+{
+       LIBXML_TEST_VERSION
+
+       unordered_map<string, Directive*> master_map;
+       master_map.insert(make_pair("title", new Replace("A very basic example")));
+       master_map.insert(make_pair("#hello", new Replace("Hello world!")));
+
+       xmlDocPtr doc = xmlParseFile(argv[1]);
+       Substitute(master_map).process(xmlDocGetRootElement(doc), false);
+       xmlSaveFile("out.xml", doc);
+
+       xmlCleanupParser();
+       xmlMemoryDump();
+       return(0);
+}