otsdaq  3.06.00
HttpXmlDocument.cc
1 #include "otsdaq/XmlUtilities/HttpXmlDocument.h"
2 #include "otsdaq/Macros/CoutMacros.h"
3 #include "otsdaq/Macros/StringMacros.h"
4 #include "otsdaq/MessageFacility/MessageFacility.h"
5 #include "otsdaq/XmlUtilities/ConvertFromXML.h"
6 #include "otsdaq/XmlUtilities/ConvertToXML.h"
7 // #include "otsdaq_cmsoutertracker/otsdaq-cmsoutertracker/Ph2_ACF/Utils/MessageTools.h"
8 
9 #include <stdexcept>
10 #include <xercesc/dom/DOM.hpp>
11 #include <xercesc/dom/DOMDocument.hpp>
12 #include <xercesc/dom/DOMDocumentType.hpp>
13 #include <xercesc/dom/DOMElement.hpp>
14 #include <xercesc/dom/DOMImplementation.hpp>
15 #include <xercesc/dom/DOMImplementationLS.hpp>
16 #include <xercesc/dom/DOMImplementationRegistry.hpp>
17 // #include <xercesc/dom/DOMLSSerializer.hpp>
18 // #include <xercesc/dom/DOMLSOutput.hpp>
19 #include <xercesc/dom/DOMNodeIterator.hpp>
20 #include <xercesc/dom/DOMNodeList.hpp>
21 #include <xercesc/dom/DOMText.hpp>
22 #include <xercesc/validators/common/Grammar.hpp>
23 
24 #include <xercesc/parsers/XercesDOMParser.hpp>
25 #include <xercesc/util/XMLUni.hpp>
26 #include <xercesc/util/XercesDefs.hpp>
27 
28 #include <xercesc/framework/LocalFileFormatTarget.hpp>
29 #include <xercesc/util/OutOfMemoryException.hpp>
30 
31 #include <iostream>
32 #include <list>
33 #include <sstream>
34 
35 #include <errno.h>
36 #include <sys/stat.h>
37 #include <sys/types.h>
38 #include <unistd.h>
39 
40 #include <chrono> //for std::chrono
41 
42 using namespace ots;
43 
44 //==============================================================================
56 HttpXmlDocument::HttpXmlDocument(std::string cookieCode, std::string displayName)
57  : XmlDocument("ROOT")
58  , headerElement_(0)
59  , dataElement_(0)
60  , headerTagName_("HEADER")
61  , dataTagName_("DATA")
62  , cookieCodeTagName_("CookieCode")
63  , displayNameTagName_("DisplayName")
64 {
65  // __COUT__ << "in" << std::endl;
66  //<HEADER>
67  if(cookieCode != "" || displayName != "") // add header
68  {
69  headerElement_ = theDocument_->createElement(CONVERT_TO_XML(headerTagName_));
70  rootElement_->appendChild(headerElement_);
71  if(cookieCode != "") // add cookie code to header
72  addTextElementToParent(cookieCodeTagName_, cookieCode, headerElement_);
73  if(displayName != "") // add display name to header
74  addTextElementToParent(displayNameTagName_, displayName, headerElement_);
75  }
76 
77  //<DATA>
78  dataElement_ = theDocument_->createElement(CONVERT_TO_XML(dataTagName_));
79  rootElement_->appendChild(dataElement_);
80  // __COUT__ << "out" << std::endl;
81 }
82 
83 //==============================================================================
85  : XmlDocument(doc)
86  , headerElement_(0)
87  , dataElement_(0)
88  , headerTagName_(doc.headerTagName_)
89  , dataTagName_(doc.dataTagName_)
90  , cookieCodeTagName_(doc.cookieCodeTagName_)
91  , displayNameTagName_(doc.displayNameTagName_)
92 {
93  // __COUT__ << "in" << std::endl;
94  *this = doc;
95  // __COUT__ << "out" << std::endl;
96 }
97 
98 //==============================================================================
99 HttpXmlDocument& HttpXmlDocument::operator=(const HttpXmlDocument& doc)
100 {
101  // __COUT__ << "in" << std::endl;
102  recursiveElementCopy(doc.rootElement_, rootElement_);
103  // __COUT__ << "in" << std::endl;
104  if(doc.headerElement_ != 0)
105  headerElement_ = (xercesc::DOMElement*)rootElement_
106  ->getElementsByTagName(CONVERT_TO_XML(headerTagName_))
107  ->item(0);
108  // __COUT__ << "in" << std::endl;
109  dataElement_ = (xercesc::DOMElement*)rootElement_
110  ->getElementsByTagName(CONVERT_TO_XML(dataTagName_))
111  ->item(0);
112  // __COUT__ << "out" << std::endl;
113  return *this;
114 }
115 
116 //==============================================================================
117 HttpXmlDocument::~HttpXmlDocument(void) {}
118 
119 void HttpXmlDocument::setHeader(std::string cookieCode, std::string displayName)
120 {
121  if(headerElement_)
122  {
123  std::stringstream ss;
124  ss << __COUT_HDR_FL__
125  << "Can NOT set header to doc with a header! Only allowed for docs without "
126  "header element.";
127  __SS_THROW__;
128  }
129 
130  if(cookieCode != "" || displayName != "") // add header
131  {
132  headerElement_ = theDocument_->createElement(CONVERT_TO_XML(headerTagName_));
133  rootElement_->appendChild(headerElement_);
134  if(cookieCode != "") // add cookie code to header
135  addTextElementToParent(cookieCodeTagName_, cookieCode, headerElement_);
136  if(displayName != "") // add display name to header
137  addTextElementToParent(displayNameTagName_, displayName, headerElement_);
138  }
139 }
140 
141 //==============================================================================
142 xercesc::DOMElement* HttpXmlDocument::addTextElementToData(const std::string& childName,
143  const std::string& childValue)
144 {
145  // __COUT__ << "in - " << childName << " value: " << childValue <<std::endl << std::endl;
146  return addTextElementToParent(childName, childValue, dataElement_);
147 }
148 
149 //==============================================================================
150 xercesc::DOMElement* HttpXmlDocument::addBinaryStringToData(const std::string& childName,
151  const std::string& binary)
152 {
153  std::string convertStr = "";
154  char hexStr[3];
155  for(unsigned int i = 0; i < binary.length(); ++i)
156  {
157  // for every byte make hex
158  sprintf(hexStr, "%2.2X", ((unsigned char)binary[i]));
159  hexStr[2] = '\0';
160  convertStr += hexStr;
161  }
162 
163  return addTextElementToParent(childName, convertStr, dataElement_);
164 }
165 
166 //==============================================================================
169 unsigned int HttpXmlDocument::getChildrenCount(xercesc::DOMElement* parent)
170 {
171  if(!parent)
172  parent = dataElement_; // default to data element
173 
174  xercesc::DOMNodeList* nodeList =
175  parent->getChildNodes(); // get all children within parent
176  unsigned int count = 0;
177 
178  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
179  {
180  if(nodeList->item(i)->getNodeType() !=
181  xercesc::DOMNode::TEXT_NODE) // ignore text node children
182  ++count;
183  }
184 
185  return count;
186 }
187 
188 //==============================================================================
192 void HttpXmlDocument::removeDataElement(unsigned int dataChildIndex)
193 {
194  xercesc::DOMNodeList* nodeList =
195  dataElement_->getChildNodes(); // get all children within data
196 
197  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
198  {
199  if(nodeList->item(i)->getNodeType() ==
200  xercesc::DOMNode::TEXT_NODE) // ignore text node children
201  continue;
202 
203  if(!dataChildIndex) // remove
204  {
205  recursiveRemoveChild((xercesc::DOMElement*)(nodeList->item(i)), dataElement_);
206  return;
207  }
208 
209  --dataChildIndex; // find proper child
210  }
211 
212  // here, then child doesnt exist
213 } // end removeDataElement()
214 
215 //==============================================================================
220 {
221  // add all first level child elements of data and recurse on them
222  xercesc::DOMNodeList* nodeList =
223  document.dataElement_->getChildNodes(); // get all children within data
224  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
225  {
226  if(nodeList->item(i)->getNodeType() ==
227  xercesc::DOMNode::TEXT_NODE) // ignore text node children
228  continue;
229 
230  recursiveAddElementToParent(
231  (xercesc::DOMElement*)(nodeList->item(i)), dataElement_, true /* html*/);
232  }
233 } // end copyDataChildren()
234 
235 //==============================================================================
239 void HttpXmlDocument::outputXmlDocument(std::ostringstream* out,
240  bool dispStdOut /* = false */,
241  bool allowWhiteSpace /* = false */,
242  bool printErrors /* = false */)
243 {
244  recursiveOutputXmlDocument(theDocument_->getDocumentElement(),
245  out,
246  dispStdOut,
247  "",
248  allowWhiteSpace,
249  printErrors);
250 } // end outputXmlDocument()
251 
252 //==============================================================================
255 void HttpXmlDocument::recursiveOutputXmlDocument(xercesc::DOMElement* currEl,
256  std::ostringstream* out,
257  bool dispStdOut,
258  std::string tabStr,
259  bool allowWhiteSpace,
260  bool printErrors)
261 {
262 #if 0
263  auto start = std::chrono::high_resolution_clock::now();
264 #endif
265 
266  // open field tag
267  if(dispStdOut)
268  std::cout << tabStr << "<" << XML_TO_CHAR(currEl->getNodeName());
269  if(out)
270  *out << tabStr << "<" << XML_TO_CHAR(currEl->getNodeName());
271 
272  // insert value if text node child
273  if(currEl->getFirstChild() != NULL &&
274  currEl->getFirstChild()->getNodeType() ==
275  xercesc::DOMNode::TEXT_NODE) // if has a text node first, insert as value
276  // attribute
277  {
278  //if is error, then double escape < > to &lt; and &gt; for better display in web browser
279  std::string nodeName = std::string(XML_TO_CHAR(currEl->getNodeName()));
280  //consider any field ending in case-insensitive "Error" an error field for this purpose
281  bool isError = nodeName.length() >= 5 &&
282  (nodeName[nodeName.length() - 5] == 'E' ||
283  nodeName[nodeName.length() - 5] == 'e') &&
284  (nodeName[nodeName.length() - 4] == 'R' ||
285  nodeName[nodeName.length() - 4] == 'r') &&
286  (nodeName[nodeName.length() - 3] == 'R' ||
287  nodeName[nodeName.length() - 3] == 'r') &&
288  (nodeName[nodeName.length() - 2] == 'O' ||
289  nodeName[nodeName.length() - 2] == 'o') &&
290  (nodeName[nodeName.length() - 1] == 'R' ||
291  nodeName[nodeName.length() - 1] == 'r');
292 
293  if(dispStdOut)
294  std::cout << " value='"
296  XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()),
297  allowWhiteSpace,
298  isError /* forHtml */)
299  << "'";
300  if(out)
301  *out << " value='"
303  XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()),
304  allowWhiteSpace,
305  isError /* forHtml */)
306  << "'";
307 
308  if(printErrors && isError)
309  __COUT_ERR__ << "xml Error-type field '" << nodeName << "' encountered:\n"
310  << XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()) << __E__;
311  }
312 
313 #if 0
314  {
315  auto end = std::chrono::high_resolution_clock::now();
316  auto duration =
317  std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
318  __COUTT__ << tabStr << XML_TO_CHAR(currEl->getNodeName()) << " -- Time taken to call recurse xml out = " << duration << " milliseconds." << std::endl;
319  }
320 #endif
321 
322  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
323 
324 #if 0
325  {
326  auto end = std::chrono::high_resolution_clock::now();
327  auto duration =
328  std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
329  __COUTT__ << tabStr << XML_TO_CHAR(currEl->getNodeName()) << " -- Time taken to call recurse xml out = " << duration << " milliseconds." << std::endl;
330  }
331 #endif
332 
333  // close opening field tag
334  if(dispStdOut)
335  std::cout << ((nodeList->getLength() == 0 ||
336  (nodeList->getLength() == 1 &&
337  currEl->getFirstChild()->getNodeType() ==
338  xercesc::DOMNode::TEXT_NODE))
339  ? "/"
340  : "")
341  << ">"
342  << " len:" << nodeList->getLength() << std::endl;
343  if(out)
344  {
345  // Dario-style... means always full node name closing tag
346  if(darioXMLStyle_ &&
347  !(std::string(XML_TO_CHAR(currEl->getNodeName())) == "ROOT" ||
348  std::string(XML_TO_CHAR(currEl->getNodeName())) == "HEADER" ||
349  std::string(XML_TO_CHAR(currEl->getNodeName())) == "DATA" ||
350  std::string(XML_TO_CHAR(currEl->getNodeName())) == "node" ||
351  std::string(XML_TO_CHAR(currEl->getNodeName())) == "nodes"))
352  {
353  *out << ">"
355  XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()),
356  allowWhiteSpace)
357  << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">" << std::endl;
358  }
359  else
360  {
361  *out << ((nodeList->getLength() == 0 ||
362  (nodeList->getLength() == 1 &&
363  currEl->getFirstChild()->getNodeType() ==
364  xercesc::DOMNode::TEXT_NODE))
365  ? "/"
366  : "")
367  << ">" << std::endl;
368 
369  if(printErrors && strcmp(XML_TO_CHAR(currEl->getNodeName()), "Error") == 0)
370  __COUT_ERR__ << "xml field 'Error' encountered:\n"
371  << XML_TO_CHAR(currEl->getFirstChild()->getNodeValue())
372  << __E__;
373  }
374  }
375 
376 #if 0
377  {
378  auto end = std::chrono::high_resolution_clock::now();
379  auto duration =
380  std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
381  __COUTT__ << tabStr << XML_TO_CHAR(currEl->getNodeName()) << " " << nodeList->getLength() <<
382  " -- Time taken to call recurse xml out = " << duration << " milliseconds." << std::endl;
383  }
384 #endif
385 
386  // insert children
387  std::string newTabStr = tabStr + "\t";
388  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
389  if(nodeList->item(i)->getNodeType() !=
390  xercesc::DOMNode::TEXT_NODE) // ignore text node children
391  recursiveOutputXmlDocument(
392  (xercesc::DOMElement*)(nodeList->item(i)),
393  out,
394  dispStdOut,
395  newTabStr, //save for debug decor: + " i=" + std::to_string(i) + " ",
396  allowWhiteSpace);
397 
398 #if 0
399  {
400  auto end = std::chrono::high_resolution_clock::now();
401  auto duration =
402  std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
403  __COUTT__ << tabStr << XML_TO_CHAR(currEl->getNodeName()) << " -- Time taken to call recurse xml out = " << duration << " milliseconds." << std::endl;
404  }
405 #endif
406 
407  if(currEl == dataElement_ && //append the data string stream
408  dataSs_.str().length()) //(for large data blocks that do not need to be escaped)
409  {
410  if(dispStdOut)
411  std::cout << dataSs_.str() << std::endl;
412  if(out)
413  *out << dataSs_.str() << std::endl;
414  }
415 
416  // close tag if children
417  if(nodeList->getLength() > 1 ||
418  (nodeList->getLength() == 1 &&
419  currEl->getFirstChild()->getNodeType() != xercesc::DOMNode::TEXT_NODE))
420  {
421  if(dispStdOut)
422  std::cout << tabStr << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">"
423  << std::endl;
424  if(out)
425  *out << tabStr << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">"
426  << std::endl;
427  }
428 
429 #if 0
430  {
431  auto end = std::chrono::high_resolution_clock::now();
432  auto duration =
433  std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
434  __COUTT__ << tabStr << XML_TO_CHAR(currEl->getNodeName()) << " -- DONE Time taken to call recurse xml out = " << duration << " milliseconds." << std::endl;
435  }
436 #endif
437 } // end recursiveOutputXmlDocument()
438 
439 //==============================================================================
443 std::string HttpXmlDocument::getMatchingValue(const std::string& field,
444  const unsigned int occurance)
445 {
446  unsigned int count = 0;
447  return recursiveFindElementValue(
448  theDocument_->getDocumentElement(), field, occurance, count);
449 } //end getMatchingValue()
450 
451 //==============================================================================
454 std::string HttpXmlDocument::recursiveFindElementValue(xercesc::DOMElement* currEl,
455  const std::string& field,
456  const unsigned int occurance,
457  unsigned int& count)
458 {
459  if(XML_TO_CHAR(currEl->getNodeName()) == field &&
460  occurance == count++) // found, done!!
461  {
462  if(currEl->getFirstChild() != NULL &&
463  currEl->getFirstChild()->getNodeType() ==
464  xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as
465  // value attribute
467  XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
468  else
469  return ""; // empty value attribute
470  }
471 
472  std::string retStr;
473  // look through children recursively
474  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
475  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
476  if(nodeList->item(i)->getNodeType() !=
477  xercesc::DOMNode::TEXT_NODE) // ignore text node children
478  {
479  retStr = recursiveFindElementValue(
480  (xercesc::DOMElement*)(nodeList->item(i)), field, occurance, count);
481  if(retStr != "")
482  return retStr; // found among children already, done
483  // else continue search within children recursively
484  }
485  return ""; // nothing found
486 } //end recursiveFindElementValue()
487 
488 //==============================================================================
492 void HttpXmlDocument::getAllMatchingValues(const std::string& field,
493  std::vector<std::string>& retVec)
494 {
495  recursiveFindAllElements(theDocument_->getDocumentElement(), field, &retVec);
496 } //end getAllMatchingValues()
497 
498 //==============================================================================
501 void HttpXmlDocument::recursiveFindAllElements(xercesc::DOMElement* currEl,
502  const std::string& field,
503  std::vector<std::string>* retVec)
504 {
505  if(XML_TO_CHAR(currEl->getNodeName()) == field && currEl->getFirstChild() != NULL &&
506  currEl->getFirstChild()->getNodeType() ==
507  xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as value
508  // attribute
509  retVec->push_back(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
510 
511  // look through children recursively
512  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
513  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
514  if(nodeList->item(i)->getNodeType() !=
515  xercesc::DOMNode::TEXT_NODE) // ignore text node children
516  recursiveFindAllElements(
517  (xercesc::DOMElement*)(nodeList->item(i)), field, retVec);
518 } //end recursiveFindAllElements()
519 
520 //==============================================================================
524 xercesc::DOMElement* HttpXmlDocument::getMatchingElement(const std::string& field,
525  const unsigned int occurance)
526 {
528  theDocument_->getDocumentElement(), field, occurance);
529 } //end getMatchingElement()
530 
531 //==============================================================================
537  xercesc::DOMElement* parentEl, const std::string& field, const unsigned int occurance)
538 {
539  unsigned int count = 0;
540  return recursiveFindElement(parentEl, field, occurance, count);
541 } //end getMatchingElementInSubtree()
542 
543 //==============================================================================
546 xercesc::DOMElement* HttpXmlDocument::recursiveFindElement(xercesc::DOMElement* currEl,
547  const std::string& field,
548  const unsigned int occurance,
549  unsigned int& count)
550 {
551  if(XML_TO_CHAR(currEl->getNodeName()) == field &&
552  occurance == count++) // found, done!!
553  {
554  if(currEl->getFirstChild() != NULL &&
555  currEl->getFirstChild()->getNodeType() ==
556  xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as
557  // value attribute
558  return currEl;
559  else
560  return 0; // empty value attribute
561  }
562 
563  xercesc::DOMElement* retEl;
564  // look through children recursively
565  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
566  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
567  if(nodeList->item(i)->getNodeType() !=
568  xercesc::DOMNode::TEXT_NODE) // ignore text node children
569  {
570  retEl = recursiveFindElement(
571  (xercesc::DOMElement*)(nodeList->item(i)), field, occurance, count);
572  if(retEl)
573  return retEl; // found among children already, done
574  // else continue search within children recursively
575  }
576  return 0; // nothing found
577 } //end recursiveFindElement()
578 
579 //==============================================================================
583 void HttpXmlDocument::recursiveAddElementToParent(xercesc::DOMElement* child,
584  xercesc::DOMElement* parent,
585  bool html)
586 {
587  std::string childText = "";
588 
589  std::string childName =
590  XML_TO_CHAR(child->getNodeName()); // XML_TO_CHAR(currEl->getNodeName());
591 
592  if(child->getFirstChild() != NULL &&
593  child->getFirstChild()->getNodeType() ==
594  xercesc::DOMNode::
595  TEXT_NODE) // if has a text node first, insert as value attribute
596  {
597  childText = XML_TO_CHAR(child->getFirstChild()->getNodeValue());
598  if(0 &&
599  html) //RAR stopped doing this escape as of Feb-2025 because it seems to double escape html characters like &#009; into &amp;#009; which doesnt work at the browser (tested with MacroMakerSupervisor)
600  {
601  __COUTS__(20) << "pre escape childText " << childText << std::endl;
602  childText = StringMacros::escapeString(childText, true /* allowWhiteSpace*/);
603  __COUTS__(20) << "post escape childText " << childText << std::endl;
604  }
605  }
606  __COUTS__(20) << "childName " << childName << " childText " << childText << std::endl;
607 
608  // insert child
609  xercesc::DOMElement* newParent = addTextElementToParent(childName, childText, parent);
610 
611  // insert rest of child tree
612  xercesc::DOMNodeList* nodeList = child->getChildNodes(); // get all children of child
613  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
614  {
615  if(nodeList->item(i)->getNodeType() ==
616  xercesc::DOMNode::TEXT_NODE) // ignore text node children
617  continue;
618 
619  recursiveAddElementToParent(
620  (xercesc::DOMElement*)(nodeList->item(i)), newParent, html);
621  }
622 } //end recursiveAddElementToParent()
623 
624 //==============================================================================
628 void HttpXmlDocument::getAllMatchingElements(const std::string& field,
629  std::vector<xercesc::DOMElement*>& retVec)
630 {
631  recursiveFindAllElements(theDocument_->getDocumentElement(), field, &retVec);
632 } //end getAllMatchingElements()
633 
634 //==============================================================================
637 void HttpXmlDocument::recursiveFindAllElements(xercesc::DOMElement* currEl,
638  const std::string& field,
639  std::vector<xercesc::DOMElement*>* retVec)
640 {
641  if(XML_TO_CHAR(currEl->getNodeName()) == field && currEl->getFirstChild() != NULL &&
642  currEl->getFirstChild()->getNodeType() ==
643  xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as value
644  // attribute
645  retVec->push_back(currEl);
646 
647  // look through children recursively
648  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
649  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
650  if(nodeList->item(i)->getNodeType() !=
651  xercesc::DOMNode::TEXT_NODE) // ignore text node children
652  recursiveFindAllElements(
653  (xercesc::DOMElement*)(nodeList->item(i)), field, retVec);
654 } //end recursiveFindAllElements()
655 
656 //==============================================================================
659 bool HttpXmlDocument::loadXmlDocument(const std::string& filePath)
660 {
661  // __COUT__<< "Loading theDocument_ from file: " << filePath <<
662  // std::endl;
663 
664  struct stat fileStatus;
665 
666  if(stat(filePath.c_str(), &fileStatus) != 0)
667  {
668  //__SS__ << "File not accessible: " << filePath << std::endl;
669  //__SS_THROW__;
670  return false; // not an error for file to not exist
671  }
672 
673  // reset xml platform and theDocument_
674  terminatePlatform();
675  initPlatform();
676 
677  xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser;
678  // Configure xercesc::DOM parser.
679  parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
680  parser->setDoNamespaces(true);
681  parser->setDoSchema(true);
682  parser->useCachedGrammarInParse(false);
683 
684  try
685  {
686  parser->parse(filePath.c_str());
687 
688  // theDocument_ memory object owned by the parent parser object
689  theDocument_ = parser->adoptDocument(); // instead of getDocument() so parser
690  // will not free theDocument_ when
691  // released
692 
693  // Get the top-level element: Name is "root". No attributes for "root"
694  rootElement_ = theDocument_->getDocumentElement();
695  if(!rootElement_)
696  {
697  __SS__ << "empty XML theDocument_: " << filePath << std::endl;
698  __SS_THROW__;
699  throw(std::runtime_error("empty XML theDocument_"));
700  }
701 
702  recursiveFixTextFields(
703  rootElement_); // remove space and new lines from value attribute
704 
705  xercesc::DOMNodeList* nodeList =
706  theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_));
707  if(nodeList->getLength()) // may not always be header element
708  headerElement_ =
709  (xercesc::DOMElement*)(theDocument_
710  ->getElementsByTagName(
711  CONVERT_TO_XML(headerTagName_))
712  ->item(0));
713  else
714  headerElement_ = 0;
715 
716  dataElement_ = (xercesc::DOMElement*)(theDocument_
717  ->getElementsByTagName(
718  CONVERT_TO_XML(dataTagName_))
719  ->item(0)); // always is data
720  }
721  catch(xercesc::XMLException& e)
722  {
723  __SS__ << "Error parsing file: " << filePath << std::endl;
724  __SS_THROW__;
725  __COUT__ << "Error parsing file." << std::endl;
726  return false;
727  }
728  delete parser;
729 
730  return true;
731 } //end loadXmlDocument()
732 
733 //==============================================================================
736 void HttpXmlDocument::recursiveFixTextFields(xercesc::DOMElement* currEl)
737 {
738  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
739 
740  // recurse through children
741  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
742  if(nodeList->item(i)->getNodeType() ==
743  xercesc::DOMNode::TEXT_NODE) // fix text nodes
744  ((xercesc::DOMElement*)(nodeList->item(i)))
745  ->setTextContent(CONVERT_TO_XML( // change text value to escaped version
746  StringMacros::escapeString(XML_TO_CHAR(
747  ((xercesc::DOMElement*)(nodeList->item(i)))->getNodeValue()))));
748  else
749  recursiveFixTextFields((xercesc::DOMElement*)(nodeList->item(i)));
750 } //end recursiveFixTextFields()
xercesc::DOMElement * getMatchingElement(const std::string &field, const unsigned int occurance=0)
void getAllMatchingValues(const std::string &field, std::vector< std::string > &retVec)
HttpXmlDocument(std::string cookieCode="", std::string displayName="")
xercesc::DOMElement * getMatchingElementInSubtree(xercesc::DOMElement *currEl, const std::string &field, const unsigned int occurance=0)
void copyDataChildren(HttpXmlDocument &document)
void removeDataElement(unsigned int dataChildIndex=0)
default to first child
bool loadXmlDocument(const std::string &filePath)
unsigned int getChildrenCount(xercesc::DOMElement *parent=0)
std::string getMatchingValue(const std::string &field, const unsigned int occurance=0)
void outputXmlDocument(std::ostringstream *out, bool dispStdOut=false, bool allowWhiteSpace=false, bool printErrors=false)
void getAllMatchingElements(const std::string &field, std::vector< xercesc::DOMElement * > &retVec)
Note that XmlDocument functionality is extended by HttpXmlDocument class.
Definition: XmlDocument.h:36
xercesc::DOMElement * addTextElementToParent(const std::string &childName, const std::string &childText, xercesc::DOMElement *parent)
Definition: XmlDocument.cc:244
void recursiveRemoveChild(xercesc::DOMElement *childEl, xercesc::DOMElement *parentEl)
Definition: XmlDocument.cc:453
defines used also by OtsConfigurationWizardSupervisor
static std::string escapeString(std::string inString, bool allowWhiteSpace=false, bool forHtml=false)