otsdaq  3.03.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(dispStdOut)
279  std::cout << " value='"
281  XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()),
282  allowWhiteSpace)
283  << "'";
284  if(out)
285  *out << " value='"
287  XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()),
288  allowWhiteSpace)
289  << "'";
290 
291  if(printErrors && strcmp(XML_TO_CHAR(currEl->getNodeName()), "Error") == 0)
292  __COUT_ERR__ << "xml field 'Error' encountered:\n"
293  << XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()) << __E__;
294  }
295 
296 #if 0
297  {
298  auto end = std::chrono::high_resolution_clock::now();
299  auto duration =
300  std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
301  __COUTT__ << tabStr << XML_TO_CHAR(currEl->getNodeName()) << " -- Time taken to call recurse xml out = " << duration << " milliseconds." << std::endl;
302  }
303 #endif
304 
305  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
306 
307 #if 0
308  {
309  auto end = std::chrono::high_resolution_clock::now();
310  auto duration =
311  std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
312  __COUTT__ << tabStr << XML_TO_CHAR(currEl->getNodeName()) << " -- Time taken to call recurse xml out = " << duration << " milliseconds." << std::endl;
313  }
314 #endif
315 
316  // close opening field tag
317  if(dispStdOut)
318  std::cout << ((nodeList->getLength() == 0 ||
319  (nodeList->getLength() == 1 &&
320  currEl->getFirstChild()->getNodeType() ==
321  xercesc::DOMNode::TEXT_NODE))
322  ? "/"
323  : "")
324  << ">"
325  << " len:" << nodeList->getLength() << std::endl;
326  if(out)
327  {
328  // Dario-style... means always full node name closing tag
329  if(darioXMLStyle_ &&
330  !(std::string(XML_TO_CHAR(currEl->getNodeName())) == "ROOT" ||
331  std::string(XML_TO_CHAR(currEl->getNodeName())) == "HEADER" ||
332  std::string(XML_TO_CHAR(currEl->getNodeName())) == "DATA" ||
333  std::string(XML_TO_CHAR(currEl->getNodeName())) == "node" ||
334  std::string(XML_TO_CHAR(currEl->getNodeName())) == "nodes"))
335  {
336  *out << ">"
338  XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()),
339  allowWhiteSpace)
340  << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">" << std::endl;
341  }
342  else
343  {
344  *out << ((nodeList->getLength() == 0 ||
345  (nodeList->getLength() == 1 &&
346  currEl->getFirstChild()->getNodeType() ==
347  xercesc::DOMNode::TEXT_NODE))
348  ? "/"
349  : "")
350  << ">" << std::endl;
351 
352  if(printErrors && strcmp(XML_TO_CHAR(currEl->getNodeName()), "Error") == 0)
353  __COUT_ERR__ << "xml field 'Error' encountered:\n"
354  << XML_TO_CHAR(currEl->getFirstChild()->getNodeValue())
355  << __E__;
356  }
357  }
358 
359 #if 0
360  {
361  auto end = std::chrono::high_resolution_clock::now();
362  auto duration =
363  std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
364  __COUTT__ << tabStr << XML_TO_CHAR(currEl->getNodeName()) << " " << nodeList->getLength() <<
365  " -- Time taken to call recurse xml out = " << duration << " milliseconds." << std::endl;
366  }
367 #endif
368 
369  // insert children
370  std::string newTabStr = tabStr + "\t";
371  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
372  if(nodeList->item(i)->getNodeType() !=
373  xercesc::DOMNode::TEXT_NODE) // ignore text node children
374  recursiveOutputXmlDocument(
375  (xercesc::DOMElement*)(nodeList->item(i)),
376  out,
377  dispStdOut,
378  newTabStr, //save for debug decor: + " i=" + std::to_string(i) + " ",
379  allowWhiteSpace);
380 
381 #if 0
382  {
383  auto end = std::chrono::high_resolution_clock::now();
384  auto duration =
385  std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
386  __COUTT__ << tabStr << XML_TO_CHAR(currEl->getNodeName()) << " -- Time taken to call recurse xml out = " << duration << " milliseconds." << std::endl;
387  }
388 #endif
389 
390  if(currEl == dataElement_ && //append the data string stream
391  dataSs_.str().length()) //(for large data blocks that do not need to be escaped)
392  {
393  if(dispStdOut)
394  std::cout << dataSs_.str() << std::endl;
395  if(out)
396  *out << dataSs_.str() << std::endl;
397  }
398 
399  // close tag if children
400  if(nodeList->getLength() > 1 ||
401  (nodeList->getLength() == 1 &&
402  currEl->getFirstChild()->getNodeType() != xercesc::DOMNode::TEXT_NODE))
403  {
404  if(dispStdOut)
405  std::cout << tabStr << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">"
406  << std::endl;
407  if(out)
408  *out << tabStr << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">"
409  << std::endl;
410  }
411 
412 #if 0
413  {
414  auto end = std::chrono::high_resolution_clock::now();
415  auto duration =
416  std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
417  __COUTT__ << tabStr << XML_TO_CHAR(currEl->getNodeName()) << " -- DONE Time taken to call recurse xml out = " << duration << " milliseconds." << std::endl;
418  }
419 #endif
420 } // end recursiveOutputXmlDocument()
421 
422 //==============================================================================
426 std::string HttpXmlDocument::getMatchingValue(const std::string& field,
427  const unsigned int occurance)
428 {
429  unsigned int count = 0;
430  return recursiveFindElementValue(
431  theDocument_->getDocumentElement(), field, occurance, count);
432 } //end getMatchingValue()
433 
434 //==============================================================================
437 std::string HttpXmlDocument::recursiveFindElementValue(xercesc::DOMElement* currEl,
438  const std::string& field,
439  const unsigned int occurance,
440  unsigned int& count)
441 {
442  if(XML_TO_CHAR(currEl->getNodeName()) == field &&
443  occurance == count++) // found, done!!
444  {
445  if(currEl->getFirstChild() != NULL &&
446  currEl->getFirstChild()->getNodeType() ==
447  xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as
448  // value attribute
450  XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
451  else
452  return ""; // empty value attribute
453  }
454 
455  std::string retStr;
456  // look through children recursively
457  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
458  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
459  if(nodeList->item(i)->getNodeType() !=
460  xercesc::DOMNode::TEXT_NODE) // ignore text node children
461  {
462  retStr = recursiveFindElementValue(
463  (xercesc::DOMElement*)(nodeList->item(i)), field, occurance, count);
464  if(retStr != "")
465  return retStr; // found among children already, done
466  // else continue search within children recursively
467  }
468  return ""; // nothing found
469 } //end recursiveFindElementValue()
470 
471 //==============================================================================
475 void HttpXmlDocument::getAllMatchingValues(const std::string& field,
476  std::vector<std::string>& retVec)
477 {
478  recursiveFindAllElements(theDocument_->getDocumentElement(), field, &retVec);
479 } //end getAllMatchingValues()
480 
481 //==============================================================================
484 void HttpXmlDocument::recursiveFindAllElements(xercesc::DOMElement* currEl,
485  const std::string& field,
486  std::vector<std::string>* retVec)
487 {
488  if(XML_TO_CHAR(currEl->getNodeName()) == field && currEl->getFirstChild() != NULL &&
489  currEl->getFirstChild()->getNodeType() ==
490  xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as value
491  // attribute
492  retVec->push_back(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
493 
494  // look through children recursively
495  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
496  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
497  if(nodeList->item(i)->getNodeType() !=
498  xercesc::DOMNode::TEXT_NODE) // ignore text node children
499  recursiveFindAllElements(
500  (xercesc::DOMElement*)(nodeList->item(i)), field, retVec);
501 } //end recursiveFindAllElements()
502 
503 //==============================================================================
507 xercesc::DOMElement* HttpXmlDocument::getMatchingElement(const std::string& field,
508  const unsigned int occurance)
509 {
511  theDocument_->getDocumentElement(), field, occurance);
512 } //end getMatchingElement()
513 
514 //==============================================================================
520  xercesc::DOMElement* parentEl, const std::string& field, const unsigned int occurance)
521 {
522  unsigned int count = 0;
523  return recursiveFindElement(parentEl, field, occurance, count);
524 } //end getMatchingElementInSubtree()
525 
526 //==============================================================================
529 xercesc::DOMElement* HttpXmlDocument::recursiveFindElement(xercesc::DOMElement* currEl,
530  const std::string& field,
531  const unsigned int occurance,
532  unsigned int& count)
533 {
534  if(XML_TO_CHAR(currEl->getNodeName()) == field &&
535  occurance == count++) // found, done!!
536  {
537  if(currEl->getFirstChild() != NULL &&
538  currEl->getFirstChild()->getNodeType() ==
539  xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as
540  // value attribute
541  return currEl;
542  else
543  return 0; // empty value attribute
544  }
545 
546  xercesc::DOMElement* retEl;
547  // look through children recursively
548  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
549  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
550  if(nodeList->item(i)->getNodeType() !=
551  xercesc::DOMNode::TEXT_NODE) // ignore text node children
552  {
553  retEl = recursiveFindElement(
554  (xercesc::DOMElement*)(nodeList->item(i)), field, occurance, count);
555  if(retEl)
556  return retEl; // found among children already, done
557  // else continue search within children recursively
558  }
559  return 0; // nothing found
560 } //end recursiveFindElement()
561 
562 //==============================================================================
566 void HttpXmlDocument::recursiveAddElementToParent(xercesc::DOMElement* child,
567  xercesc::DOMElement* parent,
568  bool html)
569 {
570  std::string childText = "";
571 
572  std::string childName =
573  XML_TO_CHAR(child->getNodeName()); // XML_TO_CHAR(currEl->getNodeName());
574 
575  if(child->getFirstChild() != NULL &&
576  child->getFirstChild()->getNodeType() ==
577  xercesc::DOMNode::
578  TEXT_NODE) // if has a text node first, insert as value attribute
579  {
580  childText = XML_TO_CHAR(child->getFirstChild()->getNodeValue());
581  if(0 &&
582  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)
583  {
584  __COUTS__(20) << "pre escape childText " << childText << std::endl;
585  childText = StringMacros::escapeString(childText, true /* allowWhiteSpace*/);
586  __COUTS__(20) << "post escape childText " << childText << std::endl;
587  }
588  }
589  __COUTS__(20) << "childName " << childName << " childText " << childText << std::endl;
590 
591  // insert child
592  xercesc::DOMElement* newParent = addTextElementToParent(childName, childText, parent);
593 
594  // insert rest of child tree
595  xercesc::DOMNodeList* nodeList = child->getChildNodes(); // get all children of child
596  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
597  {
598  if(nodeList->item(i)->getNodeType() ==
599  xercesc::DOMNode::TEXT_NODE) // ignore text node children
600  continue;
601 
602  recursiveAddElementToParent(
603  (xercesc::DOMElement*)(nodeList->item(i)), newParent, html);
604  }
605 } //end recursiveAddElementToParent()
606 
607 //==============================================================================
611 void HttpXmlDocument::getAllMatchingElements(const std::string& field,
612  std::vector<xercesc::DOMElement*>& retVec)
613 {
614  recursiveFindAllElements(theDocument_->getDocumentElement(), field, &retVec);
615 } //end getAllMatchingElements()
616 
617 //==============================================================================
620 void HttpXmlDocument::recursiveFindAllElements(xercesc::DOMElement* currEl,
621  const std::string& field,
622  std::vector<xercesc::DOMElement*>* retVec)
623 {
624  if(XML_TO_CHAR(currEl->getNodeName()) == field && currEl->getFirstChild() != NULL &&
625  currEl->getFirstChild()->getNodeType() ==
626  xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as value
627  // attribute
628  retVec->push_back(currEl);
629 
630  // look through children recursively
631  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
632  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
633  if(nodeList->item(i)->getNodeType() !=
634  xercesc::DOMNode::TEXT_NODE) // ignore text node children
635  recursiveFindAllElements(
636  (xercesc::DOMElement*)(nodeList->item(i)), field, retVec);
637 } //end recursiveFindAllElements()
638 
639 //==============================================================================
642 bool HttpXmlDocument::loadXmlDocument(const std::string& filePath)
643 {
644  // __COUT__<< "Loading theDocument_ from file: " << filePath <<
645  // std::endl;
646 
647  struct stat fileStatus;
648 
649  if(stat(filePath.c_str(), &fileStatus) != 0)
650  {
651  //__SS__ << "File not accessible: " << filePath << std::endl;
652  //__SS_THROW__;
653  return false; // not an error for file to not exist
654  }
655 
656  // reset xml platform and theDocument_
657  terminatePlatform();
658  initPlatform();
659 
660  xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser;
661  // Configure xercesc::DOM parser.
662  parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
663  parser->setDoNamespaces(true);
664  parser->setDoSchema(true);
665  parser->useCachedGrammarInParse(false);
666 
667  try
668  {
669  parser->parse(filePath.c_str());
670 
671  // theDocument_ memory object owned by the parent parser object
672  theDocument_ = parser->adoptDocument(); // instead of getDocument() so parser
673  // will not free theDocument_ when
674  // released
675 
676  // Get the top-level element: Name is "root". No attributes for "root"
677  rootElement_ = theDocument_->getDocumentElement();
678  if(!rootElement_)
679  {
680  __SS__ << "empty XML theDocument_: " << filePath << std::endl;
681  __SS_THROW__;
682  throw(std::runtime_error("empty XML theDocument_"));
683  }
684 
685  recursiveFixTextFields(
686  rootElement_); // remove space and new lines from value attribute
687 
688  xercesc::DOMNodeList* nodeList =
689  theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_));
690  if(nodeList->getLength()) // may not always be header element
691  headerElement_ =
692  (xercesc::DOMElement*)(theDocument_
693  ->getElementsByTagName(
694  CONVERT_TO_XML(headerTagName_))
695  ->item(0));
696  else
697  headerElement_ = 0;
698 
699  dataElement_ = (xercesc::DOMElement*)(theDocument_
700  ->getElementsByTagName(
701  CONVERT_TO_XML(dataTagName_))
702  ->item(0)); // always is data
703  }
704  catch(xercesc::XMLException& e)
705  {
706  __SS__ << "Error parsing file: " << filePath << std::endl;
707  __SS_THROW__;
708  __COUT__ << "Error parsing file." << std::endl;
709  return false;
710  }
711  delete parser;
712 
713  return true;
714 } //end loadXmlDocument()
715 
716 //==============================================================================
719 void HttpXmlDocument::recursiveFixTextFields(xercesc::DOMElement* currEl)
720 {
721  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
722 
723  // recurse through children
724  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
725  if(nodeList->item(i)->getNodeType() ==
726  xercesc::DOMNode::TEXT_NODE) // fix text nodes
727  ((xercesc::DOMElement*)(nodeList->item(i)))
728  ->setTextContent(CONVERT_TO_XML( // change text value to escaped version
729  StringMacros::escapeString(XML_TO_CHAR(
730  ((xercesc::DOMElement*)(nodeList->item(i)))->getNodeValue()))));
731  else
732  recursiveFixTextFields((xercesc::DOMElement*)(nodeList->item(i)));
733 } //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
static std::string escapeString(std::string inString, bool allowWhiteSpace=false)