Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

CSXMLHelperTinyXML.cpp

Go to the documentation of this file.
00001 #include "CSXMLHelper.h"
00002 
00003 #ifdef WIN32
00004 #pragma warning(disable : 4786 )
00005 #endif
00006 
00007 #ifdef USE_TINYXML
00008 
00009 #include <vector>
00010 
00011 const char *CSXMLHelper::CLASS = "CSXMLHelper";
00012 
00013 void cstoupper(char * s)
00014 {
00015     int i = strlen(s);
00016     for (int e =0; e < i; e++)
00017     {
00018         s[e] = toupper(s[e]);
00019     }
00020 }
00021 
00022 void CSXMLHelper::addEntitiesFromFile(const std::string &filename, const std::string &parentFilename)
00023 {
00024     static char *functionName="addEntitiesFromFile";
00025     LOG_ENTER
00026     std::string fullName;
00027     //////////////////////////////
00028     // Build filename + path
00029     //////////////////////////////
00030     int posStart = parentFilename.find_last_of("\\", parentFilename.size());
00031     if (posStart != -1)
00032     {
00033         fullName = parentFilename.substr(0, posStart+1);
00034     }
00035     fullName += filename;
00036 
00037     ////////////
00038     // open File
00039     ////////////
00040     FILE *handle = fopen(fullName.c_str(), "rt");
00041     if (handle == 0)
00042     {
00043         LOG_DEBUG_MESSAGE(((std::string)"Entity file: \"") + fullName+"\" cannot be opened!") 
00044         LOG_EXIT
00045         return;
00046     }
00047     static char tmp[1024];
00048 
00049     ////////////////
00050     // seek entities
00051     ////////////////
00052     while (1)
00053     {
00054         char *res = fgets(tmp, 1024, handle);
00055         std::string strValue = tmp;
00056         if (res == 0)
00057         {
00058             break;
00059         }
00060         if (strstr(tmp, "<!") != 0)
00061         {
00062             if (strstr(tmp, "SYSTEM") != 0)
00063             {
00064                 // another include found!
00065                 int posStart = strValue.find_first_of('\"');
00066                 int posEnd = strValue.find_first_of('\"', posStart+1);
00067                 std::string dtdName = strValue.substr(posStart+1, (posEnd-1) - (posStart));
00068                 if (parentFilename.size() != 0)
00069                 {
00070                     addEntitiesFromFile(dtdName, parentFilename);
00071                 }
00072                 else
00073                 {
00074                     addEntitiesFromFile(dtdName, filename);
00075                 }
00076             }
00077             else
00078             {
00079                 if (strstr(tmp, "!ENTITY") != 0)
00080                 {   
00081                     int posStart = strValue.find_first_of("!ENTITY");
00082                     posStart = strValue.find_first_of(" \t", posStart);
00083                     posStart = strValue.find_first_not_of(" \t", posStart);
00084                     int posEnd = strValue.find_first_of(" \t", posStart);
00085                     std::string key = strValue.substr(posStart, posEnd - posStart);
00086                     key = "&" + key + ";";
00087 
00088                     posStart = strValue.find_first_of('\"');
00089                     posEnd = strValue.find_first_of('\"', posStart+1);
00090 
00091                     std::string value = strValue.substr(posStart+1, (posEnd-1) - (posStart));
00092                     mEntityMap.insert(EntityMap::value_type(key, value));
00093                 }
00094             }
00095         }
00096     }
00097     
00098     fclose(handle);
00099     LOG_EXIT
00100 }
00101 
00102 
00103 CSXMLHelper::CSXMLHelper(const std::string &xmlFilename, const std::string &contextNode)
00104 {
00105     static char *functionName="CSXMLHelper";
00106     mError = CSXML_OK;
00107     mXMLdoc = 0;
00108 
00109     mXMLdoc = new TiXmlDocument(xmlFilename);
00110     mXMLdoc->setIgnoreNoEndTag(false);
00111     mXMLdoc->SetCondenseWhiteSpace(true); 
00112 
00113     if (!mXMLdoc)
00114     {
00115         mError = CSXML_CONTEXT_LOADING_ERROR;
00116         std::string errorMessageString;
00117         errorMessageString = std::string("Error - while loading context \"" + contextNode +"\"!");
00118         mErrorMessageString = mErrorMessageString + "\n"+ errorMessageString;
00119     }
00120 
00121     addEntitiesFromFile(xmlFilename, "");
00122 
00123     if (!mXMLdoc->LoadFile() )
00124     {
00125         mError = CSXML_DOCUMENT_LOADING_ERROR;
00126         std::string errorMessageString;
00127         errorMessageString = std::string("Error - while loading document \"" + xmlFilename +"\"!");
00128         mErrorMessageString = mErrorMessageString + "\n"+ errorMessageString;
00129         return;         
00130     }
00131     mXMLsource = mXMLdoc->FirstChildElement(contextNode);
00132 }
00133 
00134 CSXMLHelper::~CSXMLHelper()
00135 {
00136     static char *functionName="~CSXMLHelper";
00137     LOG_ENTER
00138     delete (mXMLdoc);
00139     mXMLdoc = 0;
00140     mXMLsource = 0;
00141     mEntityMap.clear();
00142     LOG_EXIT
00143 }
00144 
00145 int CSXMLHelper::getInt(const std::string &xpath)
00146 {
00147     static char *functionName="getInt";
00148     LOG_ENTER
00149     int ret = 0;
00150     if (mError != 0)
00151     {
00152         LOG_WARN_MESSAGE("Error")
00153         LOG_EXIT
00154         throw "error";
00155     }
00156     try
00157     {
00158         TiXmlNode *node = getXPathResult(xpath);
00159         if (node == 0)
00160         {
00161             LOG_EXIT
00162             return 0;
00163         }
00164         if (node->Type() == TiXmlNode::FUNCTION)
00165         {
00166             ret = toInt(*node);
00167             delete node;
00168             node = 0;
00169         }
00170         else
00171         {
00172             TiXmlText *element = node->ToText();
00173             if (element == 0)
00174             {
00175                 LOG_DEBUG_MESSAGE("XPath \"" + xpath + "\" doesn't represent a text element!") 
00176             }
00177             ret = toInt(*element);
00178         }
00179     }
00180     catch(...)
00181     {
00182         mError = CSXML_XPATH_ERROR;
00183         std::string errorMessageString;
00184         errorMessageString = "tinyXMLException";
00185         mErrorMessageString = mErrorMessageString + "\n"+ errorMessageString;
00186         LOG_WARN_MESSAGE(mErrorMessageString)
00187         LOG_EXIT
00188         throw "error";
00189     }
00190     LOG_EXIT
00191     return ret;
00192 }
00193 
00194 std::string CSXMLHelper::getString(const std::string &xpath)
00195 {
00196     static char *functionName="getString";
00197     LOG_ENTER
00198     std::string cstr;
00199     if (mError != 0)
00200     {
00201         LOG_WARN_MESSAGE("XML! Not properly initialized!")
00202         LOG_EXIT
00203         throw std::string("XML! Not properly initialized!");
00204     }
00205     try
00206     {
00207         TiXmlNode *node = getXPathResult(xpath);
00208         if (node == 0)
00209         {
00210             LOG_EXIT
00211             return "";
00212         }
00213         if (node->Type() == TiXmlNode::FUNCTION)
00214         {
00215             cstr = toAscii(*node);
00216             delete node;
00217             node = 0;
00218         }
00219         else
00220         {
00221             TiXmlText *element = node->ToText();
00222             if (element == 0)
00223             {
00224                 LOG_DEBUG_MESSAGE("XPath \"" + xpath + "\" doesn't represent a text element!") 
00225             }
00226             cstr = toAscii(*element);
00227         }
00228         
00229     }
00230     catch(...)
00231     {
00232         mError = CSXML_XPATH_ERROR;
00233         std::string errorMessageString;
00234         errorMessageString = "tinyXMLException";
00235         mErrorMessageString = mErrorMessageString + "\n"+ errorMessageString;
00236         LOG_WARN_MESSAGE(mErrorMessageString)
00237         LOG_EXIT
00238         throw "error";
00239     }
00240     LOG_EXIT
00241     return cstr;
00242 }
00243 
00244 ElementDescription CSXMLHelper::getElementDescription(std::string &xpath)
00245 {
00246     static char *functionName="getElementDescription";
00247     LOG_ENTER
00248     ElementDescription desc;
00249     int posStart;
00250     int posEnd;
00251     LOG_DEBUG_MESSAGE("current xpath: "+ xpath) 
00252 
00253     /////////////////////
00254     // check for function
00255     /////////////////////
00256     const std::string FKT_COUNT = "count(";
00257     if (xpath.compare(0, FKT_COUNT.size(), FKT_COUNT) == 0)
00258     {
00259         LOG_DEBUG_MESSAGE("Function count() encountered: ") 
00260         // strip xpath of function
00261         // assumes closing bracket (")") is last element of string
00262         xpath = xpath.substr(FKT_COUNT.size(), xpath.size() - FKT_COUNT.size()-1);
00263         desc.count = true;
00264         desc.function = true;
00265     }
00266 
00267     ///////////////////////////
00268     // look if we start at root
00269     ///////////////////////////
00270     posStart = xpath.find_first_of("/");
00271     if (posStart == 0)
00272     {
00273         // yes, than we have a leading slash, remember that
00274         desc.leadingSlash = true;
00275         posStart = 1;
00276     }
00277     else
00278     {
00279         // we start right at the beginning
00280         posStart = 0;
00281     }
00282     
00283     ///////////////////////////
00284     // seperate current element
00285     ///////////////////////////
00286     // this element, till we find a path-seperator "/"
00287     posEnd = xpath.find_first_of("/", posStart);
00288     if (posEnd == -1)
00289     {
00290         // now Path-seperator found - this ist the "last" element!
00291         posEnd = xpath.size();
00292     }
00293     // the element ist the one up to the next "/" or the end of the path!
00294     desc.elementName = xpath.substr(posStart, posEnd - posStart);
00295     LOG_DEBUG_MESSAGE("path element name: "+ desc.elementName) 
00296 
00297     // next we cut the current path element from xpath
00298     // if this element was not the last - than we cut the current element from xpath
00299     if (xpath.size() - posEnd > 0)
00300     {
00301         xpath = xpath.substr(posEnd, xpath.size() - posEnd);
00302     
00303         // skip next path seperator -> so we won't start from root!
00304         posStart = xpath.find_first_of("/");
00305         if (posStart == 0)
00306         {
00307             if (xpath.size() - 1 > 0)
00308             {
00309                 xpath = xpath.substr(1, xpath.size() - 1);
00310             }
00311             else
00312             {
00313                 // last element ended with a trailing "/"
00314                 xpath = "";
00315             }
00316         }
00317     }
00318     else
00319     {
00320         // if this was the last element -> xpath is empty
00321         xpath = "";
00322     }
00323 
00324     //////////////////////////////
00325     // check for predicate information
00326     //////////////////////////////
00327     posStart = desc.elementName.find_first_of("[", posStart);
00328     if (posStart != -1)
00329     {
00330         // predicate information found
00331         // now extract predicate information
00332         std::string predicateValue = desc.elementName.substr(posStart+1, desc.elementName.size() - (posStart+1+1));
00333         desc.elementName = desc.elementName.substr(0, posStart);
00334         desc.predicatePos = atoi(predicateValue.c_str()) - 1; // since predicates start in xpath with 1
00335     }
00336 
00337     LOG_DEBUG_MESSAGE("next xpath: "+ xpath) 
00338     LOG_EXIT
00339     return desc;
00340 }
00341 
00342 TiXmlNode *CSXMLHelper::getNextNode(TiXmlNode *sourceElement, std::string &xpath)
00343 {
00344     static char *functionName="getNextNode";
00345     LOG_ENTER
00346     TiXmlNode *result = sourceElement;
00347     
00348     ////////////////////
00349     // recursion ending!
00350     ////////////////////
00351     if (xpath.size() == 0)
00352     {
00353         LOG_EXIT
00354         return result;
00355     }
00356 
00357     ////////////////////////
00358     // get next element name
00359     ////////////////////////
00360     ElementDescription elementDescription = getElementDescription(xpath);
00361 
00362     ///////////////////
00363     // is root element?
00364     ///////////////////
00365     if (elementDescription.leadingSlash)
00366     {
00367         sourceElement = mXMLdoc;
00368     }
00369 
00370     //////////////
00371     // get element
00372     //////////////
00373     TiXmlNode *nextSourceElement = sourceElement->FirstChildElement(elementDescription.elementName);
00374     if (nextSourceElement == 0)
00375     {
00376         LOG_EXIT
00377         return 0;
00378     }
00379 
00380     /////////////////////////
00381     // has predicate information?
00382     /////////////////////////
00383     if (elementDescription.predicatePos != -1)
00384     {
00385         LOG_DEBUG_MESSAGE("Predicate encountered!") 
00386         std::string name = nextSourceElement->Value();
00387         int count = 0;
00388         char tmp[10];
00389         sprintf(tmp,"%i", elementDescription.predicatePos + 1); // +1 to correct predicate value
00390         while ((nextSourceElement != 0) && (count != elementDescription.predicatePos))
00391         {
00392             nextSourceElement = nextSourceElement->NextSibling(name);
00393             if (nextSourceElement)
00394             {
00395                 count++;
00396             }
00397         }
00398         if (result == 0)
00399         {
00400             LOG_DEBUG_MESSAGE(name+"["+tmp+"] not found!") 
00401             LOG_EXIT
00402             return 0;
00403         }
00404         else
00405         {
00406             LOG_DEBUG_MESSAGE(name+"["+tmp+"] found!") 
00407         }
00408     }
00409     
00410     result = getNextNode(nextSourceElement, xpath);
00411     if (result == 0)
00412     {
00413         LOG_EXIT
00414         return 0;
00415     }
00416     std::string name = result->Value();
00417 
00418     ////////////////////////
00419     // has a xpath function?
00420     ////////////////////////
00421     if (elementDescription.function)
00422     {
00423         if (elementDescription.count)
00424         {
00425             char tmp[10];
00426             int count = 1;
00427             LOG_DEBUG_MESSAGE(((std::string)"Counting Node: ")+ result->Value()) 
00428 
00429             while (result != 0)
00430             {
00431                 result = result->NextSibling(name);
00432                 if (result)
00433                 {
00434                     count++;
00435                 }
00436             }
00437             sprintf(tmp,"%i", count);
00438             LOG_DEBUG_MESSAGE(name +" found "+ tmp +" times.") 
00439             
00440             TiFunctionReturn *ret = new TiFunctionReturn(tmp);
00441             result = ret;
00442             // a node with a value  of count :-)
00443         }
00444     }
00445 
00446     LOG_EXIT
00447     return result;
00448 }
00449 
00450 TiXmlNode *CSXMLHelper::getXPathResult(const std::string &xpath)
00451 {
00452     static char *functionName="getXPathResult";
00453     static char h[1025];
00454     LOG_ENTER
00455     h[0] = 0;
00456     strcat(h, "normalize-space(");
00457     strcat(h, xpath.c_str());
00458     strcat(h, ")");
00459 
00460 //  LOG_DEBUG_MESSAGE("------------------- Start XPath -------------------") 
00461 
00462     std::string path = xpath;
00463 
00464     TiXmlNode *result = 0;
00465     result = getNextNode(mXMLsource, path);
00466     if (result==0)
00467     {
00468 //      LOG_DEBUG_MESSAGE(((std::string)"Result: null")) 
00469         if (!xpath.find("count"))
00470         {
00471             LOG_DEBUG_MESSAGE(xpath + "->0" )
00472         }
00473         else
00474         {
00475             LOG_DEBUG_MESSAGE(xpath + "->" ) 
00476         }
00477         LOG_EXIT
00478         return 0;
00479     }
00480 
00481     if (!result->NoChildren()) // than most probably a function
00482     {
00483         result = result->FirstChild();
00484     }
00485     LOG_DEBUG_MESSAGE(xpath + "->" + lookUp(result->Value()) ) 
00486 
00487     LOG_EXIT
00488     return result;
00489 }
00490 
00491 int CSXMLHelper::getError(void)
00492 {
00493     return mError;
00494 }
00495 
00496 std::string CSXMLHelper::getErrorMessage(void)
00497 {
00498     return mErrorMessageString;
00499 }
00500 
00501 std::string CSXMLHelper::toAscii(const TiXmlNode &node)
00502 {
00503     static char *functionName="toAscii";
00504     return lookUp(node.Value());
00505 }
00506 
00507 int CSXMLHelper::toInt(const TiXmlNode &node)
00508 {
00509     static char *functionName="toInt";
00510     std::string value = node.Value();
00511     int result;
00512     result = atoi(lookUp(value).c_str());
00513     
00514     return result;
00515 }
00516 
00517 std::string replace(const std::string &key, const std::string &predicate, const std::string &value);
00518 
00519 // Ersetze in dem Übergeben Ausdruck alle Entities <-> mit ihren Werten (Recursiv)
00520 std::string CSXMLHelper::lookUp(const std::string &key)
00521 {
00522     static char *functionName="lookUp";
00523     LOG_ENTER
00524     std::string newKey = key;
00525     std::string p = findPredicate(key);
00526     if (p.size() == 0)
00527     {
00528         LOG_EXIT
00529         return newKey;
00530     }
00531 
00532     do
00533     {
00534         std::string value;
00535         EntityMap::iterator iter = mEntityMap.find(p);
00536         if (iter != mEntityMap.end())
00537         {
00538             value = iter->second;
00539         }
00540         newKey = replace(newKey, p,  value);
00541         p = findPredicate(newKey);
00542     } while (p.size() > 0);
00543         
00544     LOG_EXIT
00545     return newKey;
00546 }
00547 
00548 std::string CSXMLHelper::findPredicate(const std::string &key)
00549 {
00550     EntityMap::iterator iter = mEntityMap.begin();
00551     while (iter != mEntityMap.end())
00552     {
00553         if (strstr(key.c_str(), iter->first.c_str()))
00554         {
00555             return iter->first;
00556         }
00557         iter++;
00558     }
00559     return "";
00560 }
00561 
00562 // wo, was, womit
00563 std::string replace(const std::string &key, const std::string &predicate, const std::string &value)
00564 {
00565     std::string newKey;
00566     std::string rest;
00567     int posStart = strstr(key.c_str(), predicate.c_str()) - key.c_str();
00568     int len = predicate.size();
00569     if (posStart != 0)
00570     {
00571         newKey = key.substr(0, posStart);
00572     }
00573     else
00574     {
00575         newKey = key.substr(len, key.size()-len);
00576     }
00577     newKey = newKey +value;
00578     
00579     if (posStart+len < key.size())
00580     {
00581         newKey = newKey + key.substr(posStart + len, key.size() - (posStart + len) );
00582     }
00583 
00584     return newKey;
00585 }
00586 
00587 #endif // USE_TINYXML

Generated on Wed Jul 14 00:43:43 2004 for CSLib by doxygen 1.3.6