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