#include "Element.h" #include "TextNode.h" #include "Comment.h" namespace xml { Element::Element(const std::string& name) : Node(nodeElement) { this->nodeName = name.substr(1); } Element::~Element() { } std::istream& Element::load(std::istream& in) { // if this is an empty tag with no attributes if ( nodeName[nodeName.length() - 1] == '/' ) { nodeName = nodeName.substr(0, nodeName.length() - 1); return in; } // Read children: attributes, child elements, text nodes, comments for ( std::string token = Util::nextToken(in); in; token = Util::nextToken(in) ) { size_t pos = std::string::npos; if ( (pos = token.find('=')) != std::string::npos ) { // Found an attribute std::string name = token.substr(0, pos); attributes[name] = token.substr(pos + 1); if ( token[token.length() - 1] == '/' ) return in; } else if ( token[0] == '<' ) { if ( token[1] == '/' ) { // Found end-tag for this element return in; } else if ( token[1] == '!' ) { // Found a comment Comment* comment = new Comment(); childNodes.push_back(comment); comment->load(in); } else { // Found a child element Element* child = new Element(token); childNodes.push_back(child); child->load(in); } } else { // Found a text node, include the removed separator in.unget(); TextNode* text = new TextNode(token + (char)in.get()); childNodes.push_back(text); text->load(in); } } return in; } std::ostream&Element::print(std::ostream& out, int depth) const { // Indent Util::tabs(out, depth); // Print open tag and attributes: first << '=' << itr->second; // If empty element, print empty tag if ( childNodes.size() == 0 ) return out << "/>" << std::endl; // Has children, close start tag and print each child in one line out << '>' << std::endl; for ( size_t i = 0; i < childNodes.size(); ++i ) childNodes[i]->print(out, depth + 1); return Util::tabs(out, depth) << "' << std::endl; // end-tag } } // namespace xml