Skip to content

Instantly share code, notes, and snippets.

@mpapierski
Created May 31, 2013 18:49
Show Gist options
  • Save mpapierski/5687079 to your computer and use it in GitHub Desktop.
Save mpapierski/5687079 to your computer and use it in GitHub Desktop.
this is how libxml++ should look like
#include <iostream>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/HTMLtree.h>
struct xml_attribute
{
xmlNodePtr node_;
std::string key_;
xml_attribute(xmlNodePtr node, std::string const & key)
: node_(node)
, key_(key)
{
}
xml_attribute & operator=(std::string const & value)
{
xmlNewProp(node_, reinterpret_cast<const xmlChar *>(key_.c_str()), reinterpret_cast<const xmlChar *>(value.c_str()));
return *this;
}
};
struct dom_element
{
xmlNodePtr node_;
dom_element(const char * element_name)
: node_(xmlNewNode(NULL, reinterpret_cast<const xmlChar *>(element_name)))
{
if (!node_)
{
throw std::bad_alloc();
}
}
dom_element(dom_element const & x)
: node_(xmlCopyNode(x.node_, 1))
{
}
~dom_element()
{
if (node_)
xmlFreeNode(node_);
}
void addChild(dom_element el)
{
xmlAddChild(node_, el.node_);
el.node_ = NULL;
}
xml_attribute operator[](std::string const & key)
{
return xml_attribute(node_, key);
}
};
struct document
{
xmlDocPtr doc_;
bool isHTML5_;
document(bool isHTML5 = true)
: doc_(xmlNewDoc(NULL))
, isHTML5_(isHTML5)
{
if (!doc_)
{
throw std::bad_alloc();
}
}
document(document const & doc)
: doc_(xmlCopyDocument(doc.doc_))
, isHTML5_(doc.isHTML5_)
{
}
~document()
{
xmlFreeDoc(doc_);
}
friend std::ostream & operator<<(std::ostream & lhs, document const & doc)
{
if (doc.isHTML5_)
{
lhs << "<!doctype html>" << std::endl;
}
xmlChar * xmlbuff = NULL;
int buffersize = 0;
htmlDocDumpMemory(doc.doc_, &xmlbuff, &buffersize);
try
{
lhs << reinterpret_cast<char *>(xmlbuff);
xmlFree(xmlbuff);
} catch (...)
{
xmlFree(xmlbuff);
throw;
}
return lhs;
}
void addChild(dom_element el)
{
xmlDocSetRootElement(doc_, el.node_);
el.node_ = NULL;
}
};
int
main()
{
document doc;
dom_element html("html");
html["lang"] = "en";
dom_element head("head");
head.addChild(dom_element("title"));
html.addChild(head);
html.addChild(dom_element("body"));
doc.addChild(html);
std::cout << doc << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment