Skip to content

Instantly share code, notes, and snippets.

@goldsborough
Created October 17, 2015 23:47
Show Gist options
  • Save goldsborough/07ecacbf35ace741a539 to your computer and use it in GitHub Desktop.
Save goldsborough/07ecacbf35ace741a539 to your computer and use it in GitHub Desktop.
Compresses XML to a more compact representation.
template<typename Node>
class XMLCompressor
{
public:
using map_t = std::map<std::string, std::string>;
static map_t global_keywords;
std::string operator()(Node* node, map_t& keywords = global_keywords)
{
std::string string;
_compress(node, string, keywords);
string.pop_back();
return string;
}
private:
void _compress(Node* node, std::string& string, map_t& keywords)
{
if (! node) return;
string += keywords.at(node->tag) + " ";
for (const auto& attribute : node->attributes)
{
string += keywords.at(attribute.first) + " ";
string += attribute.second + " ";
}
string += "0 ";
if (! node->data.empty())
{
string += node->data + " ";
}
for (const auto& child : node->children)
{
_compress(child, string, keywords);
}
string += "0 ";
}
};
template<typename Node>
typename XMLCompressor<Node>::map_t XMLCompressor<Node>::global_keywords = {
{"family", "1"},
{"person", "2"},
{"first_name", "3"},
{"last_name", "4"},
{"state", "5"}
};
template<typename Node>
std::string compress(Node* root)
{
XMLCompressor<Node> compress;
return compress(root);
}
struct XMLNode
{
using attributes_t = std::map<std::string, std::string>;
using children_t = std::vector<XMLNode*>;
XMLNode(const std::string& tag_,
const std::string& data_,
const attributes_t& attributes_ = attributes_t(),
const children_t& children_ = children_t())
: tag(tag_)
, data(data_)
, attributes(attributes_)
, children(children_)
{ }
std::string tag;
std::string data;
attributes_t attributes;
std::vector<XMLNode*> children;
};
template<typename Node>
void delete_xml_tree(Node* node)
{
for (auto& child : node->children)
{
delete_xml_tree(child);
}
delete node;
}
int main(int argc, char* argv[])
{
XMLNode* root = new XMLNode("family",
"",
{
{"last_name", "McDowell"},
{"state", "CA"}
},
{
new XMLNode("person",
"Some Message",
{{"first_name", "Gayle"}})
});
print::ln(compress(root));
delete_xml_tree(root);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment