xml.cpp

00001 #include <iostream> 00002 #include <fstream> 00003 #include <map> 00004 #include <list> 00005 #include <string> 00006 #include <stack> 00007 #include <sstream> 00008 00009 00010 #include "gm/gm.h" 00011 #include "gm/xml.h" 00012 00013 namespace GNUMessenger 00014 { 00015 00016 using namespace std; 00017 00018 string XMLParser::escape(string str) 00019 { 00020 string a[] = {"&", "<", ">", "\"", "'"}; 00021 string b[] = {"&amp;", "&lt;", "&gt;", "&quot;", "&apos;"}; 00022 00023 for (int i=0; i<5; i++) 00024 { 00025 size_t pos=0; 00026 while ( ( pos = str.find(a[i], pos ) ) != std::string::npos ) 00027 { 00028 str.replace( pos, a[i].length(), b[i] ); 00029 pos += b[i].length(); // new starting point of search is just after 'b' 00030 } 00031 } 00032 return str; 00033 } 00034 00035 void XMLParser::init(const string &line, Type type) 00036 { 00037 switch (type) 00038 { 00039 case String: 00040 try { 00041 parse(line); 00042 } 00043 catch (Expat::ParseFailure &e) 00044 { 00045 LOG_THROW(e.what(), ParseFailure); 00046 } 00047 break; 00048 case File: 00049 { 00050 string str; 00051 ifstream in(line.c_str()); 00052 if (!in) 00053 { 00054 LOG_THROW("XMLParser: Specified file cannot be opened.", DiskError); 00055 return; 00056 } 00057 00058 while (in.good()) 00059 { 00060 getline(in,str); 00061 str+="\n"; 00062 parse(str); 00063 } 00064 in.close(); 00065 } 00066 break; 00067 }; 00068 00069 } 00070 00071 XMLParser::XMLParser(const string &line, Type type) 00072 : Expat() 00073 { 00074 init(line, type); 00075 } 00076 00077 XMLParser::XMLParser(XMLNode &_root) 00078 : Expat() 00079 { 00080 root = _root; 00081 } 00082 00083 XMLParser::~XMLParser() 00084 { 00085 00086 } 00087 00088 int XMLParser::tree_to_xml(string &line) 00089 { 00090 printTag(root,line); 00091 return 0; 00092 } 00093 00094 int XMLParser::tree_to_file(const string &filename) 00095 { 00096 string line; 00097 ofstream out(filename.c_str()); 00098 00099 if (!out) 00100 { 00101 LOG_THROW("File Error!", DiskError); 00102 return -1; 00103 } 00104 00105 printTag(root,line); 00106 out << line; 00107 00108 out.close(); 00109 return 0; 00110 } 00111 00112 vector<XMLNode> XMLParser::get_tags(const string &key) 00113 { 00114 vector<XMLNode> ret; 00115 return ret; 00116 } 00117 00118 int XMLParser::printTag(const XMLNode &node, string &ret, int indent) 00119 { 00120 int s(0); 00121 00122 // print indent 00123 for (s=0; s<indent; s++) 00124 ret += "\t"; 00125 00126 // print tag name 00127 ret += "<" + XMLParser::escape(node.m_xmlData->m_name); 00128 00129 // print properties 00130 for (map<string,string>::const_iterator i=node.m_xmlData->m_properties.begin();i!=node.m_xmlData->m_properties.end();i++) 00131 { 00132 if (i->second == "") 00133 ret+= " " + XMLParser::escape(i->first) + "=\"\""; 00134 else 00135 ret+= " " + XMLParser::escape(i->first) + "=\"" + XMLParser::escape(i->second) + "\""; 00136 } 00137 00138 // if tag has no children, close and return 00139 if (( node.m_xmlData->m_data == "" || node.m_xmlData->m_data == "\n") && node.m_xmlData->m_children.empty()) 00140 { 00141 ret+="/>"; 00142 return 0; 00143 } 00144 00145 // if has data/children 00146 ret+=">"; 00147 00148 // print children 00149 bool childprinted = false; 00150 for (vector<XMLNode>::const_iterator it=node.m_xmlData->m_children.begin();it!=node.m_xmlData->m_children.end();it++) 00151 { 00152 ret+="\n"; 00153 childprinted = true; 00154 string tmp; 00155 printTag(*it,tmp,indent+1); 00156 ret+=tmp; 00157 } 00158 00159 // indent for data 00160 if (childprinted && (node.m_xmlData->m_data.length()>0)) 00161 for (s=0; s<indent + 1; s++) 00162 ret += "\t"; 00163 00164 if (node.m_xmlData->data_is_cdata) 00165 ret+="<![CDATA["; 00166 00167 00168 if (node.m_xmlData->m_data.length()>0) 00169 { 00170 if (node.m_xmlData->data_is_cdata) 00171 ret+=node.m_xmlData->m_data; 00172 else 00173 ret+=XMLParser::escape(node.m_xmlData->m_data); 00174 } 00175 00176 if (node.m_xmlData->data_is_cdata) 00177 ret+="]]>"; 00178 00179 if (childprinted) 00180 ret+='\n'; 00181 00182 // print indent 00183 if (childprinted) 00184 for (s=0; s<indent; s++) ret += "\t"; 00185 00186 ret += "</" + XMLParser::escape(node.m_xmlData->m_name) + ">\n"; 00187 00188 return 0; 00189 } 00190 00191 00192 void XMLParser::recievedTag(XMLNode& n) 00193 { 00194 root.addChild(n); 00195 } 00196 00197 void XMLParser::rootTagRecieved(XMLNode& _root) 00198 { 00199 root=_root; 00200 } 00201 00202 void XMLParser::parserError(const string& errorMsg, int line) 00203 { 00204 stringstream error; 00205 error << errorMsg << ": " << line; 00206 reset(); 00207 00208 LOG_THROW(error.str(), ParseFailure); 00209 00210 } 00211 00212 }

Generated on Tue Oct 5 14:41:47 2004 for GNU Messenger by doxygen 1.3.8