otsdaq  v1_01_03
 All Classes Namespaces Functions
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, const std::string &childValue)
136 {
137  //std::cout << __COUT_HDR_FL__ << "in - " << childName << " value: " << childValue <<std::endl << std::endl;
138  return addTextElementToParent(childName,childValue,dataElement_);
139 }
140 
141 //==============================================================================
142 //HttpXmlDocument::getChildrenCount
143 // get count of children ignoring text nodes.
144 unsigned int HttpXmlDocument::getChildrenCount(xercesc::DOMElement* parent)
145 {
146  if(!parent) parent = dataElement_; //default to data element
147 
148  xercesc::DOMNodeList* nodeList = parent->getChildNodes(); //get all children within parent
149  unsigned int count = 0;
150 
151  for(unsigned int i = 0; i<nodeList->getLength();++i) {
152  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) //ignore text node children
153  ++count;
154  }
155 
156  return count;
157 }
158 
159 //==============================================================================
160 //HttpXmlDocument::removeDataElement
161 // Remove child and child's sub-tree from dataElement. The child is
162 // identified with dataChildIndex.
163 void HttpXmlDocument::removeDataElement(unsigned int dataChildIndex)
164 {
165  xercesc::DOMNodeList* nodeList = dataElement_->getChildNodes(); //get all children within data
166 
167  for(unsigned int i = 0; i<nodeList->getLength();++i)
168  {
169  if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE) //ignore text node children
170  continue;
171 
172  if(!dataChildIndex) //remove
173  {
174  recursiveRemoveChild((xercesc::DOMElement*)(nodeList->item(i)),dataElement_);
175  return;
176  }
177 
178  --dataChildIndex; //find proper child
179  }
180 
181  //here, then child doesnt exist
182 }
183 
184 //==============================================================================
185 //HttpXmlDocument::addXmlData
186 // Append <DATA> from xmldoc to this XML doc
187 void HttpXmlDocument::copyDataChildren(HttpXmlDocument &document)
188 {
189  //add all first level child elements of data and recurse on them
190  xercesc::DOMNodeList* nodeList = document.dataElement_->getChildNodes(); //get all children within data
191  for(unsigned int i = 0; i<nodeList->getLength();++i)
192  {
193  if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE) //ignore text node children
194  continue;
195 
196  recursiveAddElementToParent((xercesc::DOMElement*)(nodeList->item(i)),dataElement_,true);
197  }
198 }
199 
200 //==============================================================================
201 //HttpXmlDocument::outputXmlDocument
202 // recurse through XML theDocument_ and std out and output to stream parameter if not null
203 void HttpXmlDocument::outputXmlDocument (std::ostringstream *out, bool dispStdOut, bool allowWhiteSpace)
204 {
205  recursiveOutputXmlDocument(theDocument_->getDocumentElement(),out,dispStdOut, "", allowWhiteSpace);
206 }
207 
208 //==============================================================================
209 //HttpXmlDocument::recursiveOutputXmlDocument
210 // recursively printout XML theDocument_ to std out and output stream if not null
211 void HttpXmlDocument::recursiveOutputXmlDocument (xercesc::DOMElement *currEl, std::ostringstream *out,
212  bool dispStdOut, std::string tabStr, bool allowWhiteSpace)
213 {
214  //open field tag
215  if(dispStdOut) std::cout << __COUT_HDR_FL__<< tabStr << "<" << XML_TO_CHAR(currEl->getNodeName()) ;
216  if(out) *out << tabStr << "<" << XML_TO_CHAR(currEl->getNodeName());
217 
218  //insert value if text node child
219  if( currEl->getFirstChild() != NULL &&
220  currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, insert as value attribute
221  {
222  if(dispStdOut) std::cout << " value='" <<
223  escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()),allowWhiteSpace) << "'";
224  if(out) *out << " value='" <<
225  escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()),allowWhiteSpace) << "'";
226  }
227 
228  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
229 
230  //close opening field tag
231  if(dispStdOut) std::cout << ((nodeList->getLength() == 0 ||
232  (nodeList->getLength() == 1 && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE))? "/":"")
233  << ">" << " len:" << nodeList->getLength() << std::endl;
234  if(out) *out << ((nodeList->getLength() == 0 ||
235  (nodeList->getLength() == 1 && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE))? "/":"")
236  << ">" << std::endl;
237 
238  //insert children
239  std::string newTabStr = tabStr + "\t";
240  for(unsigned int i = 0; i<nodeList->getLength();++i)
241  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) //ignore text node children
242  recursiveOutputXmlDocument ((xercesc::DOMElement*)(nodeList->item(i)),out,dispStdOut,newTabStr,allowWhiteSpace);
243 
244  //close tag if children
245  if(nodeList->getLength() > 1 || (nodeList->getLength() == 1 && currEl->getFirstChild()->getNodeType() != xercesc::DOMNode::TEXT_NODE))
246  {
247  if(dispStdOut) std::cout << __COUT_HDR_FL__<< tabStr << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">" << std::endl;
248  if(out) *out << tabStr << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">" << std::endl;
249  }
250 }
251 
252 //==============================================================================
253 //HttpXmlDocument::getMatchingValue
254 // returns the value for field found occurance number of times
255 // returns empty std::string "" if field was not found
256 std::string HttpXmlDocument::getMatchingValue (const std::string &field, const unsigned int occurance)
257 {
258  unsigned int count = 0;
259  return recursiveFindElementValue(theDocument_->getDocumentElement(),field,occurance,count);
260 }
261 
262 //==============================================================================
263 //HttpXmlDocument::recursiveFindElement
264 // recursively searches and returns the value for field found occurance number of times
265 std::string HttpXmlDocument::recursiveFindElementValue (xercesc::DOMElement *currEl, const std::string &field, const unsigned int occurance, unsigned int &count)
266 {
267  if (XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++) //found, done!!
268  {
269  if( currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, return as value attribute
270  return escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
271  else
272  return ""; //empty value attribute
273  }
274 
275  std::string retStr;
276  //look through children recursively
277  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
278  for(unsigned int i = 0; i<nodeList->getLength();++i)
279  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) //ignore text node children
280  {
281  retStr = recursiveFindElementValue ((xercesc::DOMElement*)(nodeList->item(i)),field,occurance,count);
282  if(retStr != "") return retStr; //found among children already, done
283  //else continue search within children recursively
284  }
285  return ""; //nothing found
286 }
287 
288 //==============================================================================
289 //HttpXmlDocument::getAllMatchingValues
290 // returns all of the values found for the field in a vector
291 // if none found vector will have size 0
292 void HttpXmlDocument::getAllMatchingValues (const std::string &field, std::vector<std::string> &retVec)
293 {
294  recursiveFindAllElements(theDocument_->getDocumentElement(),field,&retVec);
295 }
296 
297 //==============================================================================
298 //HttpXmlDocument::recursiveFindElement
299 // recursively searches and returns the value for field found occurance number of times
300 void HttpXmlDocument::recursiveFindAllElements (xercesc::DOMElement *currEl, const std::string &field,std::vector<std::string> *retVec)
301 {
302  if (XML_TO_CHAR(currEl->getNodeName()) == field &&
303  currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, return as value attribute
304  retVec->push_back(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
305 
306 
307  //look through children recursively
308  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
309  for(unsigned int i = 0; i<nodeList->getLength();++i)
310  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) //ignore text node children
311  recursiveFindAllElements ((xercesc::DOMElement*)(nodeList->item(i)),field,retVec);
312 }
313 
314 //==============================================================================
315 //HttpXmlDocument::getMatchingElement
316 // returns the element for field found occurance number of times
317 // returns null if field was not found
318 xercesc::DOMElement* HttpXmlDocument::getMatchingElement (const std::string &field, const unsigned int occurance)
319 {
320  return getMatchingElementInSubtree(theDocument_->getDocumentElement(),field,occurance);
321 }
322 
323 //==============================================================================
324 //HttpXmlDocument::getMatchingElementInSubtree
325 // returns the element for field found occurance number of times within the subtree
326 // specified by parentEl
327 // returns null if field was not found
328 xercesc::DOMElement* HttpXmlDocument::getMatchingElementInSubtree (xercesc::DOMElement *parentEl, const std::string &field,
329  const unsigned int occurance)
330 {
331  unsigned int count = 0;
332  return recursiveFindElement(parentEl,field,occurance,count);
333 }
334 
335 //==============================================================================
336 //HttpXmlDocument::recursiveFindElement
337 // recursively searches and returns the element for field found occurance number of times
338 xercesc::DOMElement* HttpXmlDocument::recursiveFindElement (xercesc::DOMElement *currEl, const std::string &field,
339  const unsigned int occurance, unsigned int &count)
340 {
341  if (XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++) //found, done!!
342  {
343  if( currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, return as value attribute
344  return currEl;
345  else
346  return 0; //empty value attribute
347  }
348 
349  xercesc::DOMElement* retEl;
350  //look through children recursively
351  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
352  for(unsigned int i = 0; i<nodeList->getLength();++i)
353  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) //ignore text node children
354  {
355  retEl = recursiveFindElement ((xercesc::DOMElement*)(nodeList->item(i)),field,occurance,count);
356  if(retEl) return retEl; //found among children already, done
357  //else continue search within children recursively
358  }
359  return 0; //nothing found
360 }
361 
362 //==============================================================================
363 //HttpXmlDocument::recursiveAddElementToParent
364 // add currEl and its children tree to parentEl
365 // note: attributes are not considered here
366 void HttpXmlDocument::recursiveAddElementToParent(xercesc::DOMElement* child, xercesc::DOMElement* parent, bool html)
367 {
368  std::string childText = "";
369 
370  std::string childName = XML_TO_CHAR(child->getNodeName());//XML_TO_CHAR(currEl->getNodeName());
371 
372  if( child->getFirstChild() != NULL && child->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, insert as value attribute
373  {
374  childText = XML_TO_CHAR(child->getFirstChild()->getNodeValue());
375  if(html)
376  childText = escapeString(childText);
377  }
378  //std::cout << __COUT_HDR_FL__<< "childName " << childName << " childText " << childText << std::endl;
379 
380  //insert child
381  xercesc::DOMElement* newParent = addTextElementToParent(childName, childText, parent);
382 
383  //insert rest of child tree
384  xercesc::DOMNodeList *nodeList = child->getChildNodes(); //get all children of child
385  for(unsigned int i = 0; i<nodeList->getLength();++i)
386  {
387  if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE) //ignore text node children
388  continue;
389 
390  recursiveAddElementToParent((xercesc::DOMElement*)(nodeList->item(i)), newParent, html);
391  }
392 }
393 
394 //==============================================================================
395 //HttpXmlDocument::getAllMatchingElements
396 // returns all of the values found for the field in a vector
397 // if none found vector will have size 0
398 void HttpXmlDocument::getAllMatchingElements (const std::string &field, std::vector<xercesc::DOMElement*> &retVec)
399 {
400  recursiveFindAllElements(theDocument_->getDocumentElement(),field,&retVec);
401 }
402 
403 
404 //==============================================================================
405 //HttpXmlDocument::recursiveFindElement
406 // recursively searches and returns the value for field found occurance number of times
407 void HttpXmlDocument::recursiveFindAllElements (xercesc::DOMElement *currEl, const std::string &field,std::vector<xercesc::DOMElement*> *retVec)
408 {
409  if (XML_TO_CHAR(currEl->getNodeName()) == field &&
410  currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) //if has a text node first, return as value attribute
411  retVec->push_back(currEl);
412 
413 
414  //look through children recursively
415  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
416  for(unsigned int i = 0; i<nodeList->getLength();++i)
417  if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE) //ignore text node children
418  recursiveFindAllElements ((xercesc::DOMElement*)(nodeList->item(i)),field,retVec);
419 }
420 //==============================================================================
421 //HttpXmlDocument::escapeString
422 // convert quotes to html quote characters &apos = ' and &quot = "
423 // remove new line characters
424 // and remove white space (so that read from file white space artifact removed)
425 /*
426 std::string HttpXmlDocument::escapeString(string inString)
427 {
428  unsigned int ws = -1;
429  for(unsigned int i=0;i<inString.length();++i)
430  if(inString[i] != ' ')
431  {
432  if(inString[i] == '\r' || inString[i] == '\n') //remove new line chars
433  {
434  inString.erase(i,1); // replace special character with ;
435  --i; //step back so next char to check is correct
436  continue;
437  }
438 
439  ws = i; //last non white space char
440  if(inString[i] == '\"' || inString[i] == '\'')
441  {
442  inString.insert(i,(inString[i] == '\'')?"&apos":"&quot"); //insert \ before quotes
443  inString.replace(i+5,1,1,';'); // replace special character with ;
444  i+=5; //skip to next char to check
445  }
446  }
447 
448  if(ws == (unsigned int)-1) return ""; //empty std::string since all white space
449  return inString.substr(0,ws+1); //trim right white space
450 }
451 */
452 //==============================================================================
453 //loadXmlDocument
454 // returns false if xml doc could not be opened
455 bool HttpXmlDocument::loadXmlDocument (const std::string &filePath)
456 {
457  //std::cout << __COUT_HDR_FL__<< "Loading theDocument_ from file: " << filePath << std::endl;
458 
459  struct stat fileStatus;
460 
461  if(stat(filePath.c_str(), &fileStatus) != 0)
462  {
463  std::cout << __COUT_HDR_FL__<< "File not accessible." << std::endl;
464  return false;
465  }
466 
467  //reset xml platform and theDocument_
468  terminatePlatform();
469  initPlatform();
470 
471  xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser;
472  // Configure xercesc::DOM parser.
473  parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
474  parser->setDoNamespaces ( true );
475  parser->setDoSchema ( true );
476  parser->useCachedGrammarInParse ( false );
477 
478  try
479  {
480  parser->parse( filePath.c_str() );
481 
482  //theDocument_ memory object owned by the parent parser object
483  theDocument_ = parser->adoptDocument();//instead of getDocument() so parser will not free theDocument_ when released
484 
485  // Get the top-level element: Name is "root". No attributes for "root"
486  rootElement_ = theDocument_->getDocumentElement();
487  if( !rootElement_ )
488  throw(std::runtime_error( "empty XML theDocument_" ));
489 
490  recursiveFixTextFields(rootElement_); //remove space and new lines from value attribute
491 
492  xercesc::DOMNodeList *nodeList = theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_));
493  if(nodeList->getLength()) //may not always be header element
494  headerElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_))->item(0));
495  else
496  headerElement_ = 0;
497 
498  dataElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(dataTagName_))->item(0)); //always is data
499  }
500  catch( xercesc::XMLException& e )
501  {
502  std::cout << __COUT_HDR_FL__<< "Error parsing file." << std::endl;
503  return false;
504  }
505  delete parser;
506 
507  return true;
508 }
509 
510 //==============================================================================
511 //HttpXmlDocument::recursiveFixTextFields
512 // recursively printout XML theDocument_ to std out and output stream if not null
513 void HttpXmlDocument::recursiveFixTextFields(xercesc::DOMElement *currEl)
514 {
515  xercesc::DOMNodeList *nodeList = currEl->getChildNodes(); //get all children
516 
517  //recurse through children
518  for(unsigned int i = 0; i<nodeList->getLength();++i)
519  if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE) //fix text nodes
520  ((xercesc::DOMElement*)(nodeList->item(i)))->setTextContent(CONVERT_TO_XML( //change text value to escaped version
521  escapeString(XML_TO_CHAR(((xercesc::DOMElement*)(nodeList->item(i)))->getNodeValue()))));
522  else
523  recursiveFixTextFields ((xercesc::DOMElement*)(nodeList->item(i)));
524 }
525 
526 //==============================================================================
527 //HttpXmlDocument::addDataElement
528 // Add field/value element to XML doc at parentIndexArray (with depth of parent indicated by parentIndexArraySize)
529 // If parentIndexArray = NULL, element is added with <DATA> parent
530 // otherwise, parentIndexArray indicates the parent within the node list for <DATA> where
531 // the element will be added
532 // On Success, The child index of the added element with respect to the parent is returned and can be used to add
533 // children to the new element
534 // On Failure, return -1
535 /*
536 xercesc::DOMElement* HttpXmlDocument::addDataElement ( std::string field, std::string value, unsigned int *parentIndexArray, unsigned int parentIndexArraySize)
537 {
538 
539  //std::cout << __COUT_HDR_FL__ << "field: " << field << ", value: " << value << ", parent: " << parentIndexArraySize << std::endl;
540 
541  xercesc::DOMElement* parentEl = dataElement_; // initialize parent to <DATA>
542 
543  if(parentIndexArray) //if there passed an array find parent relative to data element
544  {
545  //std::cout << __COUT_HDR_FL__<< "Using Parent Index Array" << std::endl;
546 
547  xercesc::DOMNodeList *nodeList;
548 
549  //iterate through nested parents based on parentIndexArray
550  unsigned int tmpi,cntNotTxt;
551  for(unsigned int i=0;i<parentIndexArraySize;++i)
552  {
553  nodeList = parentEl->getChildNodes(); //get all children
554  cntNotTxt = 0;
555 
556  //get cntNotTxt to proper non text node
557  for(tmpi=0;tmpi<nodeList->getLength();++tmpi)
558  {
559  if(((xercesc::DOMElement*)(nodeList->item(tmpi)))->getNodeType() == xercesc::DOMNode::TEXT_NODE) continue; //skip text nodes
560 
561  if(cntNotTxt == parentIndexArray[i]) break; //at proper parent node!
562  ++cntNotTxt; //else look for next
563  }
564 
565  //in theory, only first child can be text - ignore text node children
566  //if(parentEl->getFirstChild() != NULL && parentEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE) ++tmpi;
567 
568  if(tmpi >= nodeList->getLength())
569  {
570  std::cout << __COUT_HDR_FL__ << "illegal child index attempted in nested parents: " << parentIndexArray[i] << ", depth: " << i << ", tmpi: " << tmpi << std::endl;
571  return 0; //illegal child index attempted in nested parents
572  }
573 
574  parentEl = (xercesc::DOMElement*)(nodeList->item(tmpi));
575  }
576  }
577 
578  return addTextElementToParent(field,value,parentEl);
579 }
580 */
581