otsdaq  3.03.00
XmlDocument.cc
1 #include "otsdaq/XmlUtilities/XmlDocument.h"
2 #include "otsdaq/Macros/CoutMacros.h"
3 #include "otsdaq/Macros/MessageTools.h"
4 #include "otsdaq/Macros/StringMacros.h"
5 #include "otsdaq/MessageFacility/MessageFacility.h"
6 #include "otsdaq/XmlUtilities/ConvertFromXML.h"
7 #include "otsdaq/XmlUtilities/ConvertToXML.h"
8 
9 #include <stdexcept>
10 #include <xercesc/dom/DOM.hpp>
11 #include <xercesc/dom/DOMDocument.hpp>
12 #include <xercesc/dom/DOMDocumentType.hpp>
13 #include <xercesc/dom/DOMElement.hpp>
14 #include <xercesc/dom/DOMImplementation.hpp>
15 #include <xercesc/dom/DOMImplementationLS.hpp>
16 #include <xercesc/dom/DOMImplementationRegistry.hpp>
17 #include <xercesc/parsers/XercesDOMParser.hpp>
18 // #include <xercesc/dom/DOMLSSerializer.hpp>
19 // #include <xercesc/dom/DOMLSOutput.hpp>
20 #include <xercesc/dom/DOMNodeIterator.hpp>
21 #include <xercesc/dom/DOMNodeList.hpp>
22 #include <xercesc/dom/DOMText.hpp>
23 #include <xercesc/validators/common/Grammar.hpp>
24 
25 #include <xercesc/parsers/XercesDOMParser.hpp>
26 #include <xercesc/util/XMLUni.hpp>
27 #include <xercesc/util/XercesDefs.hpp>
28 
29 #include <xercesc/framework/LocalFileFormatTarget.hpp>
30 #include <xercesc/util/OutOfMemoryException.hpp>
31 
32 #include <boost/regex.hpp>
33 
34 #include <iostream>
35 #include <list>
36 #include <sstream>
37 
38 #include <errno.h>
39 #include <sys/stat.h>
40 #include <sys/types.h>
41 #include <unistd.h>
42 
43 using namespace ots;
44 
45 //==============================================================================
46 XmlDocument::XmlDocument(const std::string& rootName) : rootTagName_(rootName)
47 {
48  __COUTS__(50) << "in" << std::endl;
49  initDocument();
50 
51  rootElement_ = theDocument_->getDocumentElement();
52  __COUTS__(50) << "out" << std::endl;
53 } //end constructor()
54 
55 //==============================================================================
56 XmlDocument::XmlDocument(const XmlDocument& doc) : rootTagName_(doc.rootTagName_)
57 {
58  __COUTS__(50) << "in" << std::endl;
59  *this = doc;
60  __COUTS__(50) << "out" << std::endl;
61 } //end constructor()
62 
63 //==============================================================================
64 XmlDocument& XmlDocument::operator=(const XmlDocument& doc)
65 {
66  __COUTS__(50) << "in" << std::endl;
67  initDocument();
68  rootElement_ = theDocument_->getDocumentElement();
69  recursiveElementCopy(doc.rootElement_, rootElement_);
70  __COUTS__(50) << "out" << std::endl;
71  return *this;
72 } //end assignment operator
73 
74 //==============================================================================
75 XmlDocument::~XmlDocument(void)
76 {
77  __COUTS__(50) << "Xml Destructor" << std::endl;
78  terminatePlatform();
79 } //end destructor()
80 
81 //==============================================================================
82 void XmlDocument::initDocument(void)
83 {
84  initPlatform();
85 
86  theImplementation_ =
87  xercesc::DOMImplementationRegistry::getDOMImplementation(CONVERT_TO_XML("Core"));
88 
89  if(theImplementation_)
90  {
91  try
92  {
93  theDocument_ = theImplementation_->createDocument(
94  CONVERT_TO_XML("http://www.w3.org/2001/XMLSchema-instance"), // root
95  // element
96  // namespace
97  // URI.
98  CONVERT_TO_XML(rootTagName_), // root element name
99  0); // theDocument_ type object (DTD).
100  }
101  catch(const xercesc::OutOfMemoryException&)
102  {
103  __SS__ << "OutOfMemoryException" << __E__;
104  __SS_THROW__;
105  }
106  catch(const xercesc::DOMException& e)
107  {
108  __SS__ << "DOMException code is: " << e.code << __E__;
109  __SS_THROW__;
110  }
111  catch(const xercesc::XMLException& e)
112  {
113  __SS__ << "Error Message: " << XML_TO_CHAR(e.getMessage()) << __E__;
114  __SS_THROW__;
115  }
116  catch(...)
117  {
118  __SS__ << "An error occurred creating the theDocument_" << __E__;
119  try
120  {
121  throw;
122  } //one more try to printout extra info
123  catch(const std::exception& e)
124  {
125  ss << "Exception message: " << e.what();
126  }
127  catch(...)
128  {
129  }
130  __SS_THROW__;
131  }
132  }
133  else
134  {
135  __SS__ << "Requested theImplementation_ is not supported" << __E__;
136  __SS_THROW__;
137  }
138  darioXMLStyle_ = false;
139  isALeaf_[true] = "true";
140  isALeaf_[false] = "false";
141 } //end initDocument()
142 
143 //==============================================================================
144 void XmlDocument::initPlatform(void)
145 {
146  try
147  {
148  xercesc::XMLPlatformUtils::Initialize(); // Initialize Xerces infrastructure
149  //__COUT__ << "Initialized new
150  // theDocument_" << std::endl;
151  }
152  catch(xercesc::XMLException& e)
153  {
154  __COUT__ << "XML toolkit initialization error: " << XML_TO_CHAR(e.getMessage())
155  << std::endl;
156  }
157 } //end initPlatform()
158 
159 //==============================================================================
160 void XmlDocument::terminatePlatform(void)
161 {
162  try
163  {
164  __COUTS__(50) << "Releasing the document" << std::endl;
165  theDocument_->release();
166  __COUTS__(50) << "document released" << std::endl;
167  }
168  catch(...)
169  {
170  XERCES_STD_QUALIFIER cerr << "An error occurred destroying the theDocument_"
171  << XERCES_STD_QUALIFIER endl;
172  }
173 
174  try
175  {
176  xercesc::XMLPlatformUtils::Terminate(); // Terminate after release of memory
177  }
178  catch(xercesc::XMLException& e)
179  {
180  __COUT__ << "XML toolkit teardown error: " << XML_TO_CHAR(e.getMessage())
181  << std::endl;
182  // XMLString::release(&message);
183  }
184 } //end terminatePlatform()
185 
186 xercesc::DOMElement* XmlDocument::createChildElement(const std::string& childClass,
187  xercesc::DOMElement* parent)
188 {
189  if(parent == nullptr)
190  {
191  __SS__ << "Illegal Null Parent Pointer!" << __E__;
192  __SS_THROW__;
193  }
194  xercesc::DOMElement* child = nullptr;
195  try
196  {
197  child = theDocument_->createElement(CONVERT_TO_XML(childClass));
198  }
199  catch(xercesc::DOMException& e)
200  {
201  __COUT__ << "Can't use the class: " << childClass
202  << " to create the child element because the exception says: "
203  << XML_TO_CHAR(e.getMessage())
204  << ". Very likely you have a name that starts with a number and that's "
205  "not allowed!"
206  << std::endl;
207  }
208  parent->appendChild(child);
209 
210  return child;
211 }
212 
213 xercesc::DOMElement* XmlDocument::addAttributeToNode(const std::string& attributeName,
214  const std::string& attributeValue,
215  xercesc::DOMElement* node)
216 {
217  if(node == nullptr)
218  {
219  __SS__ << "Illegal Null Parent Pointer!" << __E__;
220  __SS_THROW__;
221  }
222 
223  try
224  {
225  node->setAttribute(CONVERT_TO_XML(attributeName), CONVERT_TO_XML(attributeValue));
226  }
227  catch(xercesc::DOMException& e)
228  {
229  __COUT__ << "Can't use the name: " << attributeName
230  << " to create the attribute because the exception says: "
231  << XML_TO_CHAR(e.getMessage())
232  << ". Very likely you have a name that starts with a number and that's "
233  "not allowed!"
234  << std::endl;
235  }
236 
237  return node;
238 }
239 
240 //==============================================================================
244 xercesc::DOMElement* XmlDocument::addTextElementToParent(const std::string& childName,
245  const std::string& childText,
246  xercesc::DOMElement* parent)
247 {
248  if(parent == nullptr)
249  {
250  __SS__ << "Illegal Null Parent Pointer!" << __E__;
251  __SS_THROW__;
252  }
253  xercesc::DOMElement* child = nullptr;
254  try
255  {
256  child = theDocument_->createElement(CONVERT_TO_XML(childName));
257  }
258  catch(xercesc::DOMException& e)
259  {
260  __COUT__ << "Can't use the name: " << childName
261  << " to create the child element because the exception says: "
262  << XML_TO_CHAR(e.getMessage())
263  << ". Very likely you have a name that starts with a number and that's "
264  "not allowed!"
265  << std::endl;
266  }
267  parent->appendChild(child);
268 
269  try
270  {
271  child->appendChild(theDocument_->createTextNode(CONVERT_TO_XML(childText)));
272  }
273  catch(...) // sometimes see TranscodingException
274  {
275  __COUT__ << StringMacros::stackTrace() << std::endl;
276  __COUT_ERR__ << "Error caught attempting to create a text node for this text: "
277  << childText << ". Converting instead to 'Illegal text..'"
278  << std::endl;
279  child->appendChild(theDocument_->createTextNode(
280  CONVERT_TO_XML("Illegal text content blocked.")));
281  }
282 
283  return child;
284 } //end addTextElementToParent()
285 
286 //==============================================================================
290 xercesc::DOMElement* XmlDocument::addTextElementToParent(const std::string& childName,
291  const std::string& childText,
292  const std::string& parentName,
293  unsigned int parentIndex)
294 {
295  xercesc::DOMNodeList* nodeList =
296  theDocument_->getElementsByTagName(CONVERT_TO_XML(parentName));
297 
298  if(parentIndex >= nodeList->getLength())
299  {
300  __COUT__ << "WARNING: Illegal parent index attempted in tags with name: "
301  << parentName << ", index: " << parentIndex << std::endl;
302  return 0; // illegal index attempted
303  }
304 
305  return addTextElementToParent(
306  childName, childText, (xercesc::DOMElement*)(nodeList->item(parentIndex)));
307 } //end addTextElementToParent()
308 
309 //==============================================================================
310 void XmlDocument::copyDocument(const xercesc::DOMDocument* toCopy,
311  xercesc::DOMDocument* copy)
312 {
313  recursiveElementCopy(toCopy->getDocumentElement(), copy->getDocumentElement());
314 } //end copyDocument()
315 
316 //==============================================================================
317 void XmlDocument::recursiveElementCopy(const xercesc::DOMElement* toCopy,
318  xercesc::DOMElement* copy)
319 {
320  xercesc::DOMNodeList* nodeListToCopy =
321  toCopy->getChildNodes(); // get all children of the list to copy
322  xercesc::DOMNode* iNode;
323  xercesc::DOMDocument* copyDocument = copy->getOwnerDocument();
324  for(unsigned int i = 0; i < nodeListToCopy->getLength(); i++)
325  {
326  iNode = nodeListToCopy->item(i);
327  xercesc::DOMElement* child = copyDocument->createElement(iNode->getNodeName());
328  copy->appendChild(child);
329  if(child->getFirstChild() != NULL)
330  {
331  if(iNode->getFirstChild() != 0 &&
332  iNode->getFirstChild()->getNodeType() ==
333  xercesc::DOMNode::TEXT_NODE) // if has a text node first, insert as
334  // value attribute
335  {
336  child->appendChild(
337  copyDocument->createTextNode(child->getFirstChild()->getNodeValue()));
338  }
339  recursiveElementCopy((xercesc::DOMElement*)(iNode), child);
340  }
341  }
342 } //end recursiveElementCopy()
343 
344 //==============================================================================
348 void XmlDocument::outputXmlDocument(std::ostringstream* out, bool dispStdOut)
349 {
350  recursiveOutputXmlDocument(theDocument_->getDocumentElement(), out, dispStdOut);
351 } //end outputXmlDocument()
352 
353 //==============================================================================
354 void XmlDocument::setDocument(xercesc::DOMDocument* doc) { theDocument_ = doc; }
355 //==============================================================================
358 void XmlDocument::recursiveOutputXmlDocument(xercesc::DOMElement* currEl,
359  std::ostringstream* out,
360  bool dispStdOut,
361  const std::string& tabStr)
362 {
363  // open field tag
364  if(dispStdOut)
365  {
366  __COUT__ << tabStr << "<" << XML_TO_CHAR(currEl->getNodeName());
367  }
368  if(out)
369  {
370  *out << tabStr << "<" << XML_TO_CHAR(currEl->getNodeName());
371  }
372 
373  // insert value if text node child
374  if(currEl->getFirstChild() != NULL &&
375  currEl->getFirstChild()->getNodeType() ==
376  xercesc::DOMNode::TEXT_NODE) // if has a text node first, insert as value
377  // attribute
378  {
379  if(dispStdOut)
380  std::cout << " value='"
382  XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()), true)
383  << "'";
384  if(out)
385  *out << " value='"
387  XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()), true)
388  << "'";
389  }
390 
391  xercesc::DOMNamedNodeMap* attrList = currEl->getAttributes();
392  if(attrList)
393  {
394  for(XMLSize_t ii = 0; ii < attrList->getLength(); ++ii)
395  {
396  if(dispStdOut)
397  std::cout << " " << XML_TO_CHAR(attrList->item(ii)->getNodeName()) << "='"
399  XML_TO_CHAR(attrList->item(ii)->getNodeValue()), true)
400  << "'";
401  if(out)
402  *out << " " << XML_TO_CHAR(attrList->item(ii)->getNodeName()) << "='"
404  XML_TO_CHAR(attrList->item(ii)->getNodeValue()), true)
405  << "'";
406  }
407  }
408 
409  xercesc::DOMNodeList* nodeList = currEl->getChildNodes(); // get all children
410 
411  // close opening field tag
412  if(dispStdOut)
413  std::cout << ((nodeList->getLength() == 0 ||
414  (nodeList->getLength() == 1 &&
415  currEl->getFirstChild()->getNodeType() ==
416  xercesc::DOMNode::TEXT_NODE))
417  ? "/"
418  : "")
419  << ">" << std::endl;
420  if(out)
421  *out << ((nodeList->getLength() == 0 ||
422  (nodeList->getLength() == 1 &&
423  currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE))
424  ? "/"
425  : "")
426  << ">" << std::endl;
427 
428  // insert children
429  std::string newTabStr = tabStr + "\t";
430  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
431  if(nodeList->item(i)->getNodeType() !=
432  xercesc::DOMNode::TEXT_NODE) // ignore text node children
434  (xercesc::DOMElement*)(nodeList->item(i)), out, dispStdOut, newTabStr);
435 
436  // close tag if children
437  if(nodeList->getLength() > 1 ||
438  (nodeList->getLength() == 1 &&
439  currEl->getFirstChild()->getNodeType() != xercesc::DOMNode::TEXT_NODE))
440  {
441  if(dispStdOut)
442  __COUT__ << tabStr << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">"
443  << std::endl;
444  if(out)
445  *out << tabStr << "</" << XML_TO_CHAR(currEl->getNodeName()) << ">"
446  << std::endl;
447  }
448 } //end recursiveOutputXmlDocument()
449 
450 //==============================================================================
453 void XmlDocument::recursiveRemoveChild(xercesc::DOMElement* childEl,
454  xercesc::DOMElement* parentEl)
455 {
456  // release child's children first
457  xercesc::DOMNodeList* nodeList =
458  childEl->getChildNodes(); // get all children within data
459  for(unsigned int i = 0; i < nodeList->getLength(); ++i)
461  (xercesc::DOMElement*)(nodeList->item(nodeList->getLength() - 1 - i)),
462  childEl);
463 
464  // then release child
465  parentEl->removeChild(childEl);
466  childEl->release();
467 } //end recursiveRemoveChild()
468 
469 //==============================================================================
473 void XmlDocument::saveXmlDocument(const std::string& filePath)
474 {
475  __COUT__ << "Saving theDocument_ to file: " << filePath << std::endl;
476  // Return the first registered theImplementation_ that has the desired features. In
477  // this case, we are after a DOM theImplementation_ that has the LS feature... or
478  // Load/Save. DOMImplementation *theImplementation_ =
479  // DOMImplementationRegistry::getDOMImplementation(L"LS");
480  xercesc::DOMImplementation* saveImplementation =
481  xercesc::DOMImplementationRegistry::getDOMImplementation(CONVERT_TO_XML("LS"));
482 
483  __COUTT__ << "XERCES Version: " << _XERCES_VERSION << std::endl;
484 
485 #if _XERCES_VERSION >= 30000
486 
487  //__COUT__ << "making file" << filePath << std::endl;
488  // Create a DOMLSSerializer which is used to serialize a DOM tree into an XML
489  // theDocument_.
490  xercesc::DOMLSSerializer* serializer =
491  ((xercesc::DOMImplementationLS*)saveImplementation)->createLSSerializer();
492 
493  // Make the output more human readable by inserting line feeds.
494  if(serializer->getDomConfig()->canSetParameter(
495  xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true))
496  serializer->getDomConfig()->setParameter(
497  xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true);
498 
499  // The end-of-line sequence of characters to be used in the XML being written out.
500  serializer->setNewLine(CONVERT_TO_XML("\r\n"));
501 
502  // Convert the path into Xerces compatible XMLCh*.
503  // XMLCh *tempFilePath = const_cast<XMLCh*>(CONVERT_TO_XML(filePath));
504 
505  // Specify the target for the XML output.
506  xercesc::XMLFormatTarget* formatTarget;
507  try
508  {
509  // formatTarget = new xercesc::LocalFileFormatTarget(tempFilePath);
510  formatTarget = new xercesc::LocalFileFormatTarget(filePath.c_str());
511  }
512  catch(...)
513  {
514  __COUT__ << "Inaccessible file path: " << filePath << std::endl;
515  serializer->release();
516  // xercesc::XMLString::release(&tempFilePath);
517 
518  return;
519  }
520 
521  // Create a new empty output destination object.
522  xercesc::DOMLSOutput* output =
523  ((xercesc::DOMImplementationLS*)saveImplementation)->createLSOutput();
524 
525  // Set the stream to our target.
526  output->setByteStream(formatTarget);
527  // Write the serialized output to the destination.
528  serializer->write(theDocument_, output);
529  serializer->release();
530  // xercesc::XMLString::release(&tempFilePath);
531  delete formatTarget;
532 #else
533 
534  xercesc::DOMWriter* serializer =
535  ((xercesc::DOMImplementationLS*)saveImplementation)->createDOMWriter();
536  serializer->setFeature(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true);
537 
538  /*
539  Choose a location for the serialized output. The 3 options are:
540  1) StdOutFormatTarget (std output stream - good for debugging)
541  2) MemBufFormatTarget (to Memory)
542  3) LocalFileFormatTarget (save to file)
543  (Note: You'll need a different header file for each one)
544  */
545  // XMLFormatTarget* pTarget = new StdOutFormatTarget();
546  // Convert the path into Xerces compatible XMLCh*.
547  XMLCh* tempFilePath = xercesc::XMLString::transcode(filePath.c_str());
548  xercesc::XMLFormatTarget* formatTarget;
549  try
550  {
551  formatTarget = new xercesc::LocalFileFormatTarget(tempFilePath);
552  }
553  catch(...)
554  {
555  __COUT__ << "Inaccessible file path: " << filePath << std::endl;
556  serializer->release();
557  xercesc::XMLString::release(&tempFilePath);
558  return;
559  }
560 
561  // Write the serialized output to the target.
562 
563  serializer->writeNode(formatTarget, *theDocument_);
564  serializer->release();
565  xercesc::XMLString::release(&tempFilePath);
566  delete formatTarget;
567 #endif
568 
569  // Cleanup.
570  __COUTS__(50) << "delete format target" << std::endl;
571 
572 #if _XERCES_VERSION >= 30000
573 
574  __COUTS__(50) << "delete output0" << std::endl;
575  output->release();
576  __COUTS__(50) << "delete output1" << std::endl;
577 
578 #endif
579 } //end saveXmlDocument()
580 
581 //==============================================================================
582 bool XmlDocument::loadXmlDocument(const std::string& filePath)
583 {
584  __COUT__ << "Loading theDocument_ from file: " << filePath << std::endl;
585 
586  struct stat fileStatus;
587 
588  if(stat(filePath.c_str(), &fileStatus) != 0)
589  {
590  __COUT__ << "File not accessible." << std::endl;
591  return false;
592  }
593 
594  terminatePlatform();
595  initPlatform();
596 
597  xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser;
598  parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
599  parser->setDoNamespaces(true);
600  parser->setDoSchema(true);
601  parser->useCachedGrammarInParse(false);
602 
603  try
604  {
605  parser->parse(filePath.c_str());
606 
607  // theDocument_ memory object owned by the parent parser object
608  theDocument_ = parser->adoptDocument(); // instead of getDocument() so parser
609  // will not free theDocument_ when
610  // released
611 
612  // Get the top-level element: Name is "root". No attributes for "root"
613  rootElement_ = theDocument_->getDocumentElement();
614  if(!rootElement_)
615  throw(std::runtime_error("empty XML theDocument_"));
616  }
617  catch(xercesc::XMLException& e)
618  {
619  __COUT__ << "Error parsing file." << std::endl;
620  return false;
621  }
622  delete parser;
623 
624  return true;
625 } //end loadXmlDocument()
626 
627 //============================================================================
628 void XmlDocument::setAnchors(const std::string& fSystemPath, const std::string& fRootPath)
629 {
630  fSystemPath_ = fSystemPath;
631  fRootPath_ = fRootPath;
632 } //end setAnchors()
633 
634 //============================================================================
635 void XmlDocument::makeDirectoryBinaryTree(const std::string& fSystemPath,
636  const std::string& fRootPath,
637  int indent,
638  xercesc::DOMElement* anchorNode)
639 {
640  DIR* dir;
641  struct dirent* entry;
642 
643  std::string newFullPath = "";
644  char fchar = '.';
645  char schar = '.';
646 
647  fSystemPath_ = fSystemPath;
648  fRootPath_ = fRootPath;
649 
650  std::string fullPathName =
651  fSystemPath_ + std::string("/") + fRootPath_ + std::string("/") + fFoldersPath_;
652 
653  if(!anchorNode)
654  anchorNode = rootElement_;
655 
656  if(!(dir = opendir(fullPathName.c_str())))
657  return;
658 
659  while((entry = readdir(dir)) != NULL)
660  {
661  std::string sName = std::string(entry->d_name);
662  fchar = sName.at(0);
663  if(sName.size() == 2)
664  schar = sName.at(1);
665  if(((sName.size() == 1) && fchar == '.') || ((sName.size() == 2) && schar == '.'))
666  {
667  continue; // do not consider . and .. pseudo-folders
668  }
669 
670  if(entry->d_type == DT_DIR)
671  {
672  fThisFolderPath_ = std::string(entry->d_name);
673  newFullPath = fSystemPath_ + fRootPath + std::string("/") + fThisFolderPath_;
674  hierarchyPaths_.push_back(std::string(entry->d_name) + std::string(""));
675  fFoldersPath_ += hierarchyPaths_.back() + "/";
676  xercesc::DOMElement* node = this->populateBinaryTreeNode(
677  anchorNode, std::string(entry->d_name), indent, false);
678  this->makeDirectoryBinaryTree(fSystemPath, fRootPath, indent + 1, node);
679  if(hierarchyPaths_.size() > 0)
680  hierarchyPaths_.pop_back();
681  if(hierarchyPaths_.size() > 0)
682  {
683  fFoldersPath_ = hierarchyPaths_.back() + "/";
684  }
685  else
686  {
687  fFoldersPath_ = "/";
688  }
689  }
690  else
691  {
692  newFullPath = fSystemPath_ + std::string("/") + std::string(entry->d_name);
693  boost::smatch what;
694  boost::regex re{".*\\.root$"};
695  if(boost::regex_search(newFullPath, what, re))
696  {
697  fFileName_ = std::string(entry->d_name);
698  fFoldersPath_ = "";
699  for(unsigned int i = 0; i < hierarchyPaths_.size(); ++i)
700  {
701  fFoldersPath_ += hierarchyPaths_[i] + std::string("/");
702  }
703  this->populateBinaryTreeNode(anchorNode, fFileName_, indent, true);
704  }
705  }
706  }
707  closedir(dir);
708 } //end makeDirectoryBinaryTree()
709 
710 //==========================================================================================
711 xercesc::DOMElement* XmlDocument::populateBinaryTreeNode(xercesc::DOMElement* anchorNode,
712  const std::string& name,
713  int indent,
714  bool isLeaf)
715 {
716  std::string nm = "unassigned";
717  xercesc::DOMElement* nodes = NULL;
718 
719  // if( isLeaf )
720  // {
721  // STDLINE("","") ;
722  // if( theNodes_.find(indent) != theNodes_.end() ) nodes = theNodes_.find(indent)->second ;
723  // if( theNames_.find(indent) != theNames_.end() ) nm = theNames_.find(indent)->second ;
724  // ss_.str("") ; ss_ << "Attaching " << name << " to " << nm << " size: " << theNames_.size();
725  // STDLINE(ss_.str(),ACGreen) ;
726  // }
727  // else
728  // {
729  if(theNodes_.find(indent) != theNodes_.end()) // a new node
730  {
731  if(theNodes_.find(indent) != theNodes_.end())
732  nodes = theNodes_.find(indent)->second;
733  if(theNames_.find(indent) != theNames_.end())
734  nm = theNames_.find(indent)->second;
735  }
736  else
737  {
738  nodes = theDocument_->createElement(xercesc::XMLString::transcode("nodes"));
739  theNodes_[indent] = nodes;
740  theNames_[indent] = name;
741  anchorNode->appendChild(nodes);
742  }
743  // }
744  xercesc::DOMElement* node =
745  theDocument_->createElement(xercesc::XMLString::transcode("node"));
746  nodes->appendChild(node);
747 
748  xercesc::DOMElement* nChilds =
749  theDocument_->createElement(xercesc::XMLString::transcode("nChilds"));
750  node->appendChild(nChilds);
751 
752  xercesc::DOMText* nChildsVal =
753  theDocument_->createTextNode(xercesc::XMLString::transcode("x"));
754  nChilds->appendChild(nChildsVal);
755 
756  xercesc::DOMElement* fSystemPathNode =
757  theDocument_->createElement(xercesc::XMLString::transcode("fSystemPath"));
758  node->appendChild(fSystemPathNode);
759 
760  xercesc::DOMText* fSystemPathVal =
761  theDocument_->createTextNode(xercesc::XMLString::transcode(fSystemPath_.c_str()));
762  fSystemPathNode->appendChild(fSystemPathVal);
763 
764  xercesc::DOMElement* fRootPathNode =
765  theDocument_->createElement(xercesc::XMLString::transcode("fRootPath"));
766  node->appendChild(fRootPathNode);
767 
768  xercesc::DOMText* fRootPathVal =
769  theDocument_->createTextNode(xercesc::XMLString::transcode(fRootPath_.c_str()));
770  fRootPathNode->appendChild(fRootPathVal);
771 
772  xercesc::DOMElement* fFoldersPathNode =
773  theDocument_->createElement(xercesc::XMLString::transcode("fFoldersPath"));
774  node->appendChild(fFoldersPathNode);
775 
776  xercesc::DOMText* foldersPathVal = theDocument_->createTextNode(
777  xercesc::XMLString::transcode(fFoldersPath_.c_str()));
778  fFoldersPathNode->appendChild(foldersPathVal);
779 
780  xercesc::DOMElement* fThisFolderPath = NULL;
781  xercesc::DOMElement* fFileOrHistName = NULL;
782  xercesc::DOMText* fileOrDirNameVal = NULL;
783  xercesc::DOMText* thisFolderNameVal = NULL;
784 
785  fThisFolderPath =
786  theDocument_->createElement(xercesc::XMLString::transcode("fDisplayName"));
787 
788  if(isLeaf)
789  {
790  fFileOrHistName =
791  theDocument_->createElement(xercesc::XMLString::transcode("fFileName"));
792  fileOrDirNameVal =
793  theDocument_->createTextNode(xercesc::XMLString::transcode(name.c_str()));
794  thisFolderNameVal =
795  theDocument_->createTextNode(xercesc::XMLString::transcode(name.c_str()));
796  ss_.str("");
797  ss_ << "name: " << ACRed << name << ACPlain << "/" << ACGreen << name;
798  STDLINE(ss_.str(), "");
799  }
800  else
801  {
802  std::string blank;
803  fFileOrHistName =
804  theDocument_->createElement(xercesc::XMLString::transcode("fFileName"));
805  fileOrDirNameVal =
806  theDocument_->createTextNode(xercesc::XMLString::transcode(blank.c_str()));
807  thisFolderNameVal = theDocument_->createTextNode(
808  xercesc::XMLString::transcode(fThisFolderPath_.c_str()));
809  ss_.str("");
810  ss_ << "name: " << ACRed << fThisFolderPath_ << ACPlain << "/" << ACGreen << name;
811  STDLINE(ss_.str(), "");
812  }
813 
814  node->appendChild(fFileOrHistName);
815  fFileOrHistName->appendChild(fileOrDirNameVal);
816 
817  node->appendChild(fThisFolderPath);
818  fThisFolderPath->appendChild(thisFolderNameVal);
819 
820  xercesc::DOMElement* leaf =
821  theDocument_->createElement(xercesc::XMLString::transcode("leaf"));
822  node->appendChild(leaf);
823 
824  xercesc::DOMText* leafVal = theDocument_->createTextNode(
825  xercesc::XMLString::transcode(isALeaf_[isLeaf].c_str()));
826  leaf->appendChild(leafVal);
827 
828  return node;
829 } //end populateBinaryTreeNode()
830 
831 //==========================================================================================
833 void XmlDocument::setDarioStyle(bool darioStyle)
834 {
835  darioXMLStyle_ = darioStyle;
836 } //end setDarioStyle()
Note that XmlDocument functionality is extended by HttpXmlDocument class.
Definition: XmlDocument.h:36
xercesc::DOMElement * addTextElementToParent(const std::string &childName, const std::string &childText, xercesc::DOMElement *parent)
Definition: XmlDocument.cc:244
void copyDocument(const xercesc::DOMDocument *toCopy, xercesc::DOMDocument *copy)
Definition: XmlDocument.cc:310
void recursiveRemoveChild(xercesc::DOMElement *childEl, xercesc::DOMElement *parentEl)
Definition: XmlDocument.cc:453
void setDarioStyle(bool darioStyle)
Used by developer Dario Menasce for alternative XML requests at web user interface.
Definition: XmlDocument.cc:833
XmlDocument(const std::string &rootName="ROOT")
Definition: XmlDocument.cc:46
void saveXmlDocument(const std::string &filePath)
Definition: XmlDocument.cc:473
void outputXmlDocument(std::ostringstream *out, bool dispStdOut=false)
Definition: XmlDocument.cc:348
void recursiveOutputXmlDocument(xercesc::DOMElement *currEl, std::ostringstream *out, bool dispStdOut=false, const std::string &tabStr="")
Definition: XmlDocument.cc:358
static std::string escapeString(std::string inString, bool allowWhiteSpace=false)
static std::string stackTrace(void)