Teuchos_XMLObjectImplem.cpp

00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #include "Teuchos_XMLObject.hpp"
00030 #include "Teuchos_StrUtils.hpp"
00031 
00032 using namespace Teuchos;
00033 
00034 
00035 XMLObjectImplem::XMLObjectImplem(const std::string& tag)
00036   : tag_(tag), attributes_(), children_(0), content_(0)
00037 {;}
00038 
00039 XMLObjectImplem* XMLObjectImplem::deepCopy() const 
00040 {
00041   XMLObjectImplem* rtn = new XMLObjectImplem(tag_);
00042   TEST_FOR_EXCEPTION(rtn==0, std::runtime_error, "XMLObjectImplem::deepCopy()");
00043   rtn->attributes_ = attributes_;
00044   rtn->content_ = content_;
00045   
00046   for (int i=0; i<children_.length(); i++)
00047     {
00048       rtn->addChild(children_[i].deepCopy());
00049     }
00050 
00051   return rtn;
00052 }
00053 
00054 int XMLObjectImplem::numChildren() const {return children_.length();}
00055 
00056 void XMLObjectImplem::addAttribute(const std::string& name, const std::string& value)
00057 {
00058   attributes_[name] = value;
00059 }
00060 
00061 void XMLObjectImplem::addChild(const XMLObject& child)
00062 {
00063   children_.append(child);
00064 }
00065 
00066 void XMLObjectImplem::addContent(const std::string& contentLine)
00067 {
00068   content_.append(contentLine);
00069 }
00070 
00071 const XMLObject& XMLObjectImplem::getChild(int i) const 
00072 {
00073   return children_[i];
00074 }
00075 
00076 std::string XMLObjectImplem::header(bool strictXML) const
00077 {
00078   std::string rtn = "<" + tag_;
00079       
00080   for (Map::const_iterator i=attributes_.begin(); i!=attributes_.end(); ++i)
00081     {
00082       if (strictXML) {
00083         rtn += " " 
00084             + (*i).first 
00085             + "="
00086             + XMLifyAttVal((*i).second);
00087       }
00088       else {
00089         rtn += " " + (*i).first + "=\"" + (*i).second + "\"";
00090       }
00091     }
00092   
00093   rtn += ">";
00094   return rtn;
00095 }
00096 
00097 std::string XMLObjectImplem::XMLifyAttVal(const std::string &attval) {
00098   std::string ret;
00099   bool hasQuot, hasApos;
00100   char delim;
00101 
00102   if (attval.find("\"") == std::string::npos) {
00103     hasQuot = false;
00104   }
00105   else {
00106     hasQuot = true;
00107   }
00108 
00109   if (attval.find("\'") == std::string::npos) {
00110     hasApos = false;
00111   }
00112   else {
00113     hasApos = true;
00114   }
00115 
00116   if (!hasQuot || hasApos) {
00117     delim = '\"'; // wrap the attribute value in "
00118   }
00119   else {
00120     delim = '\''; // wrap the attribute value in '
00121   }
00122 
00123   // Rules:
00124   // "-wrapped std::string cannot contain a literal "
00125   // '-wrapped std::string cannot contain a literal '
00126   // attribute value cannot contain a literal <
00127   // attribute value cannot contain a literal &
00128   ret.push_back(delim);
00129   for (std::string::const_iterator i=attval.begin(); i != attval.end(); i++) {
00130     if (*i == delim) {
00131       if (delim == '\'') ret.append("&apos;");
00132       else if (delim == '\"') ret.append("&quot;");
00133     }
00134     else if (*i == '&') {
00135       ret.append("&amp;");
00136     }
00137     else if (*i == '<') {
00138       ret.append("&lt;");
00139     }
00140     else {
00141       ret.push_back(*i);  
00142     }
00143   }
00144   ret.push_back(delim);
00145 
00146   return ret;
00147 }
00148 
00149 std::string XMLObjectImplem::terminatedHeader(bool strictXML) const
00150 {
00151   std::string rtn = "<" + tag_;
00152       
00153   for (Map::const_iterator i=attributes_.begin(); i!=attributes_.end(); ++i)
00154     {
00155       if (strictXML) {
00156         rtn += " " 
00157             + (*i).first 
00158             + "="
00159             + XMLifyAttVal((*i).second);
00160       }
00161       else {
00162         rtn += " " + (*i).first + "=\"" + (*i).second + "\"";
00163       }
00164     }
00165 
00166   rtn += "/>";
00167   return rtn;
00168 }
00169 
00170 std::string XMLObjectImplem::toString() const
00171 {
00172   std::string rtn;
00173   
00174   if (content_.length()==0 && children_.length()==0) 
00175     {
00176       rtn = terminatedHeader() + "\n";
00177     }
00178   else
00179     {
00180       rtn = header() + "\n";
00181       bool allBlankContent = true;
00182       for (int i=0; i<content_.length(); i++)
00183         {
00184           if (!StrUtils::isWhite(content_[i])) 
00185             {
00186               allBlankContent=false;
00187               break;
00188             }
00189         }
00190       if (!allBlankContent)
00191         {
00192           for (int i=0; i<content_.length(); i++)
00193             {
00194               rtn += content_[i];
00195             }
00196           rtn += "\n";
00197         }
00198       for (int i=0; i<children_.length(); i++)
00199         {
00200           rtn += children_[i].toString();
00201         }
00202       rtn += "</" + tag_ + ">\n";
00203     }
00204   return rtn;
00205 }
00206 
00207 void XMLObjectImplem::print(std::ostream& os, int indent) const
00208 {
00209   for (int i=0; i<indent; i++) os << " ";
00210   
00211   if (content_.length()==0 && children_.length()==0) 
00212     {
00213       os << terminatedHeader(true) << std::endl;
00214       return;
00215     }
00216   else
00217     {
00218       os << header(true) << std::endl;
00219       printContent(os, indent+2);
00220       
00221       for (int i=0; i<children_.length(); i++)
00222         {
00223           children_[i].print(os, indent+2);
00224         }
00225       for (int i=0; i<indent; i++) os << " ";
00226       os << "</" << tag_ << ">\n";
00227     }
00228 }
00229 
00230 void XMLObjectImplem::printContent(std::ostream& os, int indent) const 
00231 {
00232   std::string space = "";
00233   for (int i=0; i<indent; i++) space += " ";
00234 
00235   bool allBlankContent = true;
00236   for (int i=0; i<content_.length(); i++)
00237     {
00238       if (!StrUtils::isWhite(content_[i])) 
00239         {
00240           allBlankContent=false;
00241           break;
00242         }
00243     }
00244   
00245   if (!allBlankContent) 
00246     {
00247       os << space;
00248       for (int i=0; i<content_.length(); i++)
00249         {
00250           os << content_[i];
00251         }
00252       os << '\n';
00253     }
00254 }
00255 

Generated on Tue Oct 20 12:45:26 2009 for Teuchos - Trilinos Tools Package by doxygen 1.4.7