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"
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>
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>
23 #include <xercesc/parsers/XercesDOMParser.hpp>
24 #include <xercesc/util/XMLUni.hpp>
25 #include <xercesc/util/XercesDefs.hpp>
27 #include <xercesc/util/OutOfMemoryException.hpp>
28 #include <xercesc/framework/LocalFileFormatTarget.hpp>
34 #include <sys/types.h>
53 HttpXmlDocument::HttpXmlDocument(std::string cookieCode, std::string displayName) :
57 headerTagName_ (
"HEADER"),
58 dataTagName_ (
"DATA"),
59 cookieCodeTagName_ (
"CookieCode"),
60 displayNameTagName_(
"DisplayName")
65 if(cookieCode !=
"" || displayName !=
"")
67 headerElement_ = theDocument_->createElement(CONVERT_TO_XML(headerTagName_));
68 rootElement_->appendChild(headerElement_);
70 addTextElementToParent(cookieCodeTagName_,cookieCode,headerElement_);
72 addTextElementToParent(displayNameTagName_,displayName,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_);
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);
109 HttpXmlDocument::~HttpXmlDocument(
void)
112 void HttpXmlDocument::setHeader(std::string cookieCode, std::string displayName)
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());
123 if(cookieCode !=
"" || displayName !=
"")
125 headerElement_ = theDocument_->createElement(CONVERT_TO_XML(headerTagName_));
126 rootElement_->appendChild(headerElement_);
128 addTextElementToParent(cookieCodeTagName_,cookieCode,headerElement_);
129 if(displayName !=
"")
130 addTextElementToParent(displayNameTagName_,displayName,headerElement_);
135 xercesc::DOMElement* HttpXmlDocument::addTextElementToData(
const std::string &childName,
136 const std::string &childValue)
139 return addTextElementToParent(childName,childValue,dataElement_);
143 xercesc::DOMElement* HttpXmlDocument::addBinaryStringToData(
const std::string &childName,
144 const std::string &binary)
146 std::string convertStr =
"";
148 for(
unsigned int i=0;i<binary.length();++i)
151 sprintf(hexStr,
"%2.2X",((
unsigned char)binary[i]));
153 convertStr += hexStr;
156 return addTextElementToParent(childName,convertStr,dataElement_);
162 unsigned int HttpXmlDocument::getChildrenCount(xercesc::DOMElement* parent)
164 if(!parent) parent = dataElement_;
166 xercesc::DOMNodeList* nodeList = parent->getChildNodes();
167 unsigned int count = 0;
169 for(
unsigned int i = 0; i<nodeList->getLength();++i) {
170 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
181 void HttpXmlDocument::removeDataElement(
unsigned int dataChildIndex)
183 xercesc::DOMNodeList* nodeList = dataElement_->getChildNodes();
185 for(
unsigned int i = 0; i<nodeList->getLength();++i)
187 if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE)
192 recursiveRemoveChild((xercesc::DOMElement*)(nodeList->item(i)),dataElement_);
208 xercesc::DOMNodeList* nodeList = document.dataElement_->getChildNodes();
209 for(
unsigned int i = 0; i<nodeList->getLength();++i)
211 if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE)
214 recursiveAddElementToParent((xercesc::DOMElement*)(nodeList->item(i)),dataElement_,
true);
221 void HttpXmlDocument::outputXmlDocument (std::ostringstream *out,
bool dispStdOut,
222 bool allowWhiteSpace)
224 recursiveOutputXmlDocument(theDocument_->getDocumentElement(),out,dispStdOut,
"", allowWhiteSpace);
230 void HttpXmlDocument::recursiveOutputXmlDocument (xercesc::DOMElement *currEl, std::ostringstream *out,
231 bool dispStdOut, std::string tabStr,
bool allowWhiteSpace)
234 if(dispStdOut) std::cout << __COUT_HDR_FL__<< tabStr <<
"<" << XML_TO_CHAR(currEl->getNodeName()) ;
235 if(out) *out << tabStr <<
"<" << XML_TO_CHAR(currEl->getNodeName());
238 if( currEl->getFirstChild() != NULL &&
239 currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
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) <<
"'";
247 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
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))?
"/":
"")
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)
261 recursiveOutputXmlDocument ((xercesc::DOMElement*)(nodeList->item(i)),out,dispStdOut,newTabStr,allowWhiteSpace);
264 if(nodeList->getLength() > 1 || (nodeList->getLength() == 1 && currEl->getFirstChild()->getNodeType() != xercesc::DOMNode::TEXT_NODE))
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;
275 std::string HttpXmlDocument::getMatchingValue (
const std::string &field,
const unsigned int occurance)
277 unsigned int count = 0;
278 return recursiveFindElementValue(theDocument_->getDocumentElement(),field,occurance,count);
284 std::string HttpXmlDocument::recursiveFindElementValue (xercesc::DOMElement *currEl,
const std::string &field,
const unsigned int occurance,
unsigned int &count)
286 if (XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++)
288 if( currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
289 return escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
296 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
297 for(
unsigned int i = 0; i<nodeList->getLength();++i)
298 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
300 retStr = recursiveFindElementValue ((xercesc::DOMElement*)(nodeList->item(i)),field,occurance,count);
301 if(retStr !=
"")
return retStr;
311 void HttpXmlDocument::getAllMatchingValues (
const std::string &field, std::vector<std::string> &retVec)
313 recursiveFindAllElements(theDocument_->getDocumentElement(),field,&retVec);
319 void HttpXmlDocument::recursiveFindAllElements (xercesc::DOMElement *currEl,
const std::string &field,std::vector<std::string> *retVec)
321 if (XML_TO_CHAR(currEl->getNodeName()) == field &&
322 currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
323 retVec->push_back(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
327 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
328 for(
unsigned int i = 0; i<nodeList->getLength();++i)
329 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
330 recursiveFindAllElements ((xercesc::DOMElement*)(nodeList->item(i)),field,retVec);
337 xercesc::DOMElement* HttpXmlDocument::getMatchingElement (
const std::string &field,
const unsigned int occurance)
339 return getMatchingElementInSubtree(theDocument_->getDocumentElement(),field,occurance);
347 xercesc::DOMElement* HttpXmlDocument::getMatchingElementInSubtree (xercesc::DOMElement *parentEl,
const std::string &field,
348 const unsigned int occurance)
350 unsigned int count = 0;
351 return recursiveFindElement(parentEl,field,occurance,count);
357 xercesc::DOMElement* HttpXmlDocument::recursiveFindElement (xercesc::DOMElement *currEl,
const std::string &field,
358 const unsigned int occurance,
unsigned int &count)
360 if (XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++)
362 if( currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
368 xercesc::DOMElement* retEl;
370 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
371 for(
unsigned int i = 0; i<nodeList->getLength();++i)
372 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
374 retEl = recursiveFindElement ((xercesc::DOMElement*)(nodeList->item(i)),field,occurance,count);
375 if(retEl)
return retEl;
385 void HttpXmlDocument::recursiveAddElementToParent(xercesc::DOMElement* child, xercesc::DOMElement* parent,
bool html)
387 std::string childText =
"";
389 std::string childName = XML_TO_CHAR(child->getNodeName());
391 if( child->getFirstChild() != NULL && child->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
393 childText = XML_TO_CHAR(child->getFirstChild()->getNodeValue());
395 childText = escapeString(childText);
400 xercesc::DOMElement* newParent = addTextElementToParent(childName, childText, parent);
403 xercesc::DOMNodeList *nodeList = child->getChildNodes();
404 for(
unsigned int i = 0; i<nodeList->getLength();++i)
406 if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE)
409 recursiveAddElementToParent((xercesc::DOMElement*)(nodeList->item(i)), newParent, html);
417 void HttpXmlDocument::getAllMatchingElements (
const std::string &field, std::vector<xercesc::DOMElement*> &retVec)
419 recursiveFindAllElements(theDocument_->getDocumentElement(),field,&retVec);
426 void HttpXmlDocument::recursiveFindAllElements (xercesc::DOMElement *currEl,
const std::string &field,std::vector<xercesc::DOMElement*> *retVec)
428 if (XML_TO_CHAR(currEl->getNodeName()) == field &&
429 currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
430 retVec->push_back(currEl);
434 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
435 for(
unsigned int i = 0; i<nodeList->getLength();++i)
436 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
437 recursiveFindAllElements ((xercesc::DOMElement*)(nodeList->item(i)),field,retVec);
474 bool HttpXmlDocument::loadXmlDocument (
const std::string &filePath)
478 struct stat fileStatus;
480 if(stat(filePath.c_str(), &fileStatus) != 0)
482 std::cout << __COUT_HDR_FL__<<
"File not accessible." << std::endl;
490 xercesc::XercesDOMParser* parser =
new xercesc::XercesDOMParser;
492 parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
493 parser->setDoNamespaces (
true );
494 parser->setDoSchema (
true );
495 parser->useCachedGrammarInParse (
false );
499 parser->parse( filePath.c_str() );
502 theDocument_ = parser->adoptDocument();
505 rootElement_ = theDocument_->getDocumentElement();
507 throw(std::runtime_error(
"empty XML theDocument_" ));
509 recursiveFixTextFields(rootElement_);
511 xercesc::DOMNodeList *nodeList = theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_));
512 if(nodeList->getLength())
513 headerElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_))->item(0));
517 dataElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(dataTagName_))->item(0));
519 catch( xercesc::XMLException& e )
521 std::cout << __COUT_HDR_FL__<<
"Error parsing file." << std::endl;
532 void HttpXmlDocument::recursiveFixTextFields(xercesc::DOMElement *currEl)
534 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
537 for(
unsigned int i = 0; i<nodeList->getLength();++i)
538 if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE)
539 ((xercesc::DOMElement*)(nodeList->item(i)))->setTextContent(CONVERT_TO_XML(
540 escapeString(XML_TO_CHAR(((xercesc::DOMElement*)(nodeList->item(i)))->getNodeValue()))));
542 recursiveFixTextFields ((xercesc::DOMElement*)(nodeList->item(i)));