00001 #ifndef NoXmlTreeReader
00002 #include <iostream>
00003 #include <limits.h>
00004 #include "StlXmlTree.h"
00005 #include "ChapiStringUtilities.h"
00006
00007 using std::string;
00008 using std::vector;
00009 using std::map;
00010 using std::multimap;
00011 using namespace chapi_string_utilities;
00012 using stl_xml_tree::sep;
00013 using stl_xml_tree::NO_ERROR;
00014 using stl_xml_tree::NO_XML_BASE;
00015 using stl_xml_tree::BAD_XML;
00016 using std::cout;
00017 using std::cerr;
00018 #ifndef __STDB_STANDALONE__
00019 #include "StMessMgr.h"
00020 #else
00021 #define LOG_DEBUG cout
00022 #define LOG_INFO cout
00023 #define LOG_WARN cout
00024 #define LOG_ERROR cerr
00025 #define LOG_FATAL cerr
00026 #define LOG_QA cout
00027 #define endm "\n"
00028 #endif
00029
00030
00031
00032 typedef vector<string>::const_iterator VCI;
00033 typedef map<string,string>::const_iterator MCI;
00034 typedef multimap<string,string>::const_iterator MMCI;
00035
00036
00037
00039 StlXmlTree::StlXmlTree():
00040 Filter(0),
00041 XmlTree(multimap<string,string>()),
00042 Depth(0),
00043 PreviousDepth(0),
00044 MaxDepthWanted(INT_MAX),
00045 XmlTreeNodeName(""),
00046 MyStatus(NO_XML_BASE)
00047 {
00048 }
00050 StlXmlTree::StlXmlTree(const string xmlfilename, StlXmlTree* filter) :
00051 Filter(filter),
00052 XmlTree(multimap<string,string>()),
00053 Depth(0),
00054 PreviousDepth(0),
00055 MaxDepthWanted(INT_MAX),
00056 XmlTreeNodeName(""),
00057 MyStatus(NO_ERROR)
00058 {
00059 int ret;
00060 reader = xmlNewTextReaderFilename(xmlfilename.c_str());
00061 if (reader != NULL)
00062 {
00063 ret = xmlTextReaderRead(reader);
00064 while (ret == 1)
00065 {
00066 ProcessNode();
00067
00068 ret = xmlTextReaderRead(reader);
00069 }
00070 xmlFreeTextReader(reader);
00071 if (ret != 0)
00072 {
00073 LOG_ERROR<<"StlXmlTree::StlXmlTree: failed to parse "<< xmlfilename<<endm;
00074 MyStatus = BAD_XML;
00075 }
00076 }
00077 else
00078 {
00079 LOG_ERROR<<"StlXmlTree::StlXmlTree: unable to open "<< xmlfilename<< endm;
00080 MyStatus = NO_XML_BASE;
00081 }
00082 }
00084 void StlXmlTree::ShowTree()
00085 {
00086 LOG_INFO << "-----------------------------------------"<<endm;
00087 LOG_INFO << "XmlTree contains"<<endm;
00088 for (MMCI I=XmlTree.begin(); I!=XmlTree.end(); ++I)
00089 {
00090 LOG_INFO << (*I).first <<" -- "<<(*I).second <<endm;
00091 }
00092 LOG_INFO << "-----------------------------------------"<<endm;
00093 }
00095 string StlXmlTree::MakeKey(string FullyQualifiedParent, string Child)
00096 {
00097 return FullyQualifiedParent + sep + Child;
00098 }
00100 string StlXmlTree::QualifyParent(string Parent, string Attributes)
00101 {
00102 string rtrn = Parent + "(" + Attributes + ")";
00103 return rtrn;
00104 }
00106 vector<string> StlXmlTree::LookUpValueByKey(string key)
00107 {
00108 vector<string> rtrn;
00109 MMCI f = XmlTree.find(key);
00110 if (f!=XmlTree.end())
00111 {
00112 MMCI b = XmlTree.lower_bound(key);
00113 MMCI e = XmlTree.upper_bound(key);
00114
00115 for (MMCI i = b; i!=e; ++i)
00116 {
00117 rtrn.push_back((*i).second);
00118 }
00119 }
00120 return rtrn;
00121 }
00123 vector<string> StlXmlTree::LookUpValueByKey
00124 (string& Parent, string ParentAttributes, string Child)
00125 {
00126 string qp = QualifyParent(Parent,ParentAttributes);
00127 string key = MakeKey(qp,Child);
00128 #ifdef DEBUG
00129 LOG_INFO << "StlXmlTree::LookUpValueByKey key is " << key <<endm;
00130 #endif
00131 vector<string> rtrn = LookUpValueByKey(key);
00132 Parent = key;
00133 return rtrn;
00134 }
00136 void StlXmlTree::InsertKeyValuePair(string Key, string Value)
00137 {
00138 OnTheTree = XmlTree.insert(make_pair(Key,Value));
00139 }
00141 bool StlXmlTree::AttributesContain(string A, string N, string V)
00142 {
00143
00144 if ((N=="" && V=="") || N=="")
00145 {
00146 return false;
00147 }
00148 map<string,string> nv = ParseAttributeString(A);
00149 map<string,string>::iterator I = nv.find(N);
00150 if (I==nv.end())
00151 {
00152 return false;
00153 }
00154 else
00155 {
00156 if ((*I).second==V)
00157 {
00158 return true;
00159 }
00160 else
00161 {
00162 return false;
00163 }
00164 }
00165 }
00167 #ifdef DEBUG
00168 void StlXmlTree::ProcessNodeDebug()
00169 {
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 const xmlChar *name, *value;
00185
00186
00187 name = xmlTextReaderName(reader);
00188 if (name == NULL)
00189 name = BAD_CAST "--";
00190
00191
00192 value = xmlTextReaderValue(reader);
00193
00194 LOG_INFO << xmlTextReaderDepth(reader) <<" "<<xmlTextReaderNodeType(reader)<<" "<<name<<" "<<xmlTextReaderIsEmptyElement(reader)<<" "<< xmlTextReaderHasValue(reader)<<endm;
00195 if (value == NULL)
00196 {
00197 LOG_INFO <<endm;
00198 }
00199 else
00200 {
00201 if (xmlStrlen(value) > 40)
00202 {
00203 LOG_INFO<<value<<".40s..."<endm;
00204 }
00205 else
00206 {
00207 LOG_INFO<<" "<<value<<endm;
00208 }
00209 }
00210
00211 short HasAttributes = xmlTextReaderHasAttributes(reader);
00212 if (HasAttributes)
00213 {
00214 while (xmlTextReaderMoveToNextAttribute(reader))
00215 {
00216 ProcessNodeDebug();
00217 }
00218 }
00219 }
00220 #endif
00222 void StlXmlTree::UpdateDepth()
00223 {
00224 PreviousDepth = Depth;
00225 Depth = xmlTextReaderDepth(reader);
00226 }
00228 void StlXmlTree::ProcessAttribute()
00229 {
00230
00231
00232
00233
00234
00235
00236 int NodeType = xmlTextReaderNodeType(reader);
00237
00238 UpdateDepth();
00239
00240 if (NodeType!=XML_READER_TYPE_ATTRIBUTE)
00241 {
00242 return;
00243 }
00244
00245 xmlChar* atname = xmlTextReaderName(reader);
00246 string AttributeName = (char*)atname;
00247 if ( atname != NULL ) { xmlFree(atname); atname = NULL; }
00248
00249 xmlChar* tmp = xmlTextReaderValue(reader);
00250 string NodeValue = filter_string((char*)tmp);
00251 if ( tmp != NULL ) { xmlFree(tmp); tmp = NULL; }
00252
00253 IdString += AttributeName + "=" + NodeValue + ";";
00254 }
00256 void StlXmlTree::ProcessNode()
00257 {
00258 int NodeType = xmlTextReaderNodeType(reader);
00259 short HasValue = xmlTextReaderHasValue(reader);
00260 short HasAttributes = xmlTextReaderHasAttributes(reader);
00261 xmlChar* name = xmlTextReaderName(reader);
00262 NodeName = (char*)name;
00263 if ( name != NULL ) { xmlFree(name); name = NULL; }
00264
00265 string NodeValue = "";
00266
00267 IdString = "";
00268 if (HasValue)
00269 {
00270 xmlChar* tmp = xmlTextReaderValue(reader);
00271 NodeValue = filter_string((char*)tmp);
00272 if ( tmp != NULL ) { xmlFree(tmp); tmp = NULL; }
00273
00274 IdString = NodeName + "=" + NodeValue + ";";
00275 }
00276
00277 UpdateDepth();
00278
00279 if (Depth>MaxDepthWanted)
00280 {
00281 return;
00282 }
00283 if (Depth<MaxDepthWanted)
00284 {
00285 MaxDepthWanted = INT_MAX;
00286 }
00287
00288 if (Depth<PreviousDepth || NodeType==XML_READER_TYPE_END_ELEMENT)
00289 {
00290 cut_string_after_sub(XmlTreeNodeName,sep);
00291 }
00292
00293 if ((NodeType==XML_READER_TYPE_ELEMENT || NodeValue !="") && NodeType != XML_READER_TYPE_COMMENT )
00294 {
00295 if (NodeType==XML_READER_TYPE_ELEMENT)
00296 {
00297 XmlTreeNodeName = XmlTreeNodeName + sep + NodeName;
00298
00299 if (HasAttributes)
00300 {
00301
00302 while (xmlTextReaderMoveToNextAttribute(reader))
00303 {
00304 ProcessAttribute();
00305 }
00306 }
00307 }
00308
00309 if (!SkipBasedOnValue(XmlTreeNodeName,IdString))
00310 {
00311 string key = XmlTreeNodeName;
00312 string value = IdString;
00313
00314
00315 XmlTreeNodeName = QualifyParent(XmlTreeNodeName,IdString);
00316
00317
00318 {
00319 OnTheTree = XmlTree.insert(make_pair(key,value));
00320 MaxDepthWanted = INT_MAX;
00321 }
00322 }
00323 else
00324 {
00325 MaxDepthWanted = Depth-1;
00326 }
00327 }
00328
00329
00330 }
00332 map<string,string> StlXmlTree::ParseAttributeString(string in)
00333 {
00334 vector<string> v = slice(in,";");
00335 map<string,string> m = associate_pieces(v,"=");
00336 return m;
00337 }
00339 bool StlXmlTree::SkipBasedOnValue(const string key, const string value)
00340 {
00341 if (!Filter)
00342 {
00343 return false;
00344 }
00345
00346 map<string,string> m = ParseAttributeString(value);
00347
00348 #ifdef DEBUG
00349 LOG_INFO << "StlXmlTree::SkipBasedOnValue key = "<<key<<" value = "<<value<<endm;
00350 #endif
00351 MMCI b = Filter->XmlTree.lower_bound(key);
00352 MMCI e = Filter->XmlTree.upper_bound(key);
00353
00354 bool rtrn = false;
00355
00356
00357
00358
00359
00360
00361 if (b!=e)
00362 {
00363 for (MMCI i=b; i!=e; ++i)
00364 {
00365 map<string,string> f = ParseAttributeString((*i).second);
00366
00367
00368
00369 for (MCI ii = f.begin(); ii != f.end(); ++ii)
00370 {
00371 string search_key = (*ii).first;
00372
00373 MCI mykey = m.find(search_key);
00374
00375 if (mykey!=m.end())
00376 {
00377
00378
00379
00380
00381
00382 vector<string> mykey_v = slice((*mykey).second,",");
00383 vector<string> f_v = slice((*ii).second,",");
00384
00385 rtrn = true;
00386 VCI m_v_i = mykey_v.begin();
00387 while (m_v_i != mykey_v.end() && rtrn)
00388 {
00389 VCI f_v_i = f_v.begin();
00390
00391 while (f_v_i != f_v.end() && rtrn)
00392 {
00393 #ifdef DEBUG
00394 LOG_INFO <<" compare " <<*m_v_i <<" and "<<*f_v_i <<endm;
00395 #endif
00396 if (*m_v_i == *f_v_i)
00397 {
00398 rtrn = false;
00399 }
00400
00401 ++f_v_i;
00402 }
00403 ++m_v_i;
00404 }
00405
00406 if (rtrn)
00407 {
00408 #ifdef DEBUG
00409 LOG_INFO << "StlXmlTree::SkipBasedOnValue "<< rtrn <<endm;
00410 #endif
00411 return rtrn;
00412 }
00413 }
00414 }
00415 }
00416 }
00417 else
00418 {
00419 rtrn = false;
00420
00421 }
00422
00423 #ifdef DEBUG
00424 LOG_INFO << "StlXmlTree::SkipBasedOnValue "<< rtrn <<endm;
00425 #endif
00426 return rtrn;
00427 }
00428
00429 #endif
00430