Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-05-27 01:56:21

0001 #include <iostream>
0002 //#include <algorithm>
0003 //#include <utility>
0004 using namespace std;
0005 
0006 #include "L1Trigger/L1TCommon/interface/XmlConfigParser.h"
0007 #include "L1Trigger/L1TCommon/interface/TriggerSystem.h"
0008 
0009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0010 #include "Utilities/Xerces/interface/XercesStrUtils.h"
0011 #include "Utilities/Xerces/interface/Xerces.h"
0012 
0013 #include "xercesc/util/PlatformUtils.hpp"
0014 
0015 XERCES_CPP_NAMESPACE_USE
0016 
0017 using namespace l1t;
0018 
0019 //inline std::string _toString(XMLCh const* toTranscode) {
0020 //    char *c = xercesc::XMLString::transcode(toTranscode);
0021 //    std::string retval = c;
0022 //    xercesc::XMLString::release(&c);
0023 //    return retval;
0024 //}
0025 //
0026 //inline XMLCh* _toDOMS(std::string temp) {
0027 //  XMLCh* buff = XMLString::transcode(temp.c_str());
0028 //  return  buff;
0029 //}
0030 
0031 XmlConfigParser::XmlConfigParser()
0032     : kTagHw(nullptr),
0033       kTagAlgo(nullptr),
0034       kTagRunSettings(nullptr),
0035       kTagDb(nullptr),
0036       kTagKey(nullptr),
0037       kTagLoad(nullptr),
0038       kTagContext(nullptr),
0039       kTagParam(nullptr),
0040       kTagMask(nullptr),
0041       kTagDisable(nullptr),
0042       kTagExclBoards(nullptr),
0043       kTagExclude(nullptr),
0044       kTagColumns(nullptr),
0045       kTagTypes(nullptr),
0046       kTagRow(nullptr),
0047       kTagProcessor(nullptr),
0048       kTagRole(nullptr),
0049       kTagCrate(nullptr),
0050       kTagSlot(nullptr),
0051       kTagDaqTtc(nullptr),
0052       kAttrId(nullptr),
0053       kAttrType(nullptr),
0054       kAttrDelim(nullptr),
0055       kAttrModule(nullptr),
0056       kTypeTable("table") {
0057   cms::concurrency::xercesInitialize();
0058 
0059   kTagHw = XMLString::transcode("system");
0060   kTagAlgo = XMLString::transcode("algo");
0061   kTagRunSettings = XMLString::transcode("run-settings");
0062   kTagDb = XMLString::transcode("db");
0063   kTagKey = XMLString::transcode("key");
0064   kTagLoad = XMLString::transcode("load");
0065   kTagContext = XMLString::transcode("context");
0066   kTagParam = XMLString::transcode("param");
0067   kTagMask = XMLString::transcode("mask");
0068   kTagDisable = XMLString::transcode("disable");
0069   kTagExclBoards = XMLString::transcode("excluded-boards");
0070   kTagExclude = XMLString::transcode("exclude");
0071   kTagColumns = XMLString::transcode("columns");
0072   kTagTypes = XMLString::transcode("types");
0073   kTagRow = XMLString::transcode("row");
0074   kTagProcessor = XMLString::transcode("processor");
0075   kTagRole = XMLString::transcode("role");
0076   kTagCrate = XMLString::transcode("crate");
0077   kTagSlot = XMLString::transcode("slot");
0078   kTagDaqTtc = XMLString::transcode("daqttc-mgr");
0079   kAttrId = XMLString::transcode("id");
0080   kAttrType = XMLString::transcode("type");
0081   kAttrDelim = XMLString::transcode("delimiter");
0082   kAttrModule = XMLString::transcode("module");
0083 
0084   ///Initialise XML parser
0085   parser_ = new XercesDOMParser();
0086   parser_->setValidationScheme(XercesDOMParser::Val_Auto);
0087   parser_->setDoNamespaces(false);
0088 
0089   doc_ = nullptr;
0090 }
0091 
0092 XmlConfigParser::XmlConfigParser(DOMDocument* doc)
0093     : kTagHw(nullptr),
0094       kTagAlgo(nullptr),
0095       kTagRunSettings(nullptr),
0096       kTagDb(nullptr),
0097       kTagKey(nullptr),
0098       kTagLoad(nullptr),
0099       kTagContext(nullptr),
0100       kTagParam(nullptr),
0101       kTagMask(nullptr),
0102       kTagDisable(nullptr),
0103       kTagExclBoards(nullptr),
0104       kTagExclude(nullptr),
0105       kTagColumns(nullptr),
0106       kTagTypes(nullptr),
0107       kTagRow(nullptr),
0108       kTagProcessor(nullptr),
0109       kTagRole(nullptr),
0110       kTagCrate(nullptr),
0111       kTagSlot(nullptr),
0112       kTagDaqTtc(nullptr),
0113       kAttrId(nullptr),
0114       kAttrType(nullptr),
0115       kAttrDelim(nullptr),
0116       kAttrModule(nullptr),
0117       kTypeTable("table") {
0118   cms::concurrency::xercesInitialize();
0119 
0120   kTagHw = XMLString::transcode("system");
0121   kTagAlgo = XMLString::transcode("algo");
0122   kTagRunSettings = XMLString::transcode("run-settings");
0123   kTagDb = XMLString::transcode("db");
0124   kTagKey = XMLString::transcode("key");
0125   kTagLoad = XMLString::transcode("load");
0126   kTagContext = XMLString::transcode("context");
0127   kTagParam = XMLString::transcode("param");
0128   kTagMask = XMLString::transcode("mask");
0129   kTagDisable = XMLString::transcode("disable");
0130   kTagExclBoards = XMLString::transcode("excluded-boards");
0131   kTagExclude = XMLString::transcode("exclude");
0132   kTagColumns = XMLString::transcode("columns");
0133   kTagTypes = XMLString::transcode("types");
0134   kTagRow = XMLString::transcode("row");
0135   kTagProcessor = XMLString::transcode("processor");
0136   kTagRole = XMLString::transcode("role");
0137   kTagCrate = XMLString::transcode("crate");
0138   kTagSlot = XMLString::transcode("slot");
0139   kTagDaqTtc = XMLString::transcode("daqttc-mgr");
0140   kAttrId = XMLString::transcode("id");
0141   kAttrType = XMLString::transcode("type");
0142   kAttrDelim = XMLString::transcode("delimiter");
0143   kAttrModule = XMLString::transcode("module");
0144 
0145   parser_ = nullptr;
0146   doc_ = doc;
0147 }
0148 
0149 XmlConfigParser::~XmlConfigParser() {
0150   delete parser_;
0151   cms::concurrency::xercesTerminate();
0152 }
0153 
0154 void XmlConfigParser::readDOMFromString(const std::string& str, DOMDocument*& doc) {
0155   MemBufInputSource xmlstr_buf((const XMLByte*)(str.c_str()), str.size(), "xmlstrbuf");
0156   parser_->parse(xmlstr_buf);
0157   doc = parser_->getDocument();
0158   assert(doc);
0159 }
0160 
0161 void XmlConfigParser::readDOMFromString(const std::string& str) {
0162   MemBufInputSource xmlstr_buf((const XMLByte*)(str.c_str()), str.size(), "xmlstrbuf");
0163   parser_->parse(xmlstr_buf);
0164   doc_ = parser_->getDocument();
0165   assert(doc_);
0166 }
0167 
0168 void XmlConfigParser::readDOMFromFile(const std::string& fName, DOMDocument*& doc) {
0169   parser_->parse(fName.c_str());
0170   doc = parser_->getDocument();
0171 
0172   if (!doc) {
0173     edm::LogError("XmlConfigParser") << "Could not parse file " << fName << "\n";
0174   }
0175 
0176   assert(doc);
0177 }
0178 
0179 void XmlConfigParser::readDOMFromFile(const std::string& fName) {
0180   parser_->parse(fName.c_str());
0181   doc_ = parser_->getDocument();
0182 
0183   if (!doc_) {
0184     edm::LogError("XmlConfigParser") << "Could not parse file " << fName << "\n";
0185   }
0186 
0187   assert(doc_);
0188 }
0189 
0190 void XmlConfigParser::readRootElement(TriggerSystem& aTriggerSystem, const std::string& sysId) {
0191   DOMElement* rootElement = doc_->getDocumentElement();
0192   if (rootElement) {
0193     if (rootElement->getNodeType() == DOMNode::ELEMENT_NODE) {
0194       readElement(rootElement, aTriggerSystem, sysId);
0195     }
0196   } else {
0197     throw std::runtime_error("No xml root element found");
0198   }
0199 }
0200 
0201 void XmlConfigParser::readElement(const DOMElement* element, TriggerSystem& aTriggerSystem, const std::string& sysId) {
0202   if (XMLString::equals(element->getTagName(), kTagHw)) {
0203     // in case this is a HW description
0204     readHwDescription(element, aTriggerSystem, sysId);
0205   } else if (XMLString::equals(element->getTagName(), kTagAlgo) ||
0206              XMLString::equals(element->getTagName(), kTagRunSettings)) {
0207     // in case this is a configuration snippet
0208     readContext(element, sysId, aTriggerSystem);
0209   }
0210 }
0211 
0212 void XmlConfigParser::readHwDescription(const DOMElement* element,
0213                                         TriggerSystem& aTriggerSystem,
0214                                         const std::string& sysId) {
0215   // if sysId == "" set the systemId of the trigsystem from the xml sytem id
0216   if (!sysId.empty()) {
0217     std::string sId = cms::xerces::toString(element->getAttribute(kAttrId));
0218     pruneString(sId);
0219     if (sId != sysId)
0220       return;
0221   }
0222 
0223   char* sysId_ = xercesc::XMLString::transcode(element->getAttribute(kAttrId));
0224   aTriggerSystem.setSystemId(pruneString(sysId_));
0225   xercesc::XMLString::release(&sysId_);
0226 
0227   // handle processors
0228   DOMNodeList* processors = element->getElementsByTagName(kTagProcessor);
0229   XMLSize_t nodeCount = processors->getLength();
0230   for (XMLSize_t xx = 0; xx < nodeCount; ++xx) {
0231     DOMNode* currentNode = processors->item(xx);
0232     if (currentNode->getNodeType() && currentNode->getNodeType() == DOMNode::ELEMENT_NODE) {  //no null and is element
0233       DOMElement* currentElement = static_cast<DOMElement*>(currentNode);
0234 
0235       string proc = cms::xerces::toString(currentElement->getAttribute(kAttrId));
0236       pruneString(proc);
0237       string role, crate, slot;
0238 
0239       DOMNodeList* roles = currentElement->getElementsByTagName(kTagRole);
0240       // roles of this processor (should be only one)
0241       if (roles->getLength() != 1)
0242         throw std::runtime_error(string("Configutration specify not exactly one role"));
0243       //      for (XMLSize_t i = 0; i < roles->getLength(); ++i) {
0244       {
0245         XMLSize_t i = 0;
0246         DOMNodeList* roleChilds = roles->item(i)->getChildNodes();
0247         if (roleChilds->getLength() != 1)
0248           throw std::runtime_error(string("Configutration specify not exactly one role"));
0249         {
0250           //        for (XMLSize_t j = 0; j < roleChilds->getLength(); ++j) {
0251           XMLSize_t j = 0;
0252           if (roleChilds->item(j)->getNodeType() == DOMNode::TEXT_NODE) {
0253             role = cms::xerces::toString(roleChilds->item(j)->getNodeValue());
0254             pruneString(role);
0255           }
0256         }
0257       }
0258 
0259       DOMNodeList* crates = currentElement->getElementsByTagName(kTagCrate);
0260       // crates of this processor (should be only one)
0261       if (crates->getLength() != 1)
0262         throw std::runtime_error(string("Configutration specify not exactly one crate"));
0263       //      for (XMLSize_t i = 0; i < crates->getLength(); ++i) {
0264       {
0265         XMLSize_t i = 0;
0266         DOMNodeList* crateChilds = crates->item(i)->getChildNodes();
0267         if (crateChilds->getLength() != 1)
0268           throw std::runtime_error(string("Configutration specify not exactly one crate"));
0269         {
0270           XMLSize_t j = 0;
0271           //        for (XMLSize_t j = 0; j < crateChilds->getLength(); ++j) {
0272           if (crateChilds->item(j)->getNodeType() == DOMNode::TEXT_NODE) {
0273             crate = cms::xerces::toString(crateChilds->item(j)->getNodeValue());
0274             pruneString(crate);
0275           }
0276         }
0277       }
0278 
0279       DOMNodeList* slots = currentElement->getElementsByTagName(kTagSlot);
0280       // slots of this processor (should be only one)
0281       if (slots->getLength() != 1)
0282         throw std::runtime_error(string("Configutration specify not exactly one slot"));
0283       //      for (XMLSize_t i = 0; i < slots->getLength(); ++i) {
0284       {
0285         XMLSize_t i = 0;
0286         DOMNodeList* slotChilds = slots->item(i)->getChildNodes();
0287         if (slotChilds->getLength() != 1)
0288           throw std::runtime_error(string("Configutration specify not exactly one slot"));
0289         //        for (XMLSize_t j = 0; j < slotChilds->getLength(); ++j) {
0290         {
0291           XMLSize_t j = 0;
0292           if (slotChilds->item(j)->getNodeType() == DOMNode::TEXT_NODE) {
0293             slot = cms::xerces::toString(slotChilds->item(j)->getNodeValue());
0294             pruneString(slot);
0295           }
0296         }
0297       }
0298 
0299       aTriggerSystem.addProcessor(proc.c_str(), role.c_str(), crate.c_str(), slot.c_str());
0300     }
0301   }
0302 
0303   // handle DAQ TTC managers
0304   DOMNodeList* daqttcs = element->getElementsByTagName(kTagDaqTtc);
0305   nodeCount = daqttcs->getLength();
0306   for (XMLSize_t xx = 0; xx < nodeCount; ++xx) {
0307     DOMNode* currentNode = daqttcs->item(xx);
0308     if (currentNode->getNodeType() && currentNode->getNodeType() == DOMNode::ELEMENT_NODE) {  //no null and is element
0309       DOMElement* currentElement = static_cast<DOMElement*>(currentNode);
0310       string daqttc = cms::xerces::toString(currentElement->getAttribute(kAttrId));
0311       string role, crate;
0312 
0313       DOMNodeList* roles = currentElement->getElementsByTagName(kTagRole);
0314       // roles of this DAQ TTC manager (should be only one)
0315       if (roles->getLength() != 1)
0316         throw std::runtime_error(string("Configutration specify not exactly one role"));
0317       //      for (XMLSize_t i = 0; i < roles->getLength(); ++i) {
0318       {
0319         XMLSize_t i = 0;
0320         DOMNodeList* roleChilds = roles->item(i)->getChildNodes();
0321         if (roleChilds->getLength() != 1)
0322           throw std::runtime_error(string("Configutration specify not exactly one role"));
0323         //        for (XMLSize_t j = 0; j < roleChilds->getLength(); ++j) {
0324         {
0325           XMLSize_t j = 0;
0326           if (roleChilds->item(j)->getNodeType() == DOMNode::TEXT_NODE) {
0327             role = cms::xerces::toString(roleChilds->item(j)->getNodeValue());
0328             pruneString(role);
0329           }
0330         }
0331       }
0332 
0333       DOMNodeList* crates = currentElement->getElementsByTagName(kTagCrate);
0334       // crates of this DAQ TTC manager (should be only one)
0335       if (crates->getLength() != 1)
0336         throw std::runtime_error(string("Configutration specify not exactly one crate"));
0337       //      for (XMLSize_t i = 0; i < crates->getLength(); ++i) {
0338       {
0339         XMLSize_t i = 0;
0340         DOMNodeList* crateChilds = crates->item(i)->getChildNodes();
0341         if (crateChilds->getLength() != 1)
0342           throw std::runtime_error(string("Configutration specify not exactly one crate"));
0343         //        for (XMLSize_t j = 0; j < crateChilds->getLength(); ++j) {
0344         {
0345           XMLSize_t j = 0;
0346           if (crateChilds->item(j)->getNodeType() == DOMNode::TEXT_NODE) {
0347             crate = cms::xerces::toString(crateChilds->item(j)->getNodeValue());
0348             pruneString(crate);
0349           }
0350         }
0351       }
0352 
0353       aTriggerSystem.addDaq(daqttc.c_str(), role.c_str(), crate.c_str());
0354     }
0355   }
0356 
0357   // handle excluded boards
0358   DOMNodeList* exclBoards = element->getElementsByTagName(kTagExclBoards);
0359   for (XMLSize_t xx = 0; xx < exclBoards->getLength(); ++xx) {
0360     DOMElement* exclBoardElem = static_cast<DOMElement*>(exclBoards->item(xx));
0361 
0362     for (DOMElement* elem = static_cast<DOMElement*>(exclBoardElem->getFirstChild()); elem;
0363          elem = static_cast<DOMElement*>(elem->getNextSibling())) {
0364       if (elem->getNodeType() == DOMNode::ELEMENT_NODE) {
0365         if (XMLString::equals(elem->getTagName(), kTagExclude)) {
0366           // found an excluded board
0367           std::string id = cms::xerces::toString(elem->getAttribute(kAttrId));
0368           pruneString(id);
0369           aTriggerSystem.disableProcOrRoleOrDaq(
0370               id.c_str());  // handle in the same way as disabled ids in the run-settings
0371         }
0372       }
0373     }
0374   }
0375 }
0376 
0377 void XmlConfigParser::readContext(const DOMElement* element, const std::string& sysId, TriggerSystem& aTriggerSystem) {
0378   std::string systemId = sysId;
0379   if (systemId.empty()) {
0380     systemId = aTriggerSystem.systemId();
0381   }
0382   if (cms::xerces::toString(element->getAttribute(kAttrId)) == systemId) {
0383     DOMNodeList* contextElements = element->getElementsByTagName(kTagContext);
0384 
0385     for (XMLSize_t i = 0; i < contextElements->getLength(); ++i) {
0386       DOMElement* contextElement = static_cast<DOMElement*>(contextElements->item(i));
0387       std::string contextId = cms::xerces::toString(contextElement->getAttribute(kAttrId));
0388       pruneString(contextId);
0389 
0390       for (DOMElement* elem = static_cast<DOMElement*>(contextElement->getFirstChild()); elem;
0391            elem = static_cast<DOMElement*>(elem->getNextSibling())) {
0392         if (elem->getNodeType() == DOMNode::ELEMENT_NODE) {
0393           if (XMLString::equals(elem->getTagName(), kTagParam)) {
0394             // found a parameter
0395             string id = cms::xerces::toString(elem->getAttribute(kAttrId));
0396             string type = cms::xerces::toString(elem->getAttribute(kAttrType));
0397             string delim = cms::xerces::toString(elem->getAttribute(kAttrDelim));
0398             pruneString(id);
0399             pruneString(type);
0400             pruneString(delim);
0401 
0402             // the type table needs special treatment since it consists of child nodes
0403             if (type == kTypeTable) {
0404               // get the columns string
0405               std::string columnsStr = "";
0406               DOMNodeList* colElements = elem->getElementsByTagName(kTagColumns);
0407               for (XMLSize_t j = 0; j < colElements->getLength(); ++j) {
0408                 DOMNodeList* colChilds = colElements->item(j)->getChildNodes();
0409                 for (XMLSize_t k = 0; k < colChilds->getLength(); ++k) {
0410                   if (colChilds->item(k)->getNodeType() == DOMNode::TEXT_NODE) {
0411                     ///                    columnsStr = cms::xerces::toString(colChilds->item(k)->getNodeValue());
0412                     ///                    pruneString(columnsStr);
0413                     char* cStr = xercesc::XMLString::transcode(colChilds->item(k)->getNodeValue());
0414                     char *saveptr, first = 1;
0415                     for (char* item = strtok_r(cStr, delim.c_str(), &saveptr); item != nullptr;
0416                          item = strtok_r(nullptr, delim.c_str(), &saveptr), first = 0)
0417                       columnsStr += (first ? std::string("") : delim) + pruneString(item);
0418                     xercesc::XMLString::release(&cStr);
0419                   }
0420                 }
0421               }
0422 
0423               // get the column type string
0424               std::string typesStr = "";
0425               DOMNodeList* colTypesElements = elem->getElementsByTagName(kTagTypes);
0426               for (XMLSize_t j = 0; j < colTypesElements->getLength(); ++j) {
0427                 DOMNodeList* colTypesChilds = colTypesElements->item(j)->getChildNodes();
0428                 for (XMLSize_t k = 0; k < colTypesChilds->getLength(); ++k) {
0429                   if (colTypesChilds->item(k)->getNodeType() == DOMNode::TEXT_NODE) {
0430                     ///                    typesStr = cms::xerces::toString(colTypesChilds->item(k)->getNodeValue());
0431                     ///                    pruneString(typesStr);
0432                     char* tStr = xercesc::XMLString::transcode(colTypesChilds->item(k)->getNodeValue());
0433                     char *saveptr, first = 1;
0434                     for (char* item = strtok_r(tStr, delim.c_str(), &saveptr); item != nullptr;
0435                          item = strtok_r(nullptr, delim.c_str(), &saveptr), first = 0)
0436                       typesStr += (first ? std::string("") : delim) + pruneString(item);
0437                     xercesc::XMLString::release(&tStr);
0438                   }
0439                 }
0440               }
0441 
0442               // get the rows
0443               std::vector<std::string> rowStrs;
0444               DOMNodeList* rowElements = elem->getElementsByTagName(kTagRow);
0445               for (XMLSize_t j = 0; j < rowElements->getLength(); ++j) {
0446                 DOMNodeList* rowChilds = rowElements->item(j)->getChildNodes();
0447                 for (XMLSize_t k = 0; k < rowChilds->getLength(); ++k) {
0448                   if (rowChilds->item(k)->getNodeType() == DOMNode::TEXT_NODE) {
0449                     ///                    std::string rowStr = cms::xerces::toString(rowChilds->item(k)->getNodeValue());
0450                     ///                    pruneString(rowStr);
0451                     ///                    rowStrs.push_back(rowStr);
0452                     char* rStr = xercesc::XMLString::transcode(rowChilds->item(k)->getNodeValue());
0453                     char *saveptr, first = 1;
0454                     std::string row;
0455                     for (char* item = strtok_r(rStr, delim.c_str(), &saveptr); item != nullptr;
0456                          item = strtok_r(nullptr, delim.c_str(), &saveptr), first = 0)
0457                       row += (first ? std::string("") : delim) + pruneString(item);
0458 
0459                     rowStrs.push_back(row);
0460                     xercesc::XMLString::release(&rStr);
0461                   }
0462                 }
0463               }
0464               //         std::cout << "param element node with id attribute " << id << " and type attribute " << typesStr << std::endl;
0465               aTriggerSystem.addTable(
0466                   id.c_str(), contextId.c_str(), columnsStr.c_str(), typesStr.c_str(), rowStrs, delim.c_str());
0467 
0468             } else {  // all types other than table
0469               std::string value = "";
0470               DOMNodeList* valNodes = elem->getChildNodes();
0471               for (XMLSize_t j = 0; j < valNodes->getLength(); ++j) {
0472                 if (valNodes->item(j)->getNodeType() == DOMNode::TEXT_NODE) {
0473                   value += cms::xerces::toString(valNodes->item(j)->getNodeValue());  // should we prune?
0474                 }
0475               }
0476 
0477               // strip leading and trailing line breaks and spaces
0478               pruneString(value);
0479 
0480               //              std::cout << "param element node with id attribute " << id << " and type attribute " << type << " with value: [" << value << "]" << std::endl;
0481               aTriggerSystem.addParameter(id.c_str(), contextId.c_str(), type.c_str(), value.c_str(), delim.c_str());
0482             }
0483 
0484           } else if (XMLString::equals(elem->getTagName(), kTagMask)) {
0485             // found a Mask
0486             std::string id = cms::xerces::toString(elem->getAttribute(kAttrId));
0487             //std::cout << "Mask element node with id attribute " << id << std::endl;
0488             pruneString(id);
0489             aTriggerSystem.addMask(id.c_str(), contextId.c_str());
0490 
0491           } else if (XMLString::equals(elem->getTagName(), kTagDisable)) {
0492             // found a disable
0493             std::string id = cms::xerces::toString(elem->getAttribute(kAttrId));
0494             pruneString(id);
0495             aTriggerSystem.disableProcOrRoleOrDaq(id.c_str());
0496           }
0497         }
0498       }
0499     }
0500   }
0501 }
0502 
0503 void XmlConfigParser::readContexts(const std::string& key, const std::string& sysId, TriggerSystem& aTriggerSystem) {
0504   DOMElement* keyElement = getKeyElement(key);
0505   if (keyElement) {
0506     for (DOMElement* elem = static_cast<DOMElement*>(keyElement->getFirstChild()); elem;
0507          elem = static_cast<DOMElement*>(elem->getNextSibling())) {
0508       if (elem->getNodeType() == DOMNode::ELEMENT_NODE) {
0509         if (XMLString::equals(elem->getTagName(), kTagAlgo) || XMLString::equals(elem->getTagName(), kTagRunSettings)) {
0510           readContext(elem, sysId, aTriggerSystem);
0511         }
0512       }
0513     }
0514   } else {
0515     throw std::runtime_error("Key not found: " + key);
0516   }
0517 }
0518 
0519 DOMElement* XmlConfigParser::getKeyElement(const std::string& key) {
0520   DOMElement* rootElement = doc_->getDocumentElement();
0521   if (XMLString::equals(rootElement->getTagName(), kTagDb)) {
0522     DOMNodeList* keyElements = rootElement->getElementsByTagName(kTagKey);
0523 
0524     for (XMLSize_t i = 0; i < keyElements->getLength(); ++i) {
0525       DOMElement* keyElement = static_cast<DOMElement*>(keyElements->item(i));
0526       if (cms::xerces::toString(keyElement->getAttribute(kAttrId)) == key) {  // we found the key we were looking for
0527         return keyElement;
0528       }
0529     }
0530   }
0531   return nullptr;
0532 }
0533 
0534 void XmlConfigParser::buildGlobalDoc(const std::string& key, const std::string& topPath) {
0535   DOMElement* keyElement = getKeyElement(key);
0536   if (keyElement) {
0537     DOMNodeList* loadElements = keyElement->getElementsByTagName(kTagLoad);
0538     for (XMLSize_t i = 0; i < loadElements->getLength(); ++i) {
0539       DOMElement* loadElement = static_cast<DOMElement*>(loadElements->item(i));
0540       std::string fileName = cms::xerces::toString(loadElement->getAttribute(kAttrModule));
0541       if (fileName.find('/') != 0) {  // load element has a relative path
0542         // build an absolute path with directory of top xml file
0543         size_t pos;
0544         std::string topDir = "";
0545         pos = topPath.find_last_of('/');
0546         if (pos != std::string::npos) {
0547           topDir = topPath.substr(0, pos + 1);
0548         }
0549         fileName = topDir + fileName;
0550       }
0551       //std::cout << "loading file " << fileName << std::endl;
0552       DOMDocument* subDoc = nullptr;
0553       readDOMFromFile(fileName, subDoc);
0554       if (subDoc) {
0555         appendNodesFromSubDoc(keyElement, subDoc);
0556       }
0557     }
0558   }
0559 }
0560 
0561 void XmlConfigParser::appendNodesFromSubDoc(DOMNode* parentNode, DOMDocument* subDoc) {
0562   DOMElement* subDocRootElement = subDoc->getDocumentElement();
0563   //std::cout << "root element tag: " << cms::xerces::toString(subDocRootElement->getTagName()) << std::endl;
0564   if (XMLString::equals(subDocRootElement->getTagName(), kTagAlgo) ||
0565       XMLString::equals(subDocRootElement->getTagName(), kTagRunSettings)) {
0566     DOMNode* importedNode = doc_->importNode(subDocRootElement, true);
0567     parentNode->appendChild(importedNode);
0568   }
0569 }
0570 
0571 // the small static look up table below indicates in O(1) time if the symbol is '\n', (ascii code 10) '\t' (code 9), or ' ' (code 32)
0572 const char XmlConfigParser_reject_symbols[256] = {
0573     0, 0, 0, 0, 0, 0, 0, 0, 0, 1,                                // '\n'
0574     1, 0, 0, 0, 0, 0, 0, 0, 0, 0,                                // '\t'
0575     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,  // ' '
0576     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0577     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0578     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0579     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0580     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0581     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
0582 
0583 char* XmlConfigParser::pruneString(char*& str) {
0584   size_t alphanumBegin = 0, alphanumEnd = strlen(str) - 1;
0585 
0586   while (str[alphanumBegin] && XmlConfigParser_reject_symbols[unsigned(str[alphanumBegin])])
0587     alphanumBegin++;
0588   while (alphanumEnd >= alphanumBegin && XmlConfigParser_reject_symbols[unsigned(str[alphanumEnd])])
0589     alphanumEnd--;
0590 
0591   str[alphanumEnd + 1] = '\0';
0592   return str + alphanumBegin;
0593 }
0594 
0595 void XmlConfigParser::pruneString(std::string& str) {
0596   std::size_t alphanumBegin = str.find_first_not_of("\n\t ");
0597   std::size_t alphanumEnd = str.find_last_not_of("\n\t ");
0598   if (alphanumBegin != std::string::npos) {
0599     if (alphanumEnd != std::string::npos) {
0600       str = str.substr(alphanumBegin, alphanumEnd - alphanumBegin + 1);
0601     } else {
0602       str = str.substr(alphanumBegin);
0603     }
0604   }
0605 }