]> git.sesse.net Git - xml-template/commitdiff
Add include support, and unit test, to C++0x version. All unit tests pass!
authorsgunderson@bigfoot.com <>
Thu, 22 Sep 2011 00:11:43 +0000 (02:11 +0200)
committersgunderson@bigfoot.com <>
Thu, 22 Sep 2011 00:11:43 +0000 (02:11 +0200)
c++0x/Makefile
c++0x/include.cpp [new file with mode: 0644]
c++0x/xml-template.cpp
c++0x/xml-template.h

index 79c4024809ab25a41ad7763f1a25277c1f54f1ec..9c7cef95cee166e6594005229c18e9e53c47a0f9 100644 (file)
@@ -12,6 +12,9 @@ simple: simple.o $(LIBS)
 clone: clone.o $(LIBS)
        $(CXX) -o $@ $< $(LIBS) $(LDFLAGS)
 
+include: include.o $(LIBS)
+       $(CXX) -o $@ $< $(LIBS) $(LDFLAGS)
+
 attribute: attribute.o $(LIBS)
        $(CXX) -o $@ $< $(LIBS) $(LDFLAGS)
 
diff --git a/c++0x/include.cpp b/c++0x/include.cpp
new file mode 100644 (file)
index 0000000..546be7b
--- /dev/null
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+#include "xml-template.h"
+
+using namespace std;
+
+int main(int argc, char **argv)
+{
+       Substitute doc_directive = {
+               make_pair("color", new Replace("red")),
+       };
+       xmlDocPtr doc = process_file("../xml/included.xml", &doc_directive, false);
+
+       Substitute master_directive = {
+               make_pair("title", new Replace("Main HTML title")),
+               make_pair("h1", new Replace("Nice heading here")),
+               make_pair("contents", new ReplaceInclude(doc)),
+       };
+
+       xmlDocPtr master = process_file("../xml/master.xml", &master_directive);
+       output_to_fd_and_free(master, 1);
+       return(0);
+}
index e8fc0edb086678d12ebea5eddc04fe355478d7e9..5bbcb9b5dbeec7079a1b436118fc3f7a858eaaeb 100644 (file)
@@ -12,7 +12,8 @@ void clean_node(xmlNode *node)
        if (node->type != XML_ELEMENT_NODE) {
                return;
        }
-       if (strcmp(reinterpret_cast<const char *>(node->ns->href), "http://template.sesse.net/") == 0) {
+       if (node->ns != NULL &&
+           strcmp(reinterpret_cast<const char *>(node->ns->href), "http://template.sesse.net/") == 0) {
                xmlNode *frag = xmlNewDocFragment(node->doc);
                xmlReplaceNode(node, frag);
                frag->children = node->children;
@@ -47,6 +48,39 @@ void Replace::process(xmlNode *node, bool clean) {
 
 string Replace::get_contents() { return str; }
 
+ReplaceInclude::ReplaceInclude(xmlNodePtr included_node)
+       : included_node(included_node),
+         included_doc(NULL) {}
+       
+ReplaceInclude::ReplaceInclude(xmlDocPtr included_doc)
+       : included_node(xmlDocGetRootElement(included_doc)),
+         included_doc(included_doc) {}
+
+ReplaceInclude::~ReplaceInclude()
+{
+       if (included_doc != NULL) {
+               xmlFreeDoc(included_doc);
+       } else {
+               xmlFreeNode(included_node);
+       }
+}
+
+void ReplaceInclude::process(xmlNode *node, bool clean) {
+       xmlFreeNodeList(node->children);
+       node->content = NULL;
+       node->children = node->last = NULL; 
+
+       xmlNode *new_node;
+       xmlDOMWrapCloneNode(NULL, NULL, included_node, &new_node, node->doc, node, 1, 0);
+       xmlAddChild(node, new_node);
+
+       if (clean) {
+               Substitute dummy_subs {};
+               dummy_subs.process(new_node, clean);
+               clean_node(node);
+       }
+}
+
 Clone::Clone(const vector<Directive *> &subdirectives)
        : subdirectives(subdirectives) {}
 
@@ -197,12 +231,13 @@ void Substitute::process(xmlNode *node, bool clean)
 }
        
 xmlDocPtr process_file(const string &input_filename,
-                       Directive *root_directive)
+                       Directive *root_directive,
+                       bool clean)
 {
        LIBXML_TEST_VERSION
 
        xmlDocPtr doc = xmlParseFile(input_filename.c_str());
-       root_directive->process(xmlDocGetRootElement(doc), true);
+       root_directive->process(xmlDocGetRootElement(doc), clean);
        xmlCleanupParser();
        xmlMemoryDump();
        return doc;
index 35671869868cb35d662250b9c0a5546df6373f5b..7cfa0d8dc1a3de85ffc2fdae41e3d41108dc1062 100644 (file)
@@ -25,6 +25,18 @@ class Replace : public Directive {
        const std::string str;
 };
 
+class ReplaceInclude : public Directive {
+ public:
+       ReplaceInclude(xmlNodePtr included_node);
+       ReplaceInclude(xmlDocPtr included_doc);
+       ~ReplaceInclude();
+       virtual void process(xmlNode *node, bool clean);
+
+ private:
+       xmlNodePtr included_node;
+       xmlDocPtr included_doc;
+};
+
 class Substitute;
 
 class Clone : public Directive {
@@ -60,7 +72,8 @@ class Alternate : public Clone {
 };
 
 xmlDocPtr process_file(const std::string &input_filename,
-                       Directive *root_directive);
+                       Directive *root_directive,
+                       bool clean = true);
        
 void output_to_fd_and_free(xmlDocPtr doc, int fd);