/* DOM implementation */ #include #include #include #include using namespace std; class Node { public: Node( const string& n ) : nodeName( n ) {} Node( const string& n, const string& v) : nodeName( n ), nodeValue( v ) {} void setAttribute( const string& name, const string& value ) { attributes[ name ] = value; } string getAttribute( const string& name ) const { for ( map::const_iterator i = attributes.begin(); i != attributes.end(); ++i ) { if ( i->first == name ) { return i->second; } } return ""; } string getOuterHTML() const { string temp; temp += "<"; temp += nodeName; if ( nodeName != "#text") { for ( map::const_iterator i = attributes.begin(); i != attributes.end(); ++i ) { temp += " "; temp += i->first; temp += "=\""; temp += i->second; temp += "\""; } } if ( !hasChildNodes() ) { temp += "/"; } temp += ">"; if ( hasChildNodes() ) { for ( size_t i = 0; i < childNodes.size(); ++i ) { if ( childNodes[i].nodeName != "#text" ) { temp += childNodes[i].getOuterHTML(); } else { temp += childNodes[i].nodeValue; } } temp += ""; } return temp; } string getInnerHTML() const { if ( hasChildNodes() ) { string temp; for ( vector::size_type i = 0; i < childNodes.size(); ++i ) { temp += childNodes[i].getOuterHTML(); } return temp; } return ""; } bool hasChildNodes() const { return !childNodes.empty(); } void appendChild( const Node& e ) { childNodes.push_back( e ); } string getNodeName() const { return nodeName; } string getNodeValue() const { return nodeValue; } void setNodeValue(const string& value ) { if ( nodeName == "#text" ) { nodeValue = value; } } vector getNodesByNodeName(const string& name ) { vector matches; for ( vector::size_type i = 0; i < childNodes.size(); ++i ) { if ( childNodes[i].nodeName == name || name == "*" ) { matches.push_back( &childNodes[i] ); } vector sub_matches = childNodes[i].getNodesByNodeName( name ); for ( vector::size_type z = 0; z < sub_matches.size(); ++z ) { matches.push_back( sub_matches[z] ); } sub_matches.clear(); } return matches; } ~Node(){} private: string nodeName; string nodeValue; vector childNodes; map attributes; }; int main() { /* no document node needed for this example */ Node html("html"); html.setAttribute("lang", "en"); html.appendChild( Node("head") ); html.appendChild( Node("body") ); Node title("title"); title.appendChild( Node("#text", "c++ dom") ); html.getNodesByNodeName("head")[0]->appendChild( title ); Node p("p"); p.setAttribute("id", "blabla"); p.appendChild( Node("#text", "This is a paragraph") ); html.getNodesByNodeName("body")[0]->appendChild( p ); cout << html.getOuterHTML() << "\n" << endl; cout << html.getInnerHTML() << "\n" << endl; vector all = html.getNodesByNodeName("*"); for ( size_t i = 0; i < all.size(); ++i ) { cout << all[i]->getNodeName() << endl; } } // g++ -Wall -Wextra this.cpp -o this -O3 -s