$treeview $search $mathjax $extrastylesheet
otsdaq
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h" 00002 #include "otsdaq-core/Macros/CoutMacros.h" 00003 #include "otsdaq-core/MessageFacility/MessageFacility.h" 00004 #include "otsdaq-core/XmlUtilities/ConvertFromXML.h" 00005 #include "otsdaq-core/XmlUtilities/ConvertToXML.h" 00006 00007 #include <stdexcept> 00008 #include <xercesc/dom/DOM.hpp> 00009 #include <xercesc/dom/DOMDocument.hpp> 00010 #include <xercesc/dom/DOMDocumentType.hpp> 00011 #include <xercesc/dom/DOMElement.hpp> 00012 #include <xercesc/dom/DOMImplementation.hpp> 00013 #include <xercesc/dom/DOMImplementationLS.hpp> 00014 #include <xercesc/dom/DOMImplementationRegistry.hpp> 00015 //#include <xercesc/dom/DOMLSSerializer.hpp> 00016 //#include <xercesc/dom/DOMLSOutput.hpp> 00017 #include <xercesc/dom/DOMNodeIterator.hpp> 00018 #include <xercesc/dom/DOMNodeList.hpp> 00019 #include <xercesc/dom/DOMText.hpp> 00020 #include <xercesc/validators/common/Grammar.hpp> 00021 00022 #include <xercesc/parsers/XercesDOMParser.hpp> 00023 #include <xercesc/util/XMLUni.hpp> 00024 #include <xercesc/util/XercesDefs.hpp> 00025 00026 #include <xercesc/framework/LocalFileFormatTarget.hpp> 00027 #include <xercesc/util/OutOfMemoryException.hpp> 00028 00029 #include <iostream> 00030 #include <list> 00031 #include <sstream> 00032 00033 #include <errno.h> 00034 #include <sys/stat.h> 00035 #include <sys/types.h> 00036 #include <unistd.h> 00037 00038 using namespace ots; 00039 00040 //============================================================================== 00041 // HttpXmlDocument::HttpXmlDocument 00042 // Constructor to initialize XML theDocument_ for ots. 00043 // The XML theDocument_ can be written to xdaq output stream to client 00044 // 00045 // theDocument_ result: 00046 // <ROOT> 00047 // <HEADER> 00048 // --optional with value <CookieCode>, <DisplayName> added in constructor 00049 // <DATA> 00050 // --optional data elements with value and any field name 00051 // 00052 HttpXmlDocument::HttpXmlDocument(std::string cookieCode, std::string displayName) 00053 : XmlDocument("ROOT") 00054 , headerElement_(0) 00055 , dataElement_(0) 00056 , headerTagName_("HEADER") 00057 , dataTagName_("DATA") 00058 , cookieCodeTagName_("CookieCode") 00059 , displayNameTagName_("DisplayName") 00060 { 00061 // std::cout << __COUT_HDR_FL__ << "in" << std::endl; 00062 //<HEADER> 00063 if(cookieCode != "" || displayName != "") // add header 00064 { 00065 headerElement_ = theDocument_->createElement(CONVERT_TO_XML(headerTagName_)); 00066 rootElement_->appendChild(headerElement_); 00067 if(cookieCode != "") // add cookie code to header 00068 addTextElementToParent(cookieCodeTagName_, cookieCode, headerElement_); 00069 if(displayName != "") // add display name to header 00070 addTextElementToParent(displayNameTagName_, displayName, headerElement_); 00071 } 00072 00073 //<DATA> 00074 dataElement_ = theDocument_->createElement(CONVERT_TO_XML(dataTagName_)); 00075 rootElement_->appendChild(dataElement_); 00076 // std::cout << __COUT_HDR_FL__ << "out" << std::endl; 00077 } 00078 00079 //============================================================================== 00080 HttpXmlDocument::HttpXmlDocument(const HttpXmlDocument& doc) 00081 : XmlDocument(doc) 00082 , headerElement_(0) 00083 , dataElement_(0) 00084 , headerTagName_(doc.headerTagName_) 00085 , dataTagName_(doc.dataTagName_) 00086 , cookieCodeTagName_(doc.cookieCodeTagName_) 00087 , displayNameTagName_(doc.displayNameTagName_) 00088 { 00089 // std::cout << __COUT_HDR_FL__ << "in" << std::endl; 00090 *this = doc; 00091 // std::cout << __COUT_HDR_FL__ << "out" << std::endl; 00092 } 00093 00094 //============================================================================== 00095 HttpXmlDocument& HttpXmlDocument::operator=(const HttpXmlDocument& doc) 00096 { 00097 // std::cout << __COUT_HDR_FL__ << "in" << std::endl; 00098 recursiveElementCopy(doc.rootElement_, rootElement_); 00099 if(doc.headerElement_ != 0) 00100 headerElement_ = (xercesc::DOMElement*)rootElement_ 00101 ->getElementsByTagName(CONVERT_TO_XML(headerTagName_)) 00102 ->item(0); 00103 dataElement_ = (xercesc::DOMElement*)rootElement_ 00104 ->getElementsByTagName(CONVERT_TO_XML(dataTagName_)) 00105 ->item(0); 00106 // std::cout << __COUT_HDR_FL__ << "out" << std::endl; 00107 return *this; 00108 } 00109 00110 //============================================================================== 00111 HttpXmlDocument::~HttpXmlDocument(void) {} 00112 00113 void HttpXmlDocument::setHeader(std::string cookieCode, std::string displayName) 00114 { 00115 if(headerElement_) 00116 { 00117 std::stringstream ss; 00118 ss << __COUT_HDR_FL__ 00119 << "Can NOT set header to doc with a header! Only allowed for docs without " 00120 "header element."; 00121 __SS_THROW__; 00122 } 00123 00124 if(cookieCode != "" || displayName != "") // add header 00125 { 00126 headerElement_ = theDocument_->createElement(CONVERT_TO_XML(headerTagName_)); 00127 rootElement_->appendChild(headerElement_); 00128 if(cookieCode != "") // add cookie code to header 00129 addTextElementToParent(cookieCodeTagName_, cookieCode, headerElement_); 00130 if(displayName != "") // add display name to header 00131 addTextElementToParent(displayNameTagName_, displayName, headerElement_); 00132 } 00133 } 00134 00135 //============================================================================== 00136 xercesc::DOMElement* HttpXmlDocument::addTextElementToData(const std::string& childName, 00137 const std::string& childValue) 00138 { 00139 // std::cout << __COUT_HDR_FL__ << "in - " << childName << " value: " << childValue 00140 // <<std::endl << std::endl; 00141 return addTextElementToParent(childName, childValue, dataElement_); 00142 } 00143 00144 //============================================================================== 00145 xercesc::DOMElement* HttpXmlDocument::addBinaryStringToData(const std::string& childName, 00146 const std::string& binary) 00147 { 00148 std::string convertStr = ""; 00149 char hexStr[3]; 00150 for(unsigned int i = 0; i < binary.length(); ++i) 00151 { 00152 // for every byte make hex 00153 sprintf(hexStr, "%2.2X", ((unsigned char)binary[i])); 00154 hexStr[2] = '\0'; 00155 convertStr += hexStr; 00156 } 00157 00158 return addTextElementToParent(childName, convertStr, dataElement_); 00159 } 00160 00161 //============================================================================== 00162 // HttpXmlDocument::getChildrenCount 00163 // get count of children ignoring text nodes. 00164 unsigned int HttpXmlDocument::getChildrenCount(xercesc::DOMElement* parent) 00165 { 00166 if(!parent) 00167 parent = dataElement_; // default to data element 00168 00169 xercesc::DOMNodeList* nodeList = 00170 parent->getChildNodes(); // get all children within parent 00171 unsigned int count = 0; 00172 00173 for(unsigned int i = 0; i < nodeList->getLength(); ++i) 00174 { 00175 if(nodeList->item(i)->getNodeType() != 00176 xercesc::DOMNode::TEXT_NODE) // ignore text node children 00177 ++count; 00178 } 00179 00180 return count; 00181 } 00182 00183 //============================================================================== 00184 // HttpXmlDocument::removeDataElement 00185 // Remove child and child's sub-tree from dataElement. The child is 00186 // identified with dataChildIndex. 00187 void HttpXmlDocument::removeDataElement(unsigned int dataChildIndex) 00188 { 00189 xercesc::DOMNodeList* nodeList = 00190 dataElement_->getChildNodes(); // get all children within data 00191 00192 for(unsigned int i = 0; i < nodeList->getLength(); ++i) 00193 { 00194 if(nodeList->item(i)->getNodeType() == 00195 xercesc::DOMNode::TEXT_NODE) // ignore text node children 00196 continue; 00197 00198 if(!dataChildIndex) // remove 00199 { 00200 recursiveRemoveChild((xercesc::DOMElement*)(nodeList->item(i)), dataElement_); 00201 return; 00202 } 00203 00204 --dataChildIndex; // find proper child 00205 } 00206 00207 // here, then child doesnt exist 00208 } 00209 00210 //============================================================================== 00211 // HttpXmlDocument::addXmlData 00212 // Append <DATA> from xmldoc to this XML doc 00213 void HttpXmlDocument::copyDataChildren(HttpXmlDocument& document) 00214 { 00215 // add all first level child elements of data and recurse on them 00216 xercesc::DOMNodeList* nodeList = 00217 document.dataElement_->getChildNodes(); // get all children within data 00218 for(unsigned int i = 0; i < nodeList->getLength(); ++i) 00219 { 00220 if(nodeList->item(i)->getNodeType() == 00221 xercesc::DOMNode::TEXT_NODE) // ignore text node children 00222 continue; 00223 00224 recursiveAddElementToParent( 00225 (xercesc::DOMElement*)(nodeList->item(i)), dataElement_, true); 00226 } 00227 } 00228 00229 //============================================================================== 00230 // HttpXmlDocument::outputXmlDocument 00231 // recurse through XML theDocument_ and std out and output to stream parameter if not 00232 // null 00233 void HttpXmlDocument::outputXmlDocument(std::ostringstream* out, 00234 bool dispStdOut, 00235 bool allowWhiteSpace) 00236 { 00237 recursiveOutputXmlDocument( 00238 theDocument_->getDocumentElement(), out, dispStdOut, "", allowWhiteSpace); 00239 } 00240 00241 //============================================================================== 00242 // HttpXmlDocument::recursiveOutputXmlDocument 00243 // recursively printout XML theDocument_ to std out and output stream if not null 00244 void HttpXmlDocument::recursiveOutputXmlDocument(xercesc::DOMElement* currEl, 00245 std::ostringstream* out, 00246 bool dispStdOut, 00247 std::string tabStr, 00248 bool allowWhiteSpace) 00249 { 00250 // open field tag 00251 if(dispStdOut) 00252 std::cout << __COUT_HDR_FL__ << tabStr << "<" 00253 << XML_TO_CHAR(currEl->getNodeName()); 00254 if(out) 00255 *out << tabStr << "<" << XML_TO_CHAR(currEl->getNodeName()); 00256 00257 // insert value if text node child 00258 if(currEl->getFirstChild() != NULL && 00259 currEl->getFirstChild()->getNodeType() == 00260 xercesc::DOMNode::TEXT_NODE) // if has a text node first, insert as value 00261 // attribute 00262 { 00263 if(dispStdOut) 00264 std::cout << " value='" 00265 << escapeString( 00266 XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()), 00267 allowWhiteSpace) 00268 << "'"; 00269 if(out) 00270 *out << " value='" 00271 << escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()), 00272 allowWhiteSpace) 00273 << "'"; 00274 } 00275 00276 xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children 00277 00278 // close opening field tag 00279 if(dispStdOut) 00280 std::cout << ((nodeList->getLength() == 0 || 00281 (nodeList->getLength() == 1 && 00282 currEl->getFirstChild()->getNodeType() == 00283 xercesc::DOMNode::TEXT_NODE)) 00284 ? "/" 00285 : "") 00286 << ">" 00287 << " len:" << nodeList->getLength() << std::endl; 00288 if(out) 00289 *out << ((nodeList->getLength() == 0 || 00290 (nodeList->getLength() == 1 && 00291 currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)) 00292 ? "/" 00293 : "") 00294 << ">" << std::endl; 00295 00296 // insert children 00297 std::string newTabStr = tabStr + "\t"; 00298 for(unsigned int i = 0; i < nodeList->getLength(); ++i) 00299 if(nodeList->item(i)->getNodeType() != 00300 xercesc::DOMNode::TEXT_NODE) // ignore text node children 00301 recursiveOutputXmlDocument((xercesc::DOMElement*)(nodeList->item(i)), 00302 out, 00303 dispStdOut, 00304 newTabStr, 00305 allowWhiteSpace); 00306 00307 // close tag if children 00308 if(nodeList->getLength() > 1 || 00309 (nodeList->getLength() == 1 && 00310 currEl->getFirstChild()->getNodeType() != xercesc::DOMNode::TEXT_NODE)) 00311 { 00312 if(dispStdOut) 00313 std::cout << __COUT_HDR_FL__ << tabStr << "</" 00314 << XML_TO_CHAR(currEl->getNodeName()) << ">" << std::endl; 00315 if(out) 00316 *out << tabStr << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">" 00317 << std::endl; 00318 } 00319 } 00320 00321 //============================================================================== 00322 // HttpXmlDocument::getMatchingValue 00323 // returns the value for field found occurance number of times 00324 // returns empty std::string "" if field was not found 00325 std::string HttpXmlDocument::getMatchingValue(const std::string& field, 00326 const unsigned int occurance) 00327 { 00328 unsigned int count = 0; 00329 return recursiveFindElementValue( 00330 theDocument_->getDocumentElement(), field, occurance, count); 00331 } 00332 00333 //============================================================================== 00334 // HttpXmlDocument::recursiveFindElement 00335 // recursively searches and returns the value for field found occurance number of times 00336 std::string HttpXmlDocument::recursiveFindElementValue(xercesc::DOMElement* currEl, 00337 const std::string& field, 00338 const unsigned int occurance, 00339 unsigned int& count) 00340 { 00341 if(XML_TO_CHAR(currEl->getNodeName()) == field && 00342 occurance == count++) // found, done!! 00343 { 00344 if(currEl->getFirstChild() != NULL && 00345 currEl->getFirstChild()->getNodeType() == 00346 xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as value 00347 // attribute 00348 return escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue())); 00349 else 00350 return ""; // empty value attribute 00351 } 00352 00353 std::string retStr; 00354 // look through children recursively 00355 xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children 00356 for(unsigned int i = 0; i < nodeList->getLength(); ++i) 00357 if(nodeList->item(i)->getNodeType() != 00358 xercesc::DOMNode::TEXT_NODE) // ignore text node children 00359 { 00360 retStr = recursiveFindElementValue( 00361 (xercesc::DOMElement*)(nodeList->item(i)), field, occurance, count); 00362 if(retStr != "") 00363 return retStr; // found among children already, done 00364 // else continue search within children recursively 00365 } 00366 return ""; // nothing found 00367 } 00368 00369 //============================================================================== 00370 // HttpXmlDocument::getAllMatchingValues 00371 // returns all of the values found for the field in a vector 00372 // if none found vector will have size 0 00373 void HttpXmlDocument::getAllMatchingValues(const std::string& field, 00374 std::vector<std::string>& retVec) 00375 { 00376 recursiveFindAllElements(theDocument_->getDocumentElement(), field, &retVec); 00377 } 00378 00379 //============================================================================== 00380 // HttpXmlDocument::recursiveFindElement 00381 // recursively searches and returns the value for field found occurance number of times 00382 void HttpXmlDocument::recursiveFindAllElements(xercesc::DOMElement* currEl, 00383 const std::string& field, 00384 std::vector<std::string>* retVec) 00385 { 00386 if(XML_TO_CHAR(currEl->getNodeName()) == field && currEl->getFirstChild() != NULL && 00387 currEl->getFirstChild()->getNodeType() == 00388 xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as value 00389 // attribute 00390 retVec->push_back(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue())); 00391 00392 // look through children recursively 00393 xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children 00394 for(unsigned int i = 0; i < nodeList->getLength(); ++i) 00395 if(nodeList->item(i)->getNodeType() != 00396 xercesc::DOMNode::TEXT_NODE) // ignore text node children 00397 recursiveFindAllElements( 00398 (xercesc::DOMElement*)(nodeList->item(i)), field, retVec); 00399 } 00400 00401 //============================================================================== 00402 // HttpXmlDocument::getMatchingElement 00403 // returns the element for field found occurance number of times 00404 // returns null if field was not found 00405 xercesc::DOMElement* HttpXmlDocument::getMatchingElement(const std::string& field, 00406 const unsigned int occurance) 00407 { 00408 return getMatchingElementInSubtree( 00409 theDocument_->getDocumentElement(), field, occurance); 00410 } 00411 00412 //============================================================================== 00413 // HttpXmlDocument::getMatchingElementInSubtree 00414 // returns the element for field found occurance number of times within the subtree 00415 // specified by parentEl 00416 // returns null if field was not found 00417 xercesc::DOMElement* HttpXmlDocument::getMatchingElementInSubtree( 00418 xercesc::DOMElement* parentEl, const std::string& field, const unsigned int occurance) 00419 { 00420 unsigned int count = 0; 00421 return recursiveFindElement(parentEl, field, occurance, count); 00422 } 00423 00424 //============================================================================== 00425 // HttpXmlDocument::recursiveFindElement 00426 // recursively searches and returns the element for field found occurance number of times 00427 xercesc::DOMElement* HttpXmlDocument::recursiveFindElement(xercesc::DOMElement* currEl, 00428 const std::string& field, 00429 const unsigned int occurance, 00430 unsigned int& count) 00431 { 00432 if(XML_TO_CHAR(currEl->getNodeName()) == field && 00433 occurance == count++) // found, done!! 00434 { 00435 if(currEl->getFirstChild() != NULL && 00436 currEl->getFirstChild()->getNodeType() == 00437 xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as value 00438 // attribute 00439 return currEl; 00440 else 00441 return 0; // empty value attribute 00442 } 00443 00444 xercesc::DOMElement* retEl; 00445 // look through children recursively 00446 xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children 00447 for(unsigned int i = 0; i < nodeList->getLength(); ++i) 00448 if(nodeList->item(i)->getNodeType() != 00449 xercesc::DOMNode::TEXT_NODE) // ignore text node children 00450 { 00451 retEl = recursiveFindElement( 00452 (xercesc::DOMElement*)(nodeList->item(i)), field, occurance, count); 00453 if(retEl) 00454 return retEl; // found among children already, done 00455 // else continue search within children recursively 00456 } 00457 return 0; // nothing found 00458 } 00459 00460 //============================================================================== 00461 // HttpXmlDocument::recursiveAddElementToParent 00462 // add currEl and its children tree to parentEl 00463 // note: attributes are not considered here 00464 void HttpXmlDocument::recursiveAddElementToParent(xercesc::DOMElement* child, 00465 xercesc::DOMElement* parent, 00466 bool html) 00467 { 00468 std::string childText = ""; 00469 00470 std::string childName = 00471 XML_TO_CHAR(child->getNodeName()); // XML_TO_CHAR(currEl->getNodeName()); 00472 00473 if(child->getFirstChild() != NULL && 00474 child->getFirstChild()->getNodeType() == 00475 xercesc::DOMNode::TEXT_NODE) // if has a text node first, insert as value 00476 // attribute 00477 { 00478 childText = XML_TO_CHAR(child->getFirstChild()->getNodeValue()); 00479 if(html) 00480 childText = escapeString(childText); 00481 } 00482 // std::cout << __COUT_HDR_FL__<< "childName " << childName << " childText " << 00483 // childText << std::endl; 00484 00485 // insert child 00486 xercesc::DOMElement* newParent = addTextElementToParent(childName, childText, parent); 00487 00488 // insert rest of child tree 00489 xercesc::DOMNodeList* nodeList = 00490 child->getChildNodes(); // get all children of child 00491 for(unsigned int i = 0; i < nodeList->getLength(); ++i) 00492 { 00493 if(nodeList->item(i)->getNodeType() == 00494 xercesc::DOMNode::TEXT_NODE) // ignore text node children 00495 continue; 00496 00497 recursiveAddElementToParent( 00498 (xercesc::DOMElement*)(nodeList->item(i)), newParent, html); 00499 } 00500 } 00501 00502 //============================================================================== 00503 // HttpXmlDocument::getAllMatchingElements 00504 // returns all of the values found for the field in a vector 00505 // if none found vector will have size 0 00506 void HttpXmlDocument::getAllMatchingElements(const std::string& field, 00507 std::vector<xercesc::DOMElement*>& retVec) 00508 { 00509 recursiveFindAllElements(theDocument_->getDocumentElement(), field, &retVec); 00510 } 00511 00512 //============================================================================== 00513 // HttpXmlDocument::recursiveFindElement 00514 // recursively searches and returns the value for field found occurance number of times 00515 void HttpXmlDocument::recursiveFindAllElements(xercesc::DOMElement* currEl, 00516 const std::string& field, 00517 std::vector<xercesc::DOMElement*>* retVec) 00518 { 00519 if(XML_TO_CHAR(currEl->getNodeName()) == field && currEl->getFirstChild() != NULL && 00520 currEl->getFirstChild()->getNodeType() == 00521 xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as value 00522 // attribute 00523 retVec->push_back(currEl); 00524 00525 // look through children recursively 00526 xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children 00527 for(unsigned int i = 0; i < nodeList->getLength(); ++i) 00528 if(nodeList->item(i)->getNodeType() != 00529 xercesc::DOMNode::TEXT_NODE) // ignore text node children 00530 recursiveFindAllElements( 00531 (xercesc::DOMElement*)(nodeList->item(i)), field, retVec); 00532 } 00533 //============================================================================== 00534 // HttpXmlDocument::escapeString 00535 // convert quotes to html quote characters &apos = ' and " = " 00536 // remove new line characters 00537 // and remove white space (so that read from file white space artifact removed) 00538 /* 00539 std::string HttpXmlDocument::escapeString(string inString) 00540 { 00541 unsigned int ws = -1; 00542 for(unsigned int i=0;i<inString.length();++i) 00543 if(inString[i] != ' ') 00544 { 00545 if(inString[i] == '\r' || inString[i] == '\n') //remove new line chars 00546 { 00547 inString.erase(i,1); // replace special character with ; 00548 --i; //step back so next char to check is correct 00549 continue; 00550 } 00551 00552 ws = i; //last non white space char 00553 if(inString[i] == '\"' || inString[i] == '\'') 00554 { 00555 inString.insert(i,(inString[i] == '\'')?"&apos":"""); //insert \ 00556 before quotes inString.replace(i+5,1,1,';'); // replace special character with ; 00557 i+=5; //skip to next char to check 00558 } 00559 } 00560 00561 if(ws == (unsigned int)-1) return ""; //empty std::string since all white space 00562 return inString.substr(0,ws+1); //trim right white space 00563 } 00564 */ 00565 //============================================================================== 00566 // loadXmlDocument 00567 // returns false if xml doc could not be opened 00568 bool HttpXmlDocument::loadXmlDocument(const std::string& filePath) 00569 { 00570 // std::cout << __COUT_HDR_FL__<< "Loading theDocument_ from file: " << filePath << 00571 // std::endl; 00572 00573 struct stat fileStatus; 00574 00575 if(stat(filePath.c_str(), &fileStatus) != 0) 00576 { 00577 std::cout << __COUT_HDR_FL__ << "File not accessible." << std::endl; 00578 return false; 00579 } 00580 00581 // reset xml platform and theDocument_ 00582 terminatePlatform(); 00583 initPlatform(); 00584 00585 xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser; 00586 // Configure xercesc::DOM parser. 00587 parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto); 00588 parser->setDoNamespaces(true); 00589 parser->setDoSchema(true); 00590 parser->useCachedGrammarInParse(false); 00591 00592 try 00593 { 00594 parser->parse(filePath.c_str()); 00595 00596 // theDocument_ memory object owned by the parent parser object 00597 theDocument_ = parser->adoptDocument(); // instead of getDocument() so parser 00598 // will not free theDocument_ when 00599 // released 00600 00601 // Get the top-level element: Name is "root". No attributes for "root" 00602 rootElement_ = theDocument_->getDocumentElement(); 00603 if(!rootElement_) 00604 throw(std::runtime_error("empty XML theDocument_")); 00605 00606 recursiveFixTextFields( 00607 rootElement_); // remove space and new lines from value attribute 00608 00609 xercesc::DOMNodeList* nodeList = 00610 theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_)); 00611 if(nodeList->getLength()) // may not always be header element 00612 headerElement_ = 00613 (xercesc::DOMElement*)(theDocument_ 00614 ->getElementsByTagName( 00615 CONVERT_TO_XML(headerTagName_)) 00616 ->item(0)); 00617 else 00618 headerElement_ = 0; 00619 00620 dataElement_ = (xercesc::DOMElement*)(theDocument_ 00621 ->getElementsByTagName( 00622 CONVERT_TO_XML(dataTagName_)) 00623 ->item(0)); // always is data 00624 } 00625 catch(xercesc::XMLException& e) 00626 { 00627 std::cout << __COUT_HDR_FL__ << "Error parsing file." << std::endl; 00628 return false; 00629 } 00630 delete parser; 00631 00632 return true; 00633 } 00634 00635 //============================================================================== 00636 // HttpXmlDocument::recursiveFixTextFields 00637 // recursively printout XML theDocument_ to std out and output stream if not null 00638 void HttpXmlDocument::recursiveFixTextFields(xercesc::DOMElement* currEl) 00639 { 00640 xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children 00641 00642 // recurse through children 00643 for(unsigned int i = 0; i < nodeList->getLength(); ++i) 00644 if(nodeList->item(i)->getNodeType() == 00645 xercesc::DOMNode::TEXT_NODE) // fix text nodes 00646 ((xercesc::DOMElement*)(nodeList->item(i))) 00647 ->setTextContent(CONVERT_TO_XML( // change text value to escaped version 00648 escapeString(XML_TO_CHAR( 00649 ((xercesc::DOMElement*)(nodeList->item(i)))->getNodeValue())))); 00650 else 00651 recursiveFixTextFields((xercesc::DOMElement*)(nodeList->item(i))); 00652 } 00653 00654 //============================================================================== 00655 // HttpXmlDocument::addDataElement 00656 // Add field/value element to XML doc at parentIndexArray (with depth of parent indicated 00657 // by parentIndexArraySize) If parentIndexArray = NULL, element is added with <DATA> 00658 // parent otherwise, parentIndexArray indicates the parent within the node list for 00659 //<DATA> where the element will be added 00660 // On Success, The child index of the added element with respect to the parent is 00661 // returned and can be used to add 00662 // children to the new element 00663 // On Failure, return -1 00664 /* 00665 xercesc::DOMElement* HttpXmlDocument::addDataElement ( std::string field, std::string 00666 value, unsigned int *parentIndexArray, unsigned int parentIndexArraySize) 00667 { 00668 00669 //std::cout << __COUT_HDR_FL__ << "field: " << field << ", value: " << value << ", 00670 parent: " << parentIndexArraySize << std::endl; 00671 00672 xercesc::DOMElement* parentEl = dataElement_; // initialize parent to <DATA> 00673 00674 if(parentIndexArray) //if there passed an array find parent relative to data element 00675 { 00676 //std::cout << __COUT_HDR_FL__<< "Using Parent Index Array" << std::endl; 00677 00678 xercesc::DOMNodeList *nodeList; 00679 00680 //iterate through nested parents based on parentIndexArray 00681 unsigned int tmpi,cntNotTxt; 00682 for(unsigned int i=0;i<parentIndexArraySize;++i) 00683 { 00684 nodeList = parentEl->getChildNodes(); //get all children 00685 cntNotTxt = 0; 00686 00687 //get cntNotTxt to proper non text node 00688 for(tmpi=0;tmpi<nodeList->getLength();++tmpi) 00689 { 00690 if(((xercesc::DOMElement*)(nodeList->item(tmpi)))->getNodeType() == 00691 xercesc::DOMNode::TEXT_NODE) continue; //skip text nodes 00692 00693 if(cntNotTxt == parentIndexArray[i]) break; //at proper parent node! 00694 ++cntNotTxt; //else look for next 00695 } 00696 00697 //in theory, only first child can be text - ignore text node children 00698 //if(parentEl->getFirstChild() != NULL && 00699 parentEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) ++tmpi; 00700 00701 if(tmpi >= nodeList->getLength()) 00702 { 00703 std::cout << __COUT_HDR_FL__ << "illegal child index attempted in nested 00704 parents: " << parentIndexArray[i] << ", depth: " << i << ", tmpi: " << tmpi << std::endl; 00705 return 0; //illegal child index attempted in nested parents 00706 } 00707 00708 parentEl = (xercesc::DOMElement*)(nodeList->item(tmpi)); 00709 } 00710 } 00711 00712 return addTextElementToParent(field,value,parentEl); 00713 } 00714 */