otsdaq  v2_05_02_indev
HttpXmlDocument.cc
1 #include "otsdaq/XmlUtilities/HttpXmlDocument.h"
2 #include "otsdaq/Macros/CoutMacros.h"
3 #include "otsdaq/MessageFacility/MessageFacility.h"
4 #include "otsdaq/XmlUtilities/ConvertFromXML.h"
5 #include "otsdaq/XmlUtilities/ConvertToXML.h"
6 //#include "otsdaq_cmsoutertracker/otsdaq-cmsoutertracker/Ph2_ACF/Utils/MessageTools.h"
7 
8 #include <stdexcept>
9 #include <xercesc/dom/DOM.hpp>
10 #include <xercesc/dom/DOMDocument.hpp>
11 #include <xercesc/dom/DOMDocumentType.hpp>
12 #include <xercesc/dom/DOMElement.hpp>
13 #include <xercesc/dom/DOMImplementation.hpp>
14 #include <xercesc/dom/DOMImplementationLS.hpp>
15 #include <xercesc/dom/DOMImplementationRegistry.hpp>
16 //#include <xercesc/dom/DOMLSSerializer.hpp>
17 //#include <xercesc/dom/DOMLSOutput.hpp>
18 #include <xercesc/dom/DOMNodeIterator.hpp>
19 #include <xercesc/dom/DOMNodeList.hpp>
20 #include <xercesc/dom/DOMText.hpp>
21 #include <xercesc/validators/common/Grammar.hpp>
22 
23 #include <xercesc/parsers/XercesDOMParser.hpp>
24 #include <xercesc/util/XMLUni.hpp>
25 #include <xercesc/util/XercesDefs.hpp>
26 
27 #include <xercesc/framework/LocalFileFormatTarget.hpp>
28 #include <xercesc/util/OutOfMemoryException.hpp>
29 
30 #include <iostream>
31 #include <list>
32 #include <sstream>
33 
34 #include <errno.h>
35 #include <sys/stat.h>
36 #include <sys/types.h>
37 #include <unistd.h>
38 
39 using namespace ots;
40 
41 //==============================================================================
42 // HttpXmlDocument::HttpXmlDocument
43 // Constructor to initialize XML theDocument_ for ots.
44 // The XML theDocument_ can be written to xdaq output stream to client
45 //
46 // theDocument_ result:
47 // <ROOT>
48 // <HEADER>
49 // --optional with value <CookieCode>, <DisplayName> added in constructor
50 // <DATA>
51 // --optional data elements with value and any field name
52 //
53 HttpXmlDocument::HttpXmlDocument(std::string cookieCode, std::string displayName)
54  : XmlDocument("ROOT")
55  , headerElement_(0)
56  , dataElement_(0)
57  , headerTagName_("HEADER")
58  , dataTagName_("DATA")
59  , cookieCodeTagName_("CookieCode")
60  , displayNameTagName_("DisplayName")
61 {
62  // __COUT__ << "in" << std::endl;
63  //<HEADER>
64  if(cookieCode != "" || displayName != "") // add header
65  {
66  headerElement_ = theDocument_->createElement(CONVERT_TO_XML(headerTagName_));
67  rootElement_->appendChild(headerElement_);
68  if(cookieCode != "") // add cookie code to header
69  addTextElementToParent(cookieCodeTagName_, cookieCode, headerElement_);
70  if(displayName != "") // add display name to header
71  addTextElementToParent(displayNameTagName_, displayName, headerElement_);
72  }
73 
74  //<DATA>
75  dataElement_ = theDocument_->createElement(CONVERT_TO_XML(dataTagName_));
76  rootElement_->appendChild(dataElement_);
77  // __COUT__ << "out" << std::endl;
78 }
79 
80 //==============================================================================
81 HttpXmlDocument::HttpXmlDocument(const HttpXmlDocument& doc)
82  : XmlDocument(doc)
83  , headerElement_(0)
84  , dataElement_(0)
85  , headerTagName_(doc.headerTagName_)
86  , dataTagName_(doc.dataTagName_)
87  , cookieCodeTagName_(doc.cookieCodeTagName_)
88  , displayNameTagName_(doc.displayNameTagName_)
89 {
90  // __COUT__ << "in" << std::endl;
91  *this = doc;
92  // __COUT__ << "out" << std::endl;
93 }
94 
95 //==============================================================================
96 HttpXmlDocument& HttpXmlDocument::operator=(const HttpXmlDocument& doc)
97 {
98  // __COUT__ << "in" << std::endl;
99  recursiveElementCopy(doc.rootElement_, rootElement_);
100  // __COUT__ << "in" << std::endl;
101  if(doc.headerElement_ != 0)
102  headerElement_ = (xercesc::DOMElement*)rootElement_->getElementsByTagName(CONVERT_TO_XML(headerTagName_))->item(0);
103  // __COUT__ << "in" << std::endl;
104  dataElement_ = (xercesc::DOMElement*)rootElement_->getElementsByTagName(CONVERT_TO_XML(dataTagName_))->item(0);
105  // __COUT__ << "out" << std::endl;
106  return *this;
107 }
108 
109 //==============================================================================
110 HttpXmlDocument::~HttpXmlDocument(void) {}
111 
112 void HttpXmlDocument::setHeader(std::string cookieCode, std::string displayName)
113 {
114  if(headerElement_)
115  {
116  std::stringstream ss;
117  ss << __COUT_HDR_FL__
118  << "Can NOT set header to doc with a header! Only allowed for docs without "
119  "header element.";
120  __SS_THROW__;
121  }
122 
123  if(cookieCode != "" || displayName != "") // add header
124  {
125  headerElement_ = theDocument_->createElement(CONVERT_TO_XML(headerTagName_));
126  rootElement_->appendChild(headerElement_);
127  if(cookieCode != "") // add cookie code to header
128  addTextElementToParent(cookieCodeTagName_, cookieCode, headerElement_);
129  if(displayName != "") // add display name to header
130  addTextElementToParent(displayNameTagName_, displayName, headerElement_);
131  }
132 }
133 
134 //==============================================================================
135 xercesc::DOMElement* HttpXmlDocument::addTextElementToData(const std::string& childName, const std::string& childValue)
136 {
137  // __COUT__ << "in - " << childName << " value: " << childValue <<std::endl << std::endl;
138  return addTextElementToParent(childName, childValue, dataElement_);
139 }
140 
141 //==============================================================================
142 xercesc::DOMElement* HttpXmlDocument::addBinaryStringToData(const std::string& childName, const std::string& binary)
143 {
144  std::string convertStr = "";
145  char hexStr[3];
146  for(unsigned int i = 0; i < binary.length(); ++i)
147  {
148  // for every byte make hex
149  sprintf(hexStr, "%2.2X", ((unsigned char)binary[i]));
150  hexStr[2] = '\0';
151  convertStr += hexStr;
152  }
153 
154  return addTextElementToParent(childName, convertStr, dataElement_);
155 }
156 
157 //==============================================================================
158 // HttpXmlDocument::getChildrenCount
159 // get count of children ignoring text nodes.
160 unsigned int HttpXmlDocument::getChildrenCount(xercesc::DOMElement* parent)
161 {
162  if(!parent)
163  parent = dataElement_; // default to data element
164 
165  xercesc::DOMNodeList* nodeList = parent->getChildNodes(); // get all children within parent
166  unsigned int count = 0;
167 
168  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
169  {
170  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) // ignore text node children
171  ++count;
172  }
173 
174  return count;
175 }
176 
177 //==============================================================================
178 // HttpXmlDocument::removeDataElement
179 // Remove child and child's sub-tree from dataElement. The child is
180 // identified with dataChildIndex.
181 void HttpXmlDocument::removeDataElement(unsigned int dataChildIndex)
182 {
183  xercesc::DOMNodeList* nodeList = dataElement_->getChildNodes(); // get all children within data
184 
185  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
186  {
187  if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE) // ignore text node children
188  continue;
189 
190  if(!dataChildIndex) // remove
191  {
192  recursiveRemoveChild((xercesc::DOMElement*)(nodeList->item(i)), dataElement_);
193  return;
194  }
195 
196  --dataChildIndex; // find proper child
197  }
198 
199  // here, then child doesnt exist
200 }
201 
202 //==============================================================================
203 // HttpXmlDocument::addXmlData
204 // Append <DATA> from xmldoc to this XML doc
205 void HttpXmlDocument::copyDataChildren(HttpXmlDocument& document)
206 {
207  // add all first level child elements of data and recurse on them
208  xercesc::DOMNodeList* nodeList = document.dataElement_->getChildNodes(); // get all children within data
209  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
210  {
211  if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE) // ignore text node children
212  continue;
213 
214  recursiveAddElementToParent((xercesc::DOMElement*)(nodeList->item(i)), dataElement_, true);
215  }
216 }
217 
218 //==============================================================================
219 // HttpXmlDocument::outputXmlDocument
220 // recurse through XML theDocument_ and std out and output to stream parameter if not
221 // null
222 void HttpXmlDocument::outputXmlDocument(std::ostringstream* out, bool dispStdOut, bool allowWhiteSpace)
223 {
224  recursiveOutputXmlDocument(theDocument_->getDocumentElement(), out, dispStdOut, "", allowWhiteSpace);
225 }
226 
227 //==============================================================================
228 // HttpXmlDocument::recursiveOutputXmlDocument
229 // recursively printout XML theDocument_ to std out and output stream if not null
230 void HttpXmlDocument::recursiveOutputXmlDocument(
231  xercesc::DOMElement* currEl, std::ostringstream* out, bool dispStdOut, std::string tabStr, bool allowWhiteSpace)
232 {
233  // open field tag
234  if(dispStdOut)
235  __COUT__ << tabStr << "<" << XML_TO_CHAR(currEl->getNodeName());
236  if(out)
237  *out << tabStr << "<" << XML_TO_CHAR(currEl->getNodeName());
238 
239  // insert value if text node child
240  if(currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) // if has a text node first, insert as value
241  // attribute
242  {
243  if(dispStdOut)
244  std::cout << " value='" << escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()), allowWhiteSpace) << "'";
245  if(out)
246  *out << " value='" << escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()), allowWhiteSpace) << "'";
247  }
248 
249  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
250 
251  // close opening field tag
252  if(dispStdOut)
253  std::cout << ((nodeList->getLength() == 0 || (nodeList->getLength() == 1 && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE))
254  ? "/"
255  : "")
256  << ">"
257  << " len:" << nodeList->getLength() << std::endl;
258  if(out)
259  {
260  // *out << ((nodeList->getLength() == 0 ||
261  // (nodeList->getLength() == 1 &&
262  // currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE))
263  // ? "/"
264  // : "")
265  // << ">" << std::endl;
266  // Dario-style...
267  std::string outText = "";
268  if(currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
269  outText = escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()), allowWhiteSpace);
270  {
271  if(darioXMLStyle_ && !(std::string(XML_TO_CHAR(currEl->getNodeName())) == "ROOT" || std::string(XML_TO_CHAR(currEl->getNodeName())) == "HEADER" ||
272  std::string(XML_TO_CHAR(currEl->getNodeName())) == "DATA" || std::string(XML_TO_CHAR(currEl->getNodeName())) == "node" ||
273  std::string(XML_TO_CHAR(currEl->getNodeName())) == "nodes"))
274  {
275  *out << ">" << outText << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">" << std::endl;
276  }
277  else
278  {
279  *out << ((nodeList->getLength() == 0 || (nodeList->getLength() == 1 && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE))
280  ? "/"
281  : "")
282  << ">" << std::endl;
283  }
284  }
285  // Dario-style...
286  }
287  // insert children
288  std::string newTabStr = tabStr + "\t";
289  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
290  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) // ignore text node children
291  recursiveOutputXmlDocument((xercesc::DOMElement*)(nodeList->item(i)), out, dispStdOut, newTabStr, allowWhiteSpace);
292 
293  // close tag if children
294  if(nodeList->getLength() > 1 || (nodeList->getLength() == 1 && currEl->getFirstChild()->getNodeType() != xercesc::DOMNode::TEXT_NODE))
295  {
296  if(dispStdOut)
297  __COUT__ << tabStr << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">" << std::endl;
298  if(out)
299  *out << tabStr << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">" << std::endl;
300  }
301 }
302 
303 //==============================================================================
304 // HttpXmlDocument::getMatchingValue
305 // returns the value for field found occurance number of times
306 // returns empty std::string "" if field was not found
307 std::string HttpXmlDocument::getMatchingValue(const std::string& field, const unsigned int occurance)
308 {
309  unsigned int count = 0;
310  return recursiveFindElementValue(theDocument_->getDocumentElement(), field, occurance, count);
311 }
312 
313 //==============================================================================
314 // HttpXmlDocument::recursiveFindElement
315 // recursively searches and returns the value for field found occurance number of times
316 std::string HttpXmlDocument::recursiveFindElementValue(xercesc::DOMElement* currEl, const std::string& field, const unsigned int occurance, unsigned int& count)
317 {
318  if(XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++) // found, done!!
319  {
320  if(currEl->getFirstChild() != NULL &&
321  currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as value
322  // attribute
323  return escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
324  else
325  return ""; // empty value attribute
326  }
327 
328  std::string retStr;
329  // look through children recursively
330  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
331  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
332  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) // ignore text node children
333  {
334  retStr = recursiveFindElementValue((xercesc::DOMElement*)(nodeList->item(i)), field, occurance, count);
335  if(retStr != "")
336  return retStr; // found among children already, done
337  // else continue search within children recursively
338  }
339  return ""; // nothing found
340 }
341 
342 //==============================================================================
343 // HttpXmlDocument::getAllMatchingValues
344 // returns all of the values found for the field in a vector
345 // if none found vector will have size 0
346 void HttpXmlDocument::getAllMatchingValues(const std::string& field, std::vector<std::string>& retVec)
347 {
348  recursiveFindAllElements(theDocument_->getDocumentElement(), field, &retVec);
349 }
350 
351 //==============================================================================
352 // HttpXmlDocument::recursiveFindElement
353 // recursively searches and returns the value for field found occurance number of times
354 void HttpXmlDocument::recursiveFindAllElements(xercesc::DOMElement* currEl, const std::string& field, std::vector<std::string>* retVec)
355 {
356  if(XML_TO_CHAR(currEl->getNodeName()) == field && currEl->getFirstChild() != NULL &&
357  currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as value
358  // attribute
359  retVec->push_back(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
360 
361  // look through children recursively
362  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
363  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
364  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) // ignore text node children
365  recursiveFindAllElements((xercesc::DOMElement*)(nodeList->item(i)), field, retVec);
366 }
367 
368 //==============================================================================
369 // HttpXmlDocument::getMatchingElement
370 // returns the element for field found occurance number of times
371 // returns null if field was not found
372 xercesc::DOMElement* HttpXmlDocument::getMatchingElement(const std::string& field, const unsigned int occurance)
373 {
374  return getMatchingElementInSubtree(theDocument_->getDocumentElement(), field, occurance);
375 }
376 
377 //==============================================================================
378 // HttpXmlDocument::getMatchingElementInSubtree
379 // returns the element for field found occurance number of times within the subtree
380 // specified by parentEl
381 // returns null if field was not found
382 xercesc::DOMElement* HttpXmlDocument::getMatchingElementInSubtree(xercesc::DOMElement* parentEl, const std::string& field, const unsigned int occurance)
383 {
384  unsigned int count = 0;
385  return recursiveFindElement(parentEl, field, occurance, count);
386 }
387 
388 //==============================================================================
389 // HttpXmlDocument::recursiveFindElement
390 // recursively searches and returns the element for field found occurance number of times
391 xercesc::DOMElement* HttpXmlDocument::recursiveFindElement(xercesc::DOMElement* currEl,
392  const std::string& field,
393  const unsigned int occurance,
394  unsigned int& count)
395 {
396  if(XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++) // found, done!!
397  {
398  if(currEl->getFirstChild() != NULL &&
399  currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as value
400  // attribute
401  return currEl;
402  else
403  return 0; // empty value attribute
404  }
405 
406  xercesc::DOMElement* retEl;
407  // look through children recursively
408  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
409  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
410  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) // ignore text node children
411  {
412  retEl = recursiveFindElement((xercesc::DOMElement*)(nodeList->item(i)), field, occurance, count);
413  if(retEl)
414  return retEl; // found among children already, done
415  // else continue search within children recursively
416  }
417  return 0; // nothing found
418 }
419 
420 //==============================================================================
421 // HttpXmlDocument::recursiveAddElementToParent
422 // add currEl and its children tree to parentEl
423 // note: attributes are not considered here
424 void HttpXmlDocument::recursiveAddElementToParent(xercesc::DOMElement* child, xercesc::DOMElement* parent, bool html)
425 {
426  std::string childText = "";
427 
428  std::string childName = XML_TO_CHAR(child->getNodeName()); // XML_TO_CHAR(currEl->getNodeName());
429 
430  if(child->getFirstChild() != NULL && child->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) // if has a text node first, insert as value
431  // attribute
432  {
433  childText = XML_TO_CHAR(child->getFirstChild()->getNodeValue());
434  if(html)
435  childText = escapeString(childText);
436  }
437  // __COUT__<< "childName " << childName << " childText " <<
438  // childText << std::endl;
439 
440  // insert child
441  xercesc::DOMElement* newParent = addTextElementToParent(childName, childText, parent);
442 
443  // insert rest of child tree
444  xercesc::DOMNodeList* nodeList = child->getChildNodes(); // get all children of child
445  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
446  {
447  if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE) // ignore text node children
448  continue;
449 
450  recursiveAddElementToParent((xercesc::DOMElement*)(nodeList->item(i)), newParent, html);
451  }
452 }
453 
454 //==============================================================================
455 // HttpXmlDocument::getAllMatchingElements
456 // returns all of the values found for the field in a vector
457 // if none found vector will have size 0
458 void HttpXmlDocument::getAllMatchingElements(const std::string& field, std::vector<xercesc::DOMElement*>& retVec)
459 {
460  recursiveFindAllElements(theDocument_->getDocumentElement(), field, &retVec);
461 }
462 
463 //==============================================================================
464 // HttpXmlDocument::recursiveFindElement
465 // recursively searches and returns the value for field found occurance number of times
466 void HttpXmlDocument::recursiveFindAllElements(xercesc::DOMElement* currEl, const std::string& field, std::vector<xercesc::DOMElement*>* retVec)
467 {
468  if(XML_TO_CHAR(currEl->getNodeName()) == field && currEl->getFirstChild() != NULL &&
469  currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) // if has a text node first, return as value
470  // attribute
471  retVec->push_back(currEl);
472 
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() != xercesc::DOMNode::TEXT_NODE) // ignore text node children
477  recursiveFindAllElements((xercesc::DOMElement*)(nodeList->item(i)), field, retVec);
478 }
479 //==============================================================================
480 // HttpXmlDocument::escapeString
481 // convert quotes to html quote characters &apos = ' and &quot = "
482 // remove new line characters
483 // and remove white space (so that read from file white space artifact removed)
484 /*
485 std::string HttpXmlDocument::escapeString(string inString)
486 {
487  unsigned int ws = -1;
488  for(unsigned int i=0;i<inString.length();++i)
489  if(inString[i] != ' ')
490  {
491  if(inString[i] == '\r' || inString[i] == '\n') //remove new line chars
492  {
493  inString.erase(i,1); // replace special character with ;
494  --i; //step back so next char to check is correct
495  continue;
496  }
497 
498  ws = i; //last non white space char
499  if(inString[i] == '\"' || inString[i] == '\'')
500  {
501  inString.insert(i,(inString[i] == '\'')?"&apos":"&quot"); //insert \
502 before quotes inString.replace(i+5,1,1,';'); // replace special character with ;
503  i+=5; //skip to next char to check
504  }
505  }
506 
507  if(ws == (unsigned int)-1) return ""; //empty std::string since all white space
508  return inString.substr(0,ws+1); //trim right white space
509 }
510 */
511 //==============================================================================
512 // loadXmlDocument
513 // returns false if file does not exist
514 bool HttpXmlDocument::loadXmlDocument(const std::string& filePath)
515 {
516  // __COUT__<< "Loading theDocument_ from file: " << filePath <<
517  // std::endl;
518 
519  struct stat fileStatus;
520 
521  if(stat(filePath.c_str(), &fileStatus) != 0)
522  {
523  //__SS__ << "File not accessible: " << filePath << std::endl;
524  //__SS_THROW__;
525  return false; //not an error for file to not exist
526  }
527 
528  // reset xml platform and theDocument_
529  terminatePlatform();
530  initPlatform();
531 
532  xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser;
533  // Configure xercesc::DOM parser.
534  parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
535  parser->setDoNamespaces(true);
536  parser->setDoSchema(true);
537  parser->useCachedGrammarInParse(false);
538 
539  try
540  {
541  parser->parse(filePath.c_str());
542 
543  // theDocument_ memory object owned by the parent parser object
544  theDocument_ = parser->adoptDocument(); // instead of getDocument() so parser
545  // will not free theDocument_ when
546  // released
547 
548  // Get the top-level element: Name is "root". No attributes for "root"
549  rootElement_ = theDocument_->getDocumentElement();
550  if(!rootElement_)
551  {
552  __SS__ << "empty XML theDocument_: " << filePath << std::endl;
553  __SS_THROW__;
554  throw(std::runtime_error("empty XML theDocument_"));
555  }
556 
557  recursiveFixTextFields(rootElement_); // remove space and new lines from value attribute
558 
559  xercesc::DOMNodeList* nodeList = theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_));
560  if(nodeList->getLength()) // may not always be header element
561  headerElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_))->item(0));
562  else
563  headerElement_ = 0;
564 
565  dataElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(dataTagName_))->item(0)); // always is data
566  }
567  catch(xercesc::XMLException& e)
568  {
569  __SS__ << "Error parsing file: " << filePath << std::endl;
570  __SS_THROW__;
571  __COUT__ << "Error parsing file." << std::endl;
572  return false;
573  }
574  delete parser;
575 
576  return true;
577 }
578 
579 //==============================================================================
580 // HttpXmlDocument::recursiveFixTextFields
581 // recursively printout XML theDocument_ to std out and output stream if not null
582 void HttpXmlDocument::recursiveFixTextFields(xercesc::DOMElement* currEl)
583 {
584  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
585 
586  // recurse through children
587  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
588  if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE) // fix text nodes
589  ((xercesc::DOMElement*)(nodeList->item(i)))
590  ->setTextContent(CONVERT_TO_XML( // change text value to escaped version
591  escapeString(XML_TO_CHAR(((xercesc::DOMElement*)(nodeList->item(i)))->getNodeValue()))));
592  else
593  recursiveFixTextFields((xercesc::DOMElement*)(nodeList->item(i)));
594 }
595 
596 //==============================================================================
597 // HttpXmlDocument::addDataElement
598 // Add field/value element to XML doc at parentIndexArray (with depth of parent indicated
599 // by parentIndexArraySize) If parentIndexArray = NULL, element is added with <DATA>
600 // parent otherwise, parentIndexArray indicates the parent within the node list for
601 //<DATA> where the element will be added
602 // On Success, The child index of the added element with respect to the parent is
603 // returned and can be used to add
604 // children to the new element
605 // On Failure, return -1
606 /*
607 xercesc::DOMElement* HttpXmlDocument::addDataElement ( std::string field, std::string
608 value, unsigned int *parentIndexArray, unsigned int parentIndexArraySize)
609 {
610 
611  //__COUT__ << "field: " << field << ", value: " << value << ",
612 parent: " << parentIndexArraySize << std::endl;
613 
614  xercesc::DOMElement* parentEl = dataElement_; // initialize parent to <DATA>
615 
616  if(parentIndexArray) //if there passed an array find parent relative to data element
617  {
618  //__COUT__<< "Using Parent Index Array" << std::endl;
619 
620  xercesc::DOMNodeList *nodeList;
621 
622  //iterate through nested parents based on parentIndexArray
623  unsigned int tmpi,cntNotTxt;
624  for(unsigned int i=0;i<parentIndexArraySize;++i)
625  {
626  nodeList = parentEl->getChildNodes(); //get all children
627  cntNotTxt = 0;
628 
629  //get cntNotTxt to proper non text node
630  for(tmpi=0;tmpi<nodeList->getLength();++tmpi)
631  {
632  if(((xercesc::DOMElement*)(nodeList->item(tmpi)))->getNodeType() ==
633 xercesc::DOMNode::TEXT_NODE) continue; //skip text nodes
634 
635  if(cntNotTxt == parentIndexArray[i]) break; //at proper parent node!
636  ++cntNotTxt; //else look for next
637  }
638 
639  //in theory, only first child can be text - ignore text node children
640  //if(parentEl->getFirstChild() != NULL &&
641 parentEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) ++tmpi;
642 
643  if(tmpi >= nodeList->getLength())
644  {
645  __COUT__ << "illegal child index attempted in nested
646 parents: " << parentIndexArray[i] << ", depth: " << i << ", tmpi: " << tmpi << std::endl;
647  return 0; //illegal child index attempted in nested parents
648  }
649 
650  parentEl = (xercesc::DOMElement*)(nodeList->item(tmpi));
651  }
652  }
653 
654  return addTextElementToParent(field,value,parentEl);
655 }
656 */