otsdaq  v2_00_00
HttpXmlDocument.cc
1 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
2 #include "otsdaq-core/XmlUtilities/ConvertToXML.h"
3 #include "otsdaq-core/XmlUtilities/ConvertFromXML.h"
4 #include "otsdaq-core/MessageFacility/MessageFacility.h"
5 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
6 
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/DOMImplementationRegistry.hpp>
15 #include <xercesc/dom/DOMImplementationLS.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/util/OutOfMemoryException.hpp>
28 #include <xercesc/framework/LocalFileFormatTarget.hpp>
29 
30 #include <iostream>
31 #include <sstream>
32 #include <list>
33 
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <unistd.h>
37 #include <errno.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 
63  //std::cout << __COUT_HDR_FL__ << "in" << std::endl;
64  //<HEADER>
65  if(cookieCode != "" || displayName != "") //add header
66  {
67  headerElement_ = theDocument_->createElement(CONVERT_TO_XML(headerTagName_));
68  rootElement_->appendChild(headerElement_);
69  if(cookieCode != "") //add cookie code to header
70  addTextElementToParent(cookieCodeTagName_,cookieCode,headerElement_);
71  if(displayName != "") //add display name to header
72  addTextElementToParent(displayNameTagName_,displayName,headerElement_);
73  }
74 
75  //<DATA>
76  dataElement_ = theDocument_->createElement(CONVERT_TO_XML(dataTagName_));
77  rootElement_->appendChild(dataElement_);
78  //std::cout << __COUT_HDR_FL__ << "out" << std::endl;
79 }
80 
81 //==============================================================================
82 HttpXmlDocument::HttpXmlDocument(const HttpXmlDocument& doc) :
83  XmlDocument(doc),
84  headerElement_ (0),
85  dataElement_ (0),
86  headerTagName_ (doc.headerTagName_),
87  dataTagName_ (doc.dataTagName_),
88  cookieCodeTagName_ (doc.cookieCodeTagName_),
89  displayNameTagName_(doc.displayNameTagName_)
90 {
91  //std::cout << __COUT_HDR_FL__ << "in" << std::endl;
92  *this = doc;
93  //std::cout << __COUT_HDR_FL__ << "out" << std::endl;
94 }
95 
96 //==============================================================================
97 HttpXmlDocument& HttpXmlDocument::operator=(const HttpXmlDocument& doc)
98 {
99  //std::cout << __COUT_HDR_FL__ << "in" << std::endl;
100  recursiveElementCopy(doc.rootElement_, rootElement_);
101  if(doc.headerElement_ != 0)
102  headerElement_ = (xercesc::DOMElement*)rootElement_->getElementsByTagName(CONVERT_TO_XML(headerTagName_))->item(0);
103  dataElement_ = (xercesc::DOMElement*)rootElement_->getElementsByTagName(CONVERT_TO_XML(dataTagName_))->item(0);
104  //std::cout << __COUT_HDR_FL__ << "out" << std::endl;
105  return *this;
106 }
107 
108 //==============================================================================
109 HttpXmlDocument::~HttpXmlDocument(void)
110 {}
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 header element.";
119  throw std::runtime_error(ss.str());
120  }
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,
136  const std::string &childValue)
137 {
138  //std::cout << __COUT_HDR_FL__ << "in - " << childName << " value: " << childValue <<std::endl << std::endl;
139  return addTextElementToParent(childName,childValue,dataElement_);
140 }
141 
142 //==============================================================================
143 xercesc::DOMElement* HttpXmlDocument::addBinaryStringToData(const std::string &childName,
144  const std::string &binary)
145 {
146  std::string convertStr = "";
147  char hexStr[3];
148  for(unsigned int i=0;i<binary.length();++i)
149  {
150  //for every byte make hex
151  sprintf(hexStr,"%2.2X",((unsigned char)binary[i]));
152  hexStr[2] = '\0';
153  convertStr += hexStr;
154  }
155 
156  return addTextElementToParent(childName,convertStr,dataElement_);
157 }
158 
159 //==============================================================================
160 //HttpXmlDocument::getChildrenCount
161 // get count of children ignoring text nodes.
162 unsigned int HttpXmlDocument::getChildrenCount(xercesc::DOMElement* parent)
163 {
164  if(!parent) parent = dataElement_; //default to data element
165 
166  xercesc::DOMNodeList* nodeList = parent->getChildNodes(); //get all children within parent
167  unsigned int count = 0;
168 
169  for(unsigned int i = 0; i<nodeList->getLength();++i) {
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 null
221 void HttpXmlDocument::outputXmlDocument (std::ostringstream *out, bool dispStdOut,
222  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 (xercesc::DOMElement *currEl, std::ostringstream *out,
231  bool dispStdOut, std::string tabStr, bool allowWhiteSpace)
232 {
233  //open field tag
234  if(dispStdOut) std::cout << __COUT_HDR_FL__<< tabStr << "<" << XML_TO_CHAR(currEl->getNodeName()) ;
235  if(out) *out << tabStr << "<" << XML_TO_CHAR(currEl->getNodeName());
236 
237  //insert value if text node child
238  if( currEl->getFirstChild() != NULL &&
239  currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, insert as value attribute
240  {
241  if(dispStdOut) std::cout << " value='" <<
242  escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()),allowWhiteSpace) << "'";
243  if(out) *out << " value='" <<
244  escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()),allowWhiteSpace) << "'";
245  }
246 
247  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
248 
249  //close opening field tag
250  if(dispStdOut) std::cout << ((nodeList->getLength() == 0 ||
251  (nodeList->getLength() == 1 && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE))? "/":"")
252  << ">" << " len:" << nodeList->getLength() << std::endl;
253  if(out) *out << ((nodeList->getLength() == 0 ||
254  (nodeList->getLength() == 1 && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE))? "/":"")
255  << ">" << std::endl;
256 
257  //insert children
258  std::string newTabStr = tabStr + "\t";
259  for(unsigned int i = 0; i<nodeList->getLength();++i)
260  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) //ignore text node children
261  recursiveOutputXmlDocument ((xercesc::DOMElement*)(nodeList->item(i)),out,dispStdOut,newTabStr,allowWhiteSpace);
262 
263  //close tag if children
264  if(nodeList->getLength() > 1 || (nodeList->getLength() == 1 && currEl->getFirstChild()->getNodeType() != xercesc::DOMNode::TEXT_NODE))
265  {
266  if(dispStdOut) std::cout << __COUT_HDR_FL__<< tabStr << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">" << std::endl;
267  if(out) *out << tabStr << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">" << std::endl;
268  }
269 }
270 
271 //==============================================================================
272 //HttpXmlDocument::getMatchingValue
273 // returns the value for field found occurance number of times
274 // returns empty std::string "" if field was not found
275 std::string HttpXmlDocument::getMatchingValue (const std::string &field, const unsigned int occurance)
276 {
277  unsigned int count = 0;
278  return recursiveFindElementValue(theDocument_->getDocumentElement(),field,occurance,count);
279 }
280 
281 //==============================================================================
282 //HttpXmlDocument::recursiveFindElement
283 // recursively searches and returns the value for field found occurance number of times
284 std::string HttpXmlDocument::recursiveFindElementValue (xercesc::DOMElement *currEl, const std::string &field, const unsigned int occurance, unsigned int &count)
285 {
286  if (XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++) //found, done!!
287  {
288  if( currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, return as value attribute
289  return escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
290  else
291  return ""; //empty value attribute
292  }
293 
294  std::string retStr;
295  //look through children recursively
296  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
297  for(unsigned int i = 0; i<nodeList->getLength();++i)
298  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) //ignore text node children
299  {
300  retStr = recursiveFindElementValue ((xercesc::DOMElement*)(nodeList->item(i)),field,occurance,count);
301  if(retStr != "") return retStr; //found among children already, done
302  //else continue search within children recursively
303  }
304  return ""; //nothing found
305 }
306 
307 //==============================================================================
308 //HttpXmlDocument::getAllMatchingValues
309 // returns all of the values found for the field in a vector
310 // if none found vector will have size 0
311 void HttpXmlDocument::getAllMatchingValues (const std::string &field, std::vector<std::string> &retVec)
312 {
313  recursiveFindAllElements(theDocument_->getDocumentElement(),field,&retVec);
314 }
315 
316 //==============================================================================
317 //HttpXmlDocument::recursiveFindElement
318 // recursively searches and returns the value for field found occurance number of times
319 void HttpXmlDocument::recursiveFindAllElements (xercesc::DOMElement *currEl, const std::string &field,std::vector<std::string> *retVec)
320 {
321  if (XML_TO_CHAR(currEl->getNodeName()) == field &&
322  currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, return as value attribute
323  retVec->push_back(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
324 
325 
326  //look through children recursively
327  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
328  for(unsigned int i = 0; i<nodeList->getLength();++i)
329  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) //ignore text node children
330  recursiveFindAllElements ((xercesc::DOMElement*)(nodeList->item(i)),field,retVec);
331 }
332 
333 //==============================================================================
334 //HttpXmlDocument::getMatchingElement
335 // returns the element for field found occurance number of times
336 // returns null if field was not found
337 xercesc::DOMElement* HttpXmlDocument::getMatchingElement (const std::string &field, const unsigned int occurance)
338 {
339  return getMatchingElementInSubtree(theDocument_->getDocumentElement(),field,occurance);
340 }
341 
342 //==============================================================================
343 //HttpXmlDocument::getMatchingElementInSubtree
344 // returns the element for field found occurance number of times within the subtree
345 // specified by parentEl
346 // returns null if field was not found
347 xercesc::DOMElement* HttpXmlDocument::getMatchingElementInSubtree (xercesc::DOMElement *parentEl, const std::string &field,
348  const unsigned int occurance)
349 {
350  unsigned int count = 0;
351  return recursiveFindElement(parentEl,field,occurance,count);
352 }
353 
354 //==============================================================================
355 //HttpXmlDocument::recursiveFindElement
356 // recursively searches and returns the element for field found occurance number of times
357 xercesc::DOMElement* HttpXmlDocument::recursiveFindElement (xercesc::DOMElement *currEl, const std::string &field,
358  const unsigned int occurance, unsigned int &count)
359 {
360  if (XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++) //found, done!!
361  {
362  if( currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, return as value attribute
363  return currEl;
364  else
365  return 0; //empty value attribute
366  }
367 
368  xercesc::DOMElement* retEl;
369  //look through children recursively
370  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
371  for(unsigned int i = 0; i<nodeList->getLength();++i)
372  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) //ignore text node children
373  {
374  retEl = recursiveFindElement ((xercesc::DOMElement*)(nodeList->item(i)),field,occurance,count);
375  if(retEl) return retEl; //found among children already, done
376  //else continue search within children recursively
377  }
378  return 0; //nothing found
379 }
380 
381 //==============================================================================
382 //HttpXmlDocument::recursiveAddElementToParent
383 // add currEl and its children tree to parentEl
384 // note: attributes are not considered here
385 void HttpXmlDocument::recursiveAddElementToParent(xercesc::DOMElement* child, xercesc::DOMElement* parent, bool html)
386 {
387  std::string childText = "";
388 
389  std::string childName = XML_TO_CHAR(child->getNodeName());//XML_TO_CHAR(currEl->getNodeName());
390 
391  if( child->getFirstChild() != NULL && child->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, insert as value attribute
392  {
393  childText = XML_TO_CHAR(child->getFirstChild()->getNodeValue());
394  if(html)
395  childText = escapeString(childText);
396  }
397  //std::cout << __COUT_HDR_FL__<< "childName " << childName << " childText " << childText << std::endl;
398 
399  //insert child
400  xercesc::DOMElement* newParent = addTextElementToParent(childName, childText, parent);
401 
402  //insert rest of child tree
403  xercesc::DOMNodeList *nodeList = child->getChildNodes(); //get all children of child
404  for(unsigned int i = 0; i<nodeList->getLength();++i)
405  {
406  if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE) //ignore text node children
407  continue;
408 
409  recursiveAddElementToParent((xercesc::DOMElement*)(nodeList->item(i)), newParent, html);
410  }
411 }
412 
413 //==============================================================================
414 //HttpXmlDocument::getAllMatchingElements
415 // returns all of the values found for the field in a vector
416 // if none found vector will have size 0
417 void HttpXmlDocument::getAllMatchingElements (const std::string &field, std::vector<xercesc::DOMElement*> &retVec)
418 {
419  recursiveFindAllElements(theDocument_->getDocumentElement(),field,&retVec);
420 }
421 
422 
423 //==============================================================================
424 //HttpXmlDocument::recursiveFindElement
425 // recursively searches and returns the value for field found occurance number of times
426 void HttpXmlDocument::recursiveFindAllElements (xercesc::DOMElement *currEl, const std::string &field,std::vector<xercesc::DOMElement*> *retVec)
427 {
428  if (XML_TO_CHAR(currEl->getNodeName()) == field &&
429  currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, return as value attribute
430  retVec->push_back(currEl);
431 
432 
433  //look through children recursively
434  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
435  for(unsigned int i = 0; i<nodeList->getLength();++i)
436  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) //ignore text node children
437  recursiveFindAllElements ((xercesc::DOMElement*)(nodeList->item(i)),field,retVec);
438 }
439 //==============================================================================
440 //HttpXmlDocument::escapeString
441 // convert quotes to html quote characters &apos = ' and &quot = "
442 // remove new line characters
443 // and remove white space (so that read from file white space artifact removed)
444 /*
445 std::string HttpXmlDocument::escapeString(string inString)
446 {
447  unsigned int ws = -1;
448  for(unsigned int i=0;i<inString.length();++i)
449  if(inString[i] != ' ')
450  {
451  if(inString[i] == '\r' || inString[i] == '\n') //remove new line chars
452  {
453  inString.erase(i,1); // replace special character with ;
454  --i; //step back so next char to check is correct
455  continue;
456  }
457 
458  ws = i; //last non white space char
459  if(inString[i] == '\"' || inString[i] == '\'')
460  {
461  inString.insert(i,(inString[i] == '\'')?"&apos":"&quot"); //insert \ before quotes
462  inString.replace(i+5,1,1,';'); // replace special character with ;
463  i+=5; //skip to next char to check
464  }
465  }
466 
467  if(ws == (unsigned int)-1) return ""; //empty std::string since all white space
468  return inString.substr(0,ws+1); //trim right white space
469 }
470 */
471 //==============================================================================
472 //loadXmlDocument
473 // returns false if xml doc could not be opened
474 bool HttpXmlDocument::loadXmlDocument (const std::string &filePath)
475 {
476  //std::cout << __COUT_HDR_FL__<< "Loading theDocument_ from file: " << filePath << std::endl;
477 
478  struct stat fileStatus;
479 
480  if(stat(filePath.c_str(), &fileStatus) != 0)
481  {
482  std::cout << __COUT_HDR_FL__<< "File not accessible." << std::endl;
483  return false;
484  }
485 
486  //reset xml platform and theDocument_
487  terminatePlatform();
488  initPlatform();
489 
490  xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser;
491  // Configure xercesc::DOM parser.
492  parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
493  parser->setDoNamespaces ( true );
494  parser->setDoSchema ( true );
495  parser->useCachedGrammarInParse ( false );
496 
497  try
498  {
499  parser->parse( filePath.c_str() );
500 
501  //theDocument_ memory object owned by the parent parser object
502  theDocument_ = parser->adoptDocument();//instead of getDocument() so parser will not free theDocument_ when released
503 
504  // Get the top-level element: Name is "root". No attributes for "root"
505  rootElement_ = theDocument_->getDocumentElement();
506  if( !rootElement_ )
507  throw(std::runtime_error( "empty XML theDocument_" ));
508 
509  recursiveFixTextFields(rootElement_); //remove space and new lines from value attribute
510 
511  xercesc::DOMNodeList *nodeList = theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_));
512  if(nodeList->getLength()) //may not always be header element
513  headerElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_))->item(0));
514  else
515  headerElement_ = 0;
516 
517  dataElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(dataTagName_))->item(0)); //always is data
518  }
519  catch( xercesc::XMLException& e )
520  {
521  std::cout << __COUT_HDR_FL__<< "Error parsing file." << std::endl;
522  return false;
523  }
524  delete parser;
525 
526  return true;
527 }
528 
529 //==============================================================================
530 //HttpXmlDocument::recursiveFixTextFields
531 // recursively printout XML theDocument_ to std out and output stream if not null
532 void HttpXmlDocument::recursiveFixTextFields(xercesc::DOMElement *currEl)
533 {
534  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
535 
536  //recurse through children
537  for(unsigned int i = 0; i<nodeList->getLength();++i)
538  if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE) //fix text nodes
539  ((xercesc::DOMElement*)(nodeList->item(i)))->setTextContent(CONVERT_TO_XML( //change text value to escaped version
540  escapeString(XML_TO_CHAR(((xercesc::DOMElement*)(nodeList->item(i)))->getNodeValue()))));
541  else
542  recursiveFixTextFields ((xercesc::DOMElement*)(nodeList->item(i)));
543 }
544 
545 //==============================================================================
546 //HttpXmlDocument::addDataElement
547 // Add field/value element to XML doc at parentIndexArray (with depth of parent indicated by parentIndexArraySize)
548 // If parentIndexArray = NULL, element is added with <DATA> parent
549 // otherwise, parentIndexArray indicates the parent within the node list for <DATA> where
550 // the element will be added
551 // On Success, The child index of the added element with respect to the parent is returned and can be used to add
552 // children to the new element
553 // On Failure, return -1
554 /*
555 xercesc::DOMElement* HttpXmlDocument::addDataElement ( std::string field, std::string value, unsigned int *parentIndexArray, unsigned int parentIndexArraySize)
556 {
557 
558  //std::cout << __COUT_HDR_FL__ << "field: " << field << ", value: " << value << ", parent: " << parentIndexArraySize << std::endl;
559 
560  xercesc::DOMElement* parentEl = dataElement_; // initialize parent to <DATA>
561 
562  if(parentIndexArray) //if there passed an array find parent relative to data element
563  {
564  //std::cout << __COUT_HDR_FL__<< "Using Parent Index Array" << std::endl;
565 
566  xercesc::DOMNodeList *nodeList;
567 
568  //iterate through nested parents based on parentIndexArray
569  unsigned int tmpi,cntNotTxt;
570  for(unsigned int i=0;i<parentIndexArraySize;++i)
571  {
572  nodeList = parentEl->getChildNodes(); //get all children
573  cntNotTxt = 0;
574 
575  //get cntNotTxt to proper non text node
576  for(tmpi=0;tmpi<nodeList->getLength();++tmpi)
577  {
578  if(((xercesc::DOMElement*)(nodeList->item(tmpi)))->getNodeType() == xercesc::DOMNode::TEXT_NODE) continue; //skip text nodes
579 
580  if(cntNotTxt == parentIndexArray[i]) break; //at proper parent node!
581  ++cntNotTxt; //else look for next
582  }
583 
584  //in theory, only first child can be text - ignore text node children
585  //if(parentEl->getFirstChild() != NULL && parentEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) ++tmpi;
586 
587  if(tmpi >= nodeList->getLength())
588  {
589  std::cout << __COUT_HDR_FL__ << "illegal child index attempted in nested parents: " << parentIndexArray[i] << ", depth: " << i << ", tmpi: " << tmpi << std::endl;
590  return 0; //illegal child index attempted in nested parents
591  }
592 
593  parentEl = (xercesc::DOMElement*)(nodeList->item(tmpi));
594  }
595  }
596 
597  return addTextElementToParent(field,value,parentEl);
598 }
599 */
600