c++ - Pretty printing XML in wxWidgets -
i'm writing class derived wxstyledtextctrl , want prettify given xml without adding other whitespaces. cannot find simple working solution. can use wxstyledtextctrl, wxxmldocument , libxml2.
the result i'm aiming after calling settext wxstring containing following text
<!-- comment1 --> <!-- comment2 --> <node><emptynode/> <othernode>value</othernode></node>
the control should show
<!-- comment1 --> <!-- comment2 --> <node> <emptynode/> <othernode>value</othernode> </node>
using libxml2 managed achieve this, prints xml declaration (eg. <?xml version="1.0" encoding="utf-8"?>
) , don't want this.
inb4, i'm looking simple , clean solution - don't want manually remove first line of formatted xml
is there simple solution using given tools? feel i'm missing something.
is there simple solution? no. if want write you're own pretty print function, need make depth first iteration on xml document tree, printing go. there's slight complication in need way of knowing when close tag.
here's incomplete example of 1 way using wxwidgets xml classes. currently, doesn't handle attributes, self closing elements (such '' in sample text), or other special element types. complete pretty printer need add things.
#include <stack> #include <set> #include <wx/xml/xml.h> #include <wx/sstream.h> wxstring prettyprint(const wxstring& in) { wxstringinputstream string_stream(in); wxxmldocument doc(string_stream); wxstring pretty_print; if (doc.isok()) { std::stack<wxxmlnode*> nodes_in_progress; std::set<wxxmlnode*> visited_nodes; nodes_in_progress.push(doc.getdocumentnode()); while (!nodes_in_progress.empty()) { wxxmlnode* cur_node = nodes_in_progress.top(); nodes_in_progress.pop(); int depth = cur_node->getdepth(); (int i=1;i<depth;++i) { pretty_print << "\t"; } if (visited_nodes.find(cur_node)!=visited_nodes.end()) { pretty_print << "</" << cur_node->getname() << ">\n"; } else if ( !cur_node->getnodecontent().isempty() ) { //if node has content, print pretty_print << "<" << cur_node->getname() << ">"; pretty_print << cur_node->getnodecontent() ; pretty_print << "</" << cur_node->getname() << ">\n"; } else if (cur_node==doc.getdocumentnode()) { std::stack<wxxmlnode *> nodes_to_add; wxxmlnode *child = cur_node->getchildren(); while (child) { nodes_to_add.push(child); child = child->getnext(); } while (!nodes_to_add.empty()) { nodes_in_progress.push(nodes_to_add.top()); nodes_to_add.pop(); } } else if (cur_node->gettype()==wxxml_comment_node) { pretty_print << "<!-- " << cur_node->getcontent() << " -->\n"; } //insert checks other types of nodes special //printing requirements here else { //otherwise, mark node visited , put visited_nodes.insert(cur_node); nodes_in_progress.push(cur_node); //if push children in order, they'll popped //in reverse order. std::stack<wxxmlnode *> nodes_to_add; wxxmlnode *child = cur_node->getchildren(); while (child) { nodes_to_add.push(child); child = child->getnext(); } while (!nodes_to_add.empty()) { nodes_in_progress.push(nodes_to_add.top()); nodes_to_add.pop(); } pretty_print <<"<" << cur_node->getname() << ">\n"; } } } return pretty_print; }
Comments
Post a Comment