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,
const std::string &childValue)
138 return addTextElementToParent(childName,childValue,dataElement_);
144 unsigned int HttpXmlDocument::getChildrenCount(xercesc::DOMElement* parent)
146 if(!parent) parent = dataElement_;
148 xercesc::DOMNodeList* nodeList = parent->getChildNodes();
149 unsigned int count = 0;
151 for(
unsigned int i = 0; i<nodeList->getLength();++i) {
152 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
163 void HttpXmlDocument::removeDataElement(
unsigned int dataChildIndex)
165 xercesc::DOMNodeList* nodeList = dataElement_->getChildNodes();
167 for(
unsigned int i = 0; i<nodeList->getLength();++i)
169 if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE)
174 recursiveRemoveChild((xercesc::DOMElement*)(nodeList->item(i)),dataElement_);
190 xercesc::DOMNodeList* nodeList = document.dataElement_->getChildNodes();
191 for(
unsigned int i = 0; i<nodeList->getLength();++i)
193 if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE)
196 recursiveAddElementToParent((xercesc::DOMElement*)(nodeList->item(i)),dataElement_,
true);
203 void HttpXmlDocument::outputXmlDocument (std::ostringstream *out,
bool dispStdOut,
bool allowWhiteSpace)
205 recursiveOutputXmlDocument(theDocument_->getDocumentElement(),out,dispStdOut,
"", allowWhiteSpace);
211 void HttpXmlDocument::recursiveOutputXmlDocument (xercesc::DOMElement *currEl, std::ostringstream *out,
212 bool dispStdOut, std::string tabStr,
bool allowWhiteSpace)
215 if(dispStdOut) std::cout << __COUT_HDR_FL__<< tabStr <<
"<" << XML_TO_CHAR(currEl->getNodeName()) ;
216 if(out) *out << tabStr <<
"<" << XML_TO_CHAR(currEl->getNodeName());
219 if( currEl->getFirstChild() != NULL &&
220 currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
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) <<
"'";
228 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
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))?
"/":
"")
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)
242 recursiveOutputXmlDocument ((xercesc::DOMElement*)(nodeList->item(i)),out,dispStdOut,newTabStr,allowWhiteSpace);
245 if(nodeList->getLength() > 1 || (nodeList->getLength() == 1 && currEl->getFirstChild()->getNodeType() != xercesc::DOMNode::TEXT_NODE))
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;
256 std::string HttpXmlDocument::getMatchingValue (
const std::string &field,
const unsigned int occurance)
258 unsigned int count = 0;
259 return recursiveFindElementValue(theDocument_->getDocumentElement(),field,occurance,count);
265 std::string HttpXmlDocument::recursiveFindElementValue (xercesc::DOMElement *currEl,
const std::string &field,
const unsigned int occurance,
unsigned int &count)
267 if (XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++)
269 if( currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
270 return escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
277 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
278 for(
unsigned int i = 0; i<nodeList->getLength();++i)
279 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
281 retStr = recursiveFindElementValue ((xercesc::DOMElement*)(nodeList->item(i)),field,occurance,count);
282 if(retStr !=
"")
return retStr;
292 void HttpXmlDocument::getAllMatchingValues (
const std::string &field, std::vector<std::string> &retVec)
294 recursiveFindAllElements(theDocument_->getDocumentElement(),field,&retVec);
300 void HttpXmlDocument::recursiveFindAllElements (xercesc::DOMElement *currEl,
const std::string &field,std::vector<std::string> *retVec)
302 if (XML_TO_CHAR(currEl->getNodeName()) == field &&
303 currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
304 retVec->push_back(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
308 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
309 for(
unsigned int i = 0; i<nodeList->getLength();++i)
310 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
311 recursiveFindAllElements ((xercesc::DOMElement*)(nodeList->item(i)),field,retVec);
318 xercesc::DOMElement* HttpXmlDocument::getMatchingElement (
const std::string &field,
const unsigned int occurance)
320 return getMatchingElementInSubtree(theDocument_->getDocumentElement(),field,occurance);
328 xercesc::DOMElement* HttpXmlDocument::getMatchingElementInSubtree (xercesc::DOMElement *parentEl,
const std::string &field,
329 const unsigned int occurance)
331 unsigned int count = 0;
332 return recursiveFindElement(parentEl,field,occurance,count);
338 xercesc::DOMElement* HttpXmlDocument::recursiveFindElement (xercesc::DOMElement *currEl,
const std::string &field,
339 const unsigned int occurance,
unsigned int &count)
341 if (XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++)
343 if( currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
349 xercesc::DOMElement* retEl;
351 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
352 for(
unsigned int i = 0; i<nodeList->getLength();++i)
353 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
355 retEl = recursiveFindElement ((xercesc::DOMElement*)(nodeList->item(i)),field,occurance,count);
356 if(retEl)
return retEl;
366 void HttpXmlDocument::recursiveAddElementToParent(xercesc::DOMElement* child, xercesc::DOMElement* parent,
bool html)
368 std::string childText =
"";
370 std::string childName = XML_TO_CHAR(child->getNodeName());
372 if( child->getFirstChild() != NULL && child->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
374 childText = XML_TO_CHAR(child->getFirstChild()->getNodeValue());
376 childText = escapeString(childText);
381 xercesc::DOMElement* newParent = addTextElementToParent(childName, childText, parent);
384 xercesc::DOMNodeList *nodeList = child->getChildNodes();
385 for(
unsigned int i = 0; i<nodeList->getLength();++i)
387 if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE)
390 recursiveAddElementToParent((xercesc::DOMElement*)(nodeList->item(i)), newParent, html);
398 void HttpXmlDocument::getAllMatchingElements (
const std::string &field, std::vector<xercesc::DOMElement*> &retVec)
400 recursiveFindAllElements(theDocument_->getDocumentElement(),field,&retVec);
407 void HttpXmlDocument::recursiveFindAllElements (xercesc::DOMElement *currEl,
const std::string &field,std::vector<xercesc::DOMElement*> *retVec)
409 if (XML_TO_CHAR(currEl->getNodeName()) == field &&
410 currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
411 retVec->push_back(currEl);
415 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
416 for(
unsigned int i = 0; i<nodeList->getLength();++i)
417 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
418 recursiveFindAllElements ((xercesc::DOMElement*)(nodeList->item(i)),field,retVec);
455 bool HttpXmlDocument::loadXmlDocument (
const std::string &filePath)
459 struct stat fileStatus;
461 if(stat(filePath.c_str(), &fileStatus) != 0)
463 std::cout << __COUT_HDR_FL__<<
"File not accessible." << std::endl;
471 xercesc::XercesDOMParser* parser =
new xercesc::XercesDOMParser;
473 parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
474 parser->setDoNamespaces (
true );
475 parser->setDoSchema (
true );
476 parser->useCachedGrammarInParse (
false );
480 parser->parse( filePath.c_str() );
483 theDocument_ = parser->adoptDocument();
486 rootElement_ = theDocument_->getDocumentElement();
488 throw(std::runtime_error(
"empty XML theDocument_" ));
490 recursiveFixTextFields(rootElement_);
492 xercesc::DOMNodeList *nodeList = theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_));
493 if(nodeList->getLength())
494 headerElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_))->item(0));
498 dataElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(dataTagName_))->item(0));
500 catch( xercesc::XMLException& e )
502 std::cout << __COUT_HDR_FL__<<
"Error parsing file." << std::endl;
513 void HttpXmlDocument::recursiveFixTextFields(xercesc::DOMElement *currEl)
515 xercesc::DOMNodeList *nodeList = currEl->getChildNodes();
518 for(
unsigned int i = 0; i<nodeList->getLength();++i)
519 if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE)
520 ((xercesc::DOMElement*)(nodeList->item(i)))->setTextContent(CONVERT_TO_XML(
521 escapeString(XML_TO_CHAR(((xercesc::DOMElement*)(nodeList->item(i)))->getNodeValue()))));
523 recursiveFixTextFields ((xercesc::DOMElement*)(nodeList->item(i)));