// -*-c++-*- // fixg2sxd - a utility to convert fig to sxd format // Copyright (C) 2003-2006 Alexander Bürger, acfb@users.sourceforge.net // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "xmlwrite.h" using namespace std; string indent(int l) { ostringstream s; for( int i=0; i<l; ++i ) s.put(' '); return s.str(); } // ------------------------------------------------------------------------ void TextElement::write(ostream& out, int /*level*/, bool /*pretty*/) const { out << text.str(); } // ------------------------------------------------------------------------ Node::Node( string const& aName ) : name( aName ), indentation(true) { } Node::~Node() { for( attributes_t::iterator i = attributes.begin(); i != attributes.end(); ++i ) { delete i->second; } for( vector<Element*>::iterator i = elements.begin(); i != elements.end(); ++i ) { delete *i; } } ostringstream& Node::att( string const& attname ) { #ifdef USE_MAP attributes_t::iterator i = attributes.find( attname ); #else attributes_t::iterator i = attributes.begin(); while( i != attributes.end() && i->first != attname ) ++i; #endif if( i != attributes.end() ) { delete i->second; #ifndef USE_MAP attributes.erase(i); #endif } ostringstream* o = new ostringstream; #ifdef USE_MAP attributes[ attname ] = o; #else attributes.push_back( pair<string,ostringstream*>( attname, o ) ); #endif return *o; } Node& Node::subnode( string const& subname ) { Node* n = new Node( subname ); elements.push_back( n ); return *n; } TextElement& Node::text() { TextElement* t = new TextElement(); elements.push_back( t ); indentation = false; return *t; } void Node::write(ostream& out, int level, bool pretty) const { out << indent(level) << '<' << name; for( attributes_t::const_iterator i = attributes.begin(); i != attributes.end(); ++i ) { out << ' ' << i->first << "=\"" << i->second->str() << '"'; } if( elements.empty() ) { out << "/>"; if( pretty ) out << endl; } else { out << ">"; if( pretty && indentation ) out << endl; for( vector<Element*>::const_iterator i = elements.begin(); i != elements.end(); ++i ) { (*i)->write( out, level+1, pretty && indentation ); } if( pretty && indentation ) out << indent(level); out << "</" << name << '>'; if( pretty ) out << endl; } } // ------------------------------------------------------------------------ #ifdef TEST_XMLWRITE int main() { Node root("office:body"); root["hi"] << "ho"; Node& s = root.subnode("office:bah"); s["att-no"] << "yes"; root.text().t() << "this is text!"; Node& s2 = root.subnode("office:zero"); s2["att-no"] << "yes"; cout << root; } #endif // TEST_XMLWRITE