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"
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,
285 const unsigned int occurance,
unsigned int &count)
287 if (XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++)
289 if( currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
290 return escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
297 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
298 for(
unsigned int i = 0; i<nodeList->getLength();++i)
299 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
301 retStr = recursiveFindElementValue ((xercesc::DOMElement*)(nodeList->item(i)),field,occurance,count);
302 if(retStr !=
"")
return retStr;
312 void HttpXmlDocument::getAllMatchingValues (
const std::string &field, std::vector<std::string> &retVec)
314 recursiveFindAllElements(theDocument_->getDocumentElement(),field,&retVec);
320 void HttpXmlDocument::recursiveFindAllElements (xercesc::DOMElement *currEl,
const std::string &field,std::vector<std::string> *retVec)
322 if (XML_TO_CHAR(currEl->getNodeName()) == field &&
323 currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
324 retVec->push_back(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
328 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
329 for(
unsigned int i = 0; i<nodeList->getLength();++i)
330 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
331 recursiveFindAllElements ((xercesc::DOMElement*)(nodeList->item(i)),field,retVec);
338 xercesc::DOMElement* HttpXmlDocument::getMatchingElement (
const std::string &field,
const unsigned int occurance)
340 return getMatchingElementInSubtree(theDocument_->getDocumentElement(),field,occurance);
348 xercesc::DOMElement* HttpXmlDocument::getMatchingElementInSubtree (xercesc::DOMElement *parentEl,
const std::string &field,
349 const unsigned int occurance)
351 unsigned int count = 0;
352 return recursiveFindElement(parentEl,field,occurance,count);
358 xercesc::DOMElement* HttpXmlDocument::recursiveFindElement (xercesc::DOMElement *currEl,
const std::string &field,
359 const unsigned int occurance,
unsigned int &count)
361 if (XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++)
363 if( currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
369 xercesc::DOMElement* retEl;
371 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
372 for(
unsigned int i = 0; i<nodeList->getLength();++i)
373 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
375 retEl = recursiveFindElement ((xercesc::DOMElement*)(nodeList->item(i)),field,occurance,count);
376 if(retEl)
return retEl;
386 void HttpXmlDocument::recursiveAddElementToParent(xercesc::DOMElement* child, xercesc::DOMElement* parent,
bool html)
388 std::string childText =
"";
390 std::string childName = XML_TO_CHAR(child->getNodeName());
392 if( child->getFirstChild() != NULL && child->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
394 childText = XML_TO_CHAR(child->getFirstChild()->getNodeValue());
396 childText = escapeString(childText);
401 xercesc::DOMElement* newParent = addTextElementToParent(childName, childText, parent);
404 xercesc::DOMNodeList *nodeList = child->getChildNodes();
405 for(
unsigned int i = 0; i<nodeList->getLength();++i)
407 if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE)
410 recursiveAddElementToParent((xercesc::DOMElement*)(nodeList->item(i)), newParent, html);
418 void HttpXmlDocument::getAllMatchingElements (
const std::string &field, std::vector<xercesc::DOMElement*> &retVec)
420 recursiveFindAllElements(theDocument_->getDocumentElement(),field,&retVec);
427 void HttpXmlDocument::recursiveFindAllElements (xercesc::DOMElement *currEl,
const std::string &field,std::vector<xercesc::DOMElement*> *retVec)
429 if (XML_TO_CHAR(currEl->getNodeName()) == field &&
430 currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
431 retVec->push_back(currEl);
435 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
436 for(
unsigned int i = 0; i<nodeList->getLength();++i)
437 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
438 recursiveFindAllElements ((xercesc::DOMElement*)(nodeList->item(i)),field,retVec);
475 bool HttpXmlDocument::loadXmlDocument (
const std::string &filePath)
479 struct stat fileStatus;
481 if(stat(filePath.c_str(), &fileStatus) != 0)
483 std::cout << __COUT_HDR_FL__<<
"File not accessible." << std::endl;
491 xercesc::XercesDOMParser* parser =
new xercesc::XercesDOMParser;
493 parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
494 parser->setDoNamespaces (
true );
495 parser->setDoSchema (
true );
496 parser->useCachedGrammarInParse (
false );
500 parser->parse( filePath.c_str() );
503 theDocument_ = parser->adoptDocument();
506 rootElement_ = theDocument_->getDocumentElement();
508 throw(std::runtime_error(
"empty XML theDocument_" ));
510 recursiveFixTextFields(rootElement_);
512 xercesc::DOMNodeList *nodeList = theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_));
513 if(nodeList->getLength())
514 headerElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_))->item(0));
518 dataElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(dataTagName_))->item(0));
520 catch( xercesc::XMLException& e )
522 std::cout << __COUT_HDR_FL__<<
"Error parsing file." << std::endl;
533 void HttpXmlDocument::recursiveFixTextFields(xercesc::DOMElement *currEl)
535 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
538 for(
unsigned int i = 0; i<nodeList->getLength();++i)
539 if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE)
540 ((xercesc::DOMElement*)(nodeList->item(i)))->setTextContent(CONVERT_TO_XML(
541 escapeString(XML_TO_CHAR(((xercesc::DOMElement*)(nodeList->item(i)))->getNodeValue()))));
543 recursiveFixTextFields ((xercesc::DOMElement*)(nodeList->item(i)));