otsdaq  v2_01_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/CoutMacros.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,
285  const unsigned int occurance, unsigned int &count)
286 {
287  if (XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++) //found, done!!
288  {
289  if( currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, return as value attribute
290  return escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
291  else
292  return ""; //empty value attribute
293  }
294 
295  std::string retStr;
296  //look through children recursively
297  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
298  for(unsigned int i = 0; i<nodeList->getLength();++i)
299  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) //ignore text node children
300  {
301  retStr = recursiveFindElementValue ((xercesc::DOMElement*)(nodeList->item(i)),field,occurance,count);
302  if(retStr != "") return retStr; //found among children already, done
303  //else continue search within children recursively
304  }
305  return ""; //nothing found
306 }
307 
308 //==============================================================================
309 //HttpXmlDocument::getAllMatchingValues
310 // returns all of the values found for the field in a vector
311 // if none found vector will have size 0
312 void HttpXmlDocument::getAllMatchingValues (const std::string &field, std::vector<std::string> &retVec)
313 {
314  recursiveFindAllElements(theDocument_->getDocumentElement(),field,&retVec);
315 }
316 
317 //==============================================================================
318 //HttpXmlDocument::recursiveFindElement
319 // recursively searches and returns the value for field found occurance number of times
320 void HttpXmlDocument::recursiveFindAllElements (xercesc::DOMElement *currEl, const std::string &field,std::vector<std::string> *retVec)
321 {
322  if (XML_TO_CHAR(currEl->getNodeName()) == field &&
323  currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, return as value attribute
324  retVec->push_back(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
325 
326 
327  //look through children recursively
328  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
329  for(unsigned int i = 0; i<nodeList->getLength();++i)
330  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) //ignore text node children
331  recursiveFindAllElements ((xercesc::DOMElement*)(nodeList->item(i)),field,retVec);
332 }
333 
334 //==============================================================================
335 //HttpXmlDocument::getMatchingElement
336 // returns the element for field found occurance number of times
337 // returns null if field was not found
338 xercesc::DOMElement* HttpXmlDocument::getMatchingElement (const std::string &field, const unsigned int occurance)
339 {
340  return getMatchingElementInSubtree(theDocument_->getDocumentElement(),field,occurance);
341 }
342 
343 //==============================================================================
344 //HttpXmlDocument::getMatchingElementInSubtree
345 // returns the element for field found occurance number of times within the subtree
346 // specified by parentEl
347 // returns null if field was not found
348 xercesc::DOMElement* HttpXmlDocument::getMatchingElementInSubtree (xercesc::DOMElement *parentEl, const std::string &field,
349  const unsigned int occurance)
350 {
351  unsigned int count = 0;
352  return recursiveFindElement(parentEl,field,occurance,count);
353 }
354 
355 //==============================================================================
356 //HttpXmlDocument::recursiveFindElement
357 // recursively searches and returns the element for field found occurance number of times
358 xercesc::DOMElement* HttpXmlDocument::recursiveFindElement (xercesc::DOMElement *currEl, const std::string &field,
359  const unsigned int occurance, unsigned int &count)
360 {
361  if (XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++) //found, done!!
362  {
363  if( currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, return as value attribute
364  return currEl;
365  else
366  return 0; //empty value attribute
367  }
368 
369  xercesc::DOMElement* retEl;
370  //look through children recursively
371  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
372  for(unsigned int i = 0; i<nodeList->getLength();++i)
373  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) //ignore text node children
374  {
375  retEl = recursiveFindElement ((xercesc::DOMElement*)(nodeList->item(i)),field,occurance,count);
376  if(retEl) return retEl; //found among children already, done
377  //else continue search within children recursively
378  }
379  return 0; //nothing found
380 }
381 
382 //==============================================================================
383 //HttpXmlDocument::recursiveAddElementToParent
384 // add currEl and its children tree to parentEl
385 // note: attributes are not considered here
386 void HttpXmlDocument::recursiveAddElementToParent(xercesc::DOMElement* child, xercesc::DOMElement* parent, bool html)
387 {
388  std::string childText = "";
389 
390  std::string childName = XML_TO_CHAR(child->getNodeName());//XML_TO_CHAR(currEl->getNodeName());
391 
392  if( child->getFirstChild() != NULL && child->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, insert as value attribute
393  {
394  childText = XML_TO_CHAR(child->getFirstChild()->getNodeValue());
395  if(html)
396  childText = escapeString(childText);
397  }
398  //std::cout << __COUT_HDR_FL__<< "childName " << childName << " childText " << childText << std::endl;
399 
400  //insert child
401  xercesc::DOMElement* newParent = addTextElementToParent(childName, childText, parent);
402 
403  //insert rest of child tree
404  xercesc::DOMNodeList *nodeList = child->getChildNodes(); //get all children of child
405  for(unsigned int i = 0; i<nodeList->getLength();++i)
406  {
407  if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE) //ignore text node children
408  continue;
409 
410  recursiveAddElementToParent((xercesc::DOMElement*)(nodeList->item(i)), newParent, html);
411  }
412 }
413 
414 //==============================================================================
415 //HttpXmlDocument::getAllMatchingElements
416 // returns all of the values found for the field in a vector
417 // if none found vector will have size 0
418 void HttpXmlDocument::getAllMatchingElements (const std::string &field, std::vector<xercesc::DOMElement*> &retVec)
419 {
420  recursiveFindAllElements(theDocument_->getDocumentElement(),field,&retVec);
421 }
422 
423 
424 //==============================================================================
425 //HttpXmlDocument::recursiveFindElement
426 // recursively searches and returns the value for field found occurance number of times
427 void HttpXmlDocument::recursiveFindAllElements (xercesc::DOMElement *currEl, const std::string &field,std::vector<xercesc::DOMElement*> *retVec)
428 {
429  if (XML_TO_CHAR(currEl->getNodeName()) == field &&
430  currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, return as value attribute
431  retVec->push_back(currEl);
432 
433 
434  //look through children recursively
435  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
436  for(unsigned int i = 0; i<nodeList->getLength();++i)
437  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) //ignore text node children
438  recursiveFindAllElements ((xercesc::DOMElement*)(nodeList->item(i)),field,retVec);
439 }
440 //==============================================================================
441 //HttpXmlDocument::escapeString
442 // convert quotes to html quote characters &apos = ' and &quot = "
443 // remove new line characters
444 // and remove white space (so that read from file white space artifact removed)
445 /*
446 std::string HttpXmlDocument::escapeString(string inString)
447 {
448  unsigned int ws = -1;
449  for(unsigned int i=0;i<inString.length();++i)
450  if(inString[i] != ' ')
451  {
452  if(inString[i] == '\r' || inString[i] == '\n') //remove new line chars
453  {
454  inString.erase(i,1); // replace special character with ;
455  --i; //step back so next char to check is correct
456  continue;
457  }
458 
459  ws = i; //last non white space char
460  if(inString[i] == '\"' || inString[i] == '\'')
461  {
462  inString.insert(i,(inString[i] == '\'')?"&apos":"&quot"); //insert \ before quotes
463  inString.replace(i+5,1,1,';'); // replace special character with ;
464  i+=5; //skip to next char to check
465  }
466  }
467 
468  if(ws == (unsigned int)-1) return ""; //empty std::string since all white space
469  return inString.substr(0,ws+1); //trim right white space
470 }
471 */
472 //==============================================================================
473 //loadXmlDocument
474 // returns false if xml doc could not be opened
475 bool HttpXmlDocument::loadXmlDocument (const std::string &filePath)
476 {
477  //std::cout << __COUT_HDR_FL__<< "Loading theDocument_ from file: " << filePath << std::endl;
478 
479  struct stat fileStatus;
480 
481  if(stat(filePath.c_str(), &fileStatus) != 0)
482  {
483  std::cout << __COUT_HDR_FL__<< "File not accessible." << std::endl;
484  return false;
485  }
486 
487  //reset xml platform and theDocument_
488  terminatePlatform();
489  initPlatform();
490 
491  xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser;
492  // Configure xercesc::DOM parser.
493  parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
494  parser->setDoNamespaces ( true );
495  parser->setDoSchema ( true );
496  parser->useCachedGrammarInParse ( false );
497 
498  try
499  {
500  parser->parse( filePath.c_str() );
501 
502  //theDocument_ memory object owned by the parent parser object
503  theDocument_ = parser->adoptDocument();//instead of getDocument() so parser will not free theDocument_ when released
504 
505  // Get the top-level element: Name is "root". No attributes for "root"
506  rootElement_ = theDocument_->getDocumentElement();
507  if( !rootElement_ )
508  throw(std::runtime_error( "empty XML theDocument_" ));
509 
510  recursiveFixTextFields(rootElement_); //remove space and new lines from value attribute
511 
512  xercesc::DOMNodeList *nodeList = theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_));
513  if(nodeList->getLength()) //may not always be header element
514  headerElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_))->item(0));
515  else
516  headerElement_ = 0;
517 
518  dataElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(dataTagName_))->item(0)); //always is data
519  }
520  catch( xercesc::XMLException& e )
521  {
522  std::cout << __COUT_HDR_FL__<< "Error parsing file." << std::endl;
523  return false;
524  }
525  delete parser;
526 
527  return true;
528 }
529 
530 //==============================================================================
531 //HttpXmlDocument::recursiveFixTextFields
532 // recursively printout XML theDocument_ to std out and output stream if not null
533 void HttpXmlDocument::recursiveFixTextFields(xercesc::DOMElement *currEl)
534 {
535  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
536 
537  //recurse through children
538  for(unsigned int i = 0; i<nodeList->getLength();++i)
539  if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE) //fix text nodes
540  ((xercesc::DOMElement*)(nodeList->item(i)))->setTextContent(CONVERT_TO_XML( //change text value to escaped version
541  escapeString(XML_TO_CHAR(((xercesc::DOMElement*)(nodeList->item(i)))->getNodeValue()))));
542  else
543  recursiveFixTextFields ((xercesc::DOMElement*)(nodeList->item(i)));
544 }
545 
546 //==============================================================================
547 //HttpXmlDocument::addDataElement
548 // Add field/value element to XML doc at parentIndexArray (with depth of parent indicated by parentIndexArraySize)
549 // If parentIndexArray = NULL, element is added with <DATA> parent
550 // otherwise, parentIndexArray indicates the parent within the node list for <DATA> where
551 // the element will be added
552 // On Success, The child index of the added element with respect to the parent is returned and can be used to add
553 // children to the new element
554 // On Failure, return -1
555 /*
556 xercesc::DOMElement* HttpXmlDocument::addDataElement ( std::string field, std::string value, unsigned int *parentIndexArray, unsigned int parentIndexArraySize)
557 {
558 
559  //std::cout << __COUT_HDR_FL__ << "field: " << field << ", value: " << value << ", parent: " << parentIndexArraySize << std::endl;
560 
561  xercesc::DOMElement* parentEl = dataElement_; // initialize parent to <DATA>
562 
563  if(parentIndexArray) //if there passed an array find parent relative to data element
564  {
565  //std::cout << __COUT_HDR_FL__<< "Using Parent Index Array" << std::endl;
566 
567  xercesc::DOMNodeList *nodeList;
568 
569  //iterate through nested parents based on parentIndexArray
570  unsigned int tmpi,cntNotTxt;
571  for(unsigned int i=0;i<parentIndexArraySize;++i)
572  {
573  nodeList = parentEl->getChildNodes(); //get all children
574  cntNotTxt = 0;
575 
576  //get cntNotTxt to proper non text node
577  for(tmpi=0;tmpi<nodeList->getLength();++tmpi)
578  {
579  if(((xercesc::DOMElement*)(nodeList->item(tmpi)))->getNodeType() == xercesc::DOMNode::TEXT_NODE) continue; //skip text nodes
580 
581  if(cntNotTxt == parentIndexArray[i]) break; //at proper parent node!
582  ++cntNotTxt; //else look for next
583  }
584 
585  //in theory, only first child can be text - ignore text node children
586  //if(parentEl->getFirstChild() != NULL && parentEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) ++tmpi;
587 
588  if(tmpi >= nodeList->getLength())
589  {
590  std::cout << __COUT_HDR_FL__ << "illegal child index attempted in nested parents: " << parentIndexArray[i] << ", depth: " << i << ", tmpi: " << tmpi << std::endl;
591  return 0; //illegal child index attempted in nested parents
592  }
593 
594  parentEl = (xercesc::DOMElement*)(nodeList->item(tmpi));
595  }
596  }
597 
598  return addTextElementToParent(field,value,parentEl);
599 }
600 */
601