1 #include "otsdaq/XmlUtilities/HttpXmlDocument.h"
2 #include "otsdaq/Macros/CoutMacros.h"
3 #include "otsdaq/Macros/StringMacros.h"
4 #include "otsdaq/MessageFacility/MessageFacility.h"
5 #include "otsdaq/XmlUtilities/ConvertFromXML.h"
6 #include "otsdaq/XmlUtilities/ConvertToXML.h"
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>
19 #include <xercesc/dom/DOMNodeIterator.hpp>
20 #include <xercesc/dom/DOMNodeList.hpp>
21 #include <xercesc/dom/DOMText.hpp>
22 #include <xercesc/validators/common/Grammar.hpp>
24 #include <xercesc/parsers/XercesDOMParser.hpp>
25 #include <xercesc/util/XMLUni.hpp>
26 #include <xercesc/util/XercesDefs.hpp>
28 #include <xercesc/framework/LocalFileFormatTarget.hpp>
29 #include <xercesc/util/OutOfMemoryException.hpp>
37 #include <sys/types.h>
58 , headerTagName_(
"HEADER")
59 , dataTagName_(
"DATA")
60 , cookieCodeTagName_(
"CookieCode")
61 , displayNameTagName_(
"DisplayName")
65 if(cookieCode !=
"" || displayName !=
"")
67 headerElement_ = theDocument_->createElement(CONVERT_TO_XML(headerTagName_));
68 rootElement_->appendChild(headerElement_);
76 dataElement_ = theDocument_->createElement(CONVERT_TO_XML(dataTagName_));
77 rootElement_->appendChild(dataElement_);
86 , headerTagName_(doc.headerTagName_)
87 , dataTagName_(doc.dataTagName_)
88 , cookieCodeTagName_(doc.cookieCodeTagName_)
89 , displayNameTagName_(doc.displayNameTagName_)
100 recursiveElementCopy(doc.rootElement_, rootElement_);
102 if(doc.headerElement_ != 0)
103 headerElement_ = (xercesc::DOMElement*)rootElement_
104 ->getElementsByTagName(CONVERT_TO_XML(headerTagName_))
107 dataElement_ = (xercesc::DOMElement*)rootElement_
108 ->getElementsByTagName(CONVERT_TO_XML(dataTagName_))
115 HttpXmlDocument::~HttpXmlDocument(
void) {}
117 void HttpXmlDocument::setHeader(std::string cookieCode, std::string displayName)
121 std::stringstream ss;
122 ss << __COUT_HDR_FL__
123 <<
"Can NOT set header to doc with a header! Only allowed for docs without "
128 if(cookieCode !=
"" || displayName !=
"")
130 headerElement_ = theDocument_->createElement(CONVERT_TO_XML(headerTagName_));
131 rootElement_->appendChild(headerElement_);
134 if(displayName !=
"")
140 xercesc::DOMElement* HttpXmlDocument::addTextElementToData(
const std::string& childName,
141 const std::string& childValue)
148 xercesc::DOMElement* HttpXmlDocument::addBinaryStringToData(
const std::string& childName,
149 const std::string& binary)
151 std::string convertStr =
"";
153 for(
unsigned int i = 0; i < binary.length(); ++i)
156 sprintf(hexStr,
"%2.2X", ((
unsigned char)binary[i]));
158 convertStr += hexStr;
170 parent = dataElement_;
172 xercesc::DOMNodeList* nodeList =
173 parent->getChildNodes();
174 unsigned int count = 0;
176 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
178 if(nodeList->item(i)->getNodeType() !=
179 xercesc::DOMNode::TEXT_NODE)
192 xercesc::DOMNodeList* nodeList =
193 dataElement_->getChildNodes();
195 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
197 if(nodeList->item(i)->getNodeType() ==
198 xercesc::DOMNode::TEXT_NODE)
219 xercesc::DOMNodeList* nodeList =
220 document.dataElement_->getChildNodes();
221 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
223 if(nodeList->item(i)->getNodeType() ==
224 xercesc::DOMNode::TEXT_NODE)
227 recursiveAddElementToParent(
228 (xercesc::DOMElement*)(nodeList->item(i)), dataElement_,
true);
238 bool allowWhiteSpace)
240 recursiveOutputXmlDocument(
241 theDocument_->getDocumentElement(), out, dispStdOut,
"", allowWhiteSpace);
247 void HttpXmlDocument::recursiveOutputXmlDocument(xercesc::DOMElement* currEl,
248 std::ostringstream* out,
251 bool allowWhiteSpace)
255 std::cout << tabStr <<
"<" << XML_TO_CHAR(currEl->getNodeName());
257 *out << tabStr <<
"<" << XML_TO_CHAR(currEl->getNodeName());
260 if(currEl->getFirstChild() != NULL &&
261 currEl->getFirstChild()->getNodeType() ==
262 xercesc::DOMNode::TEXT_NODE)
266 std::cout <<
" value='"
268 XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()),
274 XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()),
279 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
283 std::cout << ((nodeList->getLength() == 0 ||
284 (nodeList->getLength() == 1 &&
285 currEl->getFirstChild()->getNodeType() ==
286 xercesc::DOMNode::TEXT_NODE))
290 <<
" len:" << nodeList->getLength() << std::endl;
300 std::string outText =
"";
301 if(currEl->getFirstChild() != NULL &&
302 currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
304 XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()), allowWhiteSpace);
307 !(std::string(XML_TO_CHAR(currEl->getNodeName())) ==
"ROOT" ||
308 std::string(XML_TO_CHAR(currEl->getNodeName())) ==
"HEADER" ||
309 std::string(XML_TO_CHAR(currEl->getNodeName())) ==
"DATA" ||
310 std::string(XML_TO_CHAR(currEl->getNodeName())) ==
"node" ||
311 std::string(XML_TO_CHAR(currEl->getNodeName())) ==
"nodes"))
313 *out <<
">" << outText <<
"</" << XML_TO_CHAR(currEl->getNodeName())
318 *out << ((nodeList->getLength() == 0 ||
319 (nodeList->getLength() == 1 &&
320 currEl->getFirstChild()->getNodeType() ==
321 xercesc::DOMNode::TEXT_NODE))
330 std::string newTabStr = tabStr +
"\t";
331 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
332 if(nodeList->item(i)->getNodeType() !=
333 xercesc::DOMNode::TEXT_NODE)
334 recursiveOutputXmlDocument((xercesc::DOMElement*)(nodeList->item(i)),
340 if(currEl == dataElement_ &&
341 dataSs_.str().length())
344 std::cout << dataSs_.str() << std::endl;
346 *out << dataSs_.str() << std::endl;
350 if(nodeList->getLength() > 1 ||
351 (nodeList->getLength() == 1 &&
352 currEl->getFirstChild()->getNodeType() != xercesc::DOMNode::TEXT_NODE))
355 std::cout << tabStr <<
"</" << XML_TO_CHAR(currEl->getNodeName()) <<
">"
358 *out << tabStr <<
"</" << XML_TO_CHAR(currEl->getNodeName()) <<
">"
368 const unsigned int occurance)
370 unsigned int count = 0;
371 return recursiveFindElementValue(
372 theDocument_->getDocumentElement(), field, occurance, count);
378 std::string HttpXmlDocument::recursiveFindElementValue(xercesc::DOMElement* currEl,
379 const std::string& field,
380 const unsigned int occurance,
383 if(XML_TO_CHAR(currEl->getNodeName()) == field &&
384 occurance == count++)
386 if(currEl->getFirstChild() != NULL &&
387 currEl->getFirstChild()->getNodeType() ==
388 xercesc::DOMNode::TEXT_NODE)
391 XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
398 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
399 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
400 if(nodeList->item(i)->getNodeType() !=
401 xercesc::DOMNode::TEXT_NODE)
403 retStr = recursiveFindElementValue(
404 (xercesc::DOMElement*)(nodeList->item(i)), field, occurance, count);
417 std::vector<std::string>& retVec)
419 recursiveFindAllElements(theDocument_->getDocumentElement(), field, &retVec);
425 void HttpXmlDocument::recursiveFindAllElements(xercesc::DOMElement* currEl,
426 const std::string& field,
427 std::vector<std::string>* retVec)
429 if(XML_TO_CHAR(currEl->getNodeName()) == field && currEl->getFirstChild() != NULL &&
430 currEl->getFirstChild()->getNodeType() ==
431 xercesc::DOMNode::TEXT_NODE)
433 retVec->push_back(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
436 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
437 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
438 if(nodeList->item(i)->getNodeType() !=
439 xercesc::DOMNode::TEXT_NODE)
440 recursiveFindAllElements(
441 (xercesc::DOMElement*)(nodeList->item(i)), field, retVec);
449 const unsigned int occurance)
452 theDocument_->getDocumentElement(), field, occurance);
461 xercesc::DOMElement* parentEl,
const std::string& field,
const unsigned int occurance)
463 unsigned int count = 0;
464 return recursiveFindElement(parentEl, field, occurance, count);
470 xercesc::DOMElement* HttpXmlDocument::recursiveFindElement(xercesc::DOMElement* currEl,
471 const std::string& field,
472 const unsigned int occurance,
475 if(XML_TO_CHAR(currEl->getNodeName()) == field &&
476 occurance == count++)
478 if(currEl->getFirstChild() != NULL &&
479 currEl->getFirstChild()->getNodeType() ==
480 xercesc::DOMNode::TEXT_NODE)
487 xercesc::DOMElement* retEl;
489 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
490 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
491 if(nodeList->item(i)->getNodeType() !=
492 xercesc::DOMNode::TEXT_NODE)
494 retEl = recursiveFindElement(
495 (xercesc::DOMElement*)(nodeList->item(i)), field, occurance, count);
507 void HttpXmlDocument::recursiveAddElementToParent(xercesc::DOMElement* child,
508 xercesc::DOMElement* parent,
511 std::string childText =
"";
513 std::string childName =
514 XML_TO_CHAR(child->getNodeName());
516 if(child->getFirstChild() != NULL &&
517 child->getFirstChild()->getNodeType() ==
518 xercesc::DOMNode::TEXT_NODE)
521 childText = XML_TO_CHAR(child->getFirstChild()->getNodeValue());
532 xercesc::DOMNodeList* nodeList =
533 child->getChildNodes();
534 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
536 if(nodeList->item(i)->getNodeType() ==
537 xercesc::DOMNode::TEXT_NODE)
540 recursiveAddElementToParent(
541 (xercesc::DOMElement*)(nodeList->item(i)), newParent, html);
550 std::vector<xercesc::DOMElement*>& retVec)
552 recursiveFindAllElements(theDocument_->getDocumentElement(), field, &retVec);
558 void HttpXmlDocument::recursiveFindAllElements(xercesc::DOMElement* currEl,
559 const std::string& field,
560 std::vector<xercesc::DOMElement*>* retVec)
562 if(XML_TO_CHAR(currEl->getNodeName()) == field && currEl->getFirstChild() != NULL &&
563 currEl->getFirstChild()->getNodeType() ==
564 xercesc::DOMNode::TEXT_NODE)
566 retVec->push_back(currEl);
569 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
570 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
571 if(nodeList->item(i)->getNodeType() !=
572 xercesc::DOMNode::TEXT_NODE)
573 recursiveFindAllElements(
574 (xercesc::DOMElement*)(nodeList->item(i)), field, retVec);
616 struct stat fileStatus;
618 if(stat(filePath.c_str(), &fileStatus) != 0)
629 xercesc::XercesDOMParser* parser =
new xercesc::XercesDOMParser;
631 parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
632 parser->setDoNamespaces(
true);
633 parser->setDoSchema(
true);
634 parser->useCachedGrammarInParse(
false);
638 parser->parse(filePath.c_str());
641 theDocument_ = parser->adoptDocument();
646 rootElement_ = theDocument_->getDocumentElement();
649 __SS__ <<
"empty XML theDocument_: " << filePath << std::endl;
651 throw(std::runtime_error(
"empty XML theDocument_"));
654 recursiveFixTextFields(
657 xercesc::DOMNodeList* nodeList =
658 theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_));
659 if(nodeList->getLength())
661 (xercesc::DOMElement*)(theDocument_
662 ->getElementsByTagName(
663 CONVERT_TO_XML(headerTagName_))
668 dataElement_ = (xercesc::DOMElement*)(theDocument_
669 ->getElementsByTagName(
670 CONVERT_TO_XML(dataTagName_))
673 catch(xercesc::XMLException& e)
675 __SS__ <<
"Error parsing file: " << filePath << std::endl;
677 __COUT__ <<
"Error parsing file." << std::endl;
688 void HttpXmlDocument::recursiveFixTextFields(xercesc::DOMElement* currEl)
690 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
693 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
694 if(nodeList->item(i)->getNodeType() ==
695 xercesc::DOMNode::TEXT_NODE)
696 ((xercesc::DOMElement*)(nodeList->item(i)))
697 ->setTextContent(CONVERT_TO_XML(
699 ((xercesc::DOMElement*)(nodeList->item(i)))->getNodeValue()))));
701 recursiveFixTextFields((xercesc::DOMElement*)(nodeList->item(i)));
xercesc::DOMElement * getMatchingElement(const std::string &field, const unsigned int occurance=0)
void getAllMatchingValues(const std::string &field, std::vector< std::string > &retVec)
void outputXmlDocument(std::ostringstream *out, bool dispStdOut=false, bool allowWhiteSpace=false)
HttpXmlDocument(std::string cookieCode="", std::string displayName="")
xercesc::DOMElement * getMatchingElementInSubtree(xercesc::DOMElement *currEl, const std::string &field, const unsigned int occurance=0)
void copyDataChildren(HttpXmlDocument &document)
void removeDataElement(unsigned int dataChildIndex=0)
default to first child
bool loadXmlDocument(const std::string &filePath)
unsigned int getChildrenCount(xercesc::DOMElement *parent=0)
std::string getMatchingValue(const std::string &field, const unsigned int occurance=0)
void getAllMatchingElements(const std::string &field, std::vector< xercesc::DOMElement * > &retVec)
xercesc::DOMElement * addTextElementToParent(const std::string &childName, const std::string &childText, xercesc::DOMElement *parent)
void recursiveRemoveChild(xercesc::DOMElement *childEl, xercesc::DOMElement *parentEl)
static std::string escapeString(std::string inString, bool allowWhiteSpace=false)