1 #include "otsdaq/XmlUtilities/HttpXmlDocument.h"
2 #include "otsdaq/Macros/CoutMacros.h"
3 #include "otsdaq/MessageFacility/MessageFacility.h"
4 #include "otsdaq/XmlUtilities/ConvertFromXML.h"
5 #include "otsdaq/XmlUtilities/ConvertToXML.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/DOMImplementationLS.hpp>
15 #include <xercesc/dom/DOMImplementationRegistry.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/framework/LocalFileFormatTarget.hpp>
28 #include <xercesc/util/OutOfMemoryException.hpp>
36 #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")
64 if(cookieCode !=
"" || displayName !=
"")
66 headerElement_ = theDocument_->createElement(CONVERT_TO_XML(headerTagName_));
67 rootElement_->appendChild(headerElement_);
69 addTextElementToParent(cookieCodeTagName_, cookieCode, headerElement_);
71 addTextElementToParent(displayNameTagName_, displayName, headerElement_);
75 dataElement_ = theDocument_->createElement(CONVERT_TO_XML(dataTagName_));
76 rootElement_->appendChild(dataElement_);
85 , headerTagName_(doc.headerTagName_)
86 , dataTagName_(doc.dataTagName_)
87 , cookieCodeTagName_(doc.cookieCodeTagName_)
88 , displayNameTagName_(doc.displayNameTagName_)
99 recursiveElementCopy(doc.rootElement_, rootElement_);
101 if(doc.headerElement_ != 0)
102 headerElement_ = (xercesc::DOMElement*)rootElement_->getElementsByTagName(CONVERT_TO_XML(headerTagName_))->item(0);
104 dataElement_ = (xercesc::DOMElement*)rootElement_->getElementsByTagName(CONVERT_TO_XML(dataTagName_))->item(0);
110 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 "
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_);
142 xercesc::DOMElement* HttpXmlDocument::addBinaryStringToData(
const std::string& childName,
const std::string& binary)
144 std::string convertStr =
"";
146 for(
unsigned int i = 0; i < binary.length(); ++i)
149 sprintf(hexStr,
"%2.2X", ((
unsigned char)binary[i]));
151 convertStr += hexStr;
154 return addTextElementToParent(childName, convertStr, dataElement_);
160 unsigned int HttpXmlDocument::getChildrenCount(xercesc::DOMElement* parent)
163 parent = dataElement_;
165 xercesc::DOMNodeList* nodeList = parent->getChildNodes();
166 unsigned int count = 0;
168 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);
222 void HttpXmlDocument::outputXmlDocument(std::ostringstream* out,
bool dispStdOut,
bool allowWhiteSpace)
224 recursiveOutputXmlDocument(theDocument_->getDocumentElement(), out, dispStdOut,
"", allowWhiteSpace);
230 void HttpXmlDocument::recursiveOutputXmlDocument(
231 xercesc::DOMElement* currEl, std::ostringstream* out,
bool dispStdOut, std::string tabStr,
bool allowWhiteSpace)
235 __COUT__ << tabStr <<
"<" << XML_TO_CHAR(currEl->getNodeName());
237 *out << tabStr <<
"<" << XML_TO_CHAR(currEl->getNodeName());
240 if(currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
244 std::cout <<
" value='" << escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()), allowWhiteSpace) <<
"'";
246 *out <<
" value='" << escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()), allowWhiteSpace) <<
"'";
249 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
253 std::cout << ((nodeList->getLength() == 0 || (nodeList->getLength() == 1 && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE))
257 <<
" len:" << nodeList->getLength() << std::endl;
267 std::string outText =
"";
268 if(currEl->getFirstChild() != NULL && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
269 outText = escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()), allowWhiteSpace);
271 if(darioXMLStyle_ && !(std::string(XML_TO_CHAR(currEl->getNodeName())) ==
"ROOT" || std::string(XML_TO_CHAR(currEl->getNodeName())) ==
"HEADER" ||
272 std::string(XML_TO_CHAR(currEl->getNodeName())) ==
"DATA" || std::string(XML_TO_CHAR(currEl->getNodeName())) ==
"node" ||
273 std::string(XML_TO_CHAR(currEl->getNodeName())) ==
"nodes"))
275 *out <<
">" << outText <<
"</" << XML_TO_CHAR(currEl->getNodeName()) <<
">" << std::endl;
279 *out << ((nodeList->getLength() == 0 || (nodeList->getLength() == 1 && currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE))
288 std::string newTabStr = tabStr +
"\t";
289 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
290 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
291 recursiveOutputXmlDocument((xercesc::DOMElement*)(nodeList->item(i)), out, dispStdOut, newTabStr, allowWhiteSpace);
294 if(nodeList->getLength() > 1 || (nodeList->getLength() == 1 && currEl->getFirstChild()->getNodeType() != xercesc::DOMNode::TEXT_NODE))
297 __COUT__ << tabStr <<
"</" << XML_TO_CHAR(currEl->getNodeName()) <<
">" << std::endl;
299 *out << tabStr <<
"</" << XML_TO_CHAR(currEl->getNodeName()) <<
">" << std::endl;
307 std::string HttpXmlDocument::getMatchingValue(
const std::string& field,
const unsigned int occurance)
309 unsigned int count = 0;
310 return recursiveFindElementValue(theDocument_->getDocumentElement(), field, occurance, count);
316 std::string HttpXmlDocument::recursiveFindElementValue(xercesc::DOMElement* currEl,
const std::string& field,
const unsigned int occurance,
unsigned int& count)
318 if(XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++)
320 if(currEl->getFirstChild() != NULL &&
321 currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
323 return escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
330 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
331 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
332 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
334 retStr = recursiveFindElementValue((xercesc::DOMElement*)(nodeList->item(i)), field, occurance, count);
346 void HttpXmlDocument::getAllMatchingValues(
const std::string& field, std::vector<std::string>& retVec)
348 recursiveFindAllElements(theDocument_->getDocumentElement(), field, &retVec);
354 void HttpXmlDocument::recursiveFindAllElements(xercesc::DOMElement* currEl,
const std::string& field, std::vector<std::string>* retVec)
356 if(XML_TO_CHAR(currEl->getNodeName()) == field && currEl->getFirstChild() != NULL &&
357 currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
359 retVec->push_back(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
362 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
363 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
364 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
365 recursiveFindAllElements((xercesc::DOMElement*)(nodeList->item(i)), field, retVec);
372 xercesc::DOMElement* HttpXmlDocument::getMatchingElement(
const std::string& field,
const unsigned int occurance)
374 return getMatchingElementInSubtree(theDocument_->getDocumentElement(), field, occurance);
382 xercesc::DOMElement* HttpXmlDocument::getMatchingElementInSubtree(xercesc::DOMElement* parentEl,
const std::string& field,
const unsigned int occurance)
384 unsigned int count = 0;
385 return recursiveFindElement(parentEl, field, occurance, count);
391 xercesc::DOMElement* HttpXmlDocument::recursiveFindElement(xercesc::DOMElement* currEl,
392 const std::string& field,
393 const unsigned int occurance,
396 if(XML_TO_CHAR(currEl->getNodeName()) == field && occurance == count++)
398 if(currEl->getFirstChild() != NULL &&
399 currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
406 xercesc::DOMElement* retEl;
408 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
409 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
410 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
412 retEl = recursiveFindElement((xercesc::DOMElement*)(nodeList->item(i)), field, occurance, count);
424 void HttpXmlDocument::recursiveAddElementToParent(xercesc::DOMElement* child, xercesc::DOMElement* parent,
bool html)
426 std::string childText =
"";
428 std::string childName = XML_TO_CHAR(child->getNodeName());
430 if(child->getFirstChild() != NULL && child->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
433 childText = XML_TO_CHAR(child->getFirstChild()->getNodeValue());
435 childText = escapeString(childText);
441 xercesc::DOMElement* newParent = addTextElementToParent(childName, childText, parent);
444 xercesc::DOMNodeList* nodeList = child->getChildNodes();
445 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
447 if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE)
450 recursiveAddElementToParent((xercesc::DOMElement*)(nodeList->item(i)), newParent, html);
458 void HttpXmlDocument::getAllMatchingElements(
const std::string& field, std::vector<xercesc::DOMElement*>& retVec)
460 recursiveFindAllElements(theDocument_->getDocumentElement(), field, &retVec);
466 void HttpXmlDocument::recursiveFindAllElements(xercesc::DOMElement* currEl,
const std::string& field, std::vector<xercesc::DOMElement*>* retVec)
468 if(XML_TO_CHAR(currEl->getNodeName()) == field && currEl->getFirstChild() != NULL &&
469 currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE)
471 retVec->push_back(currEl);
474 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
475 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
476 if(nodeList->item(i)->getNodeType() != xercesc::DOMNode::TEXT_NODE)
477 recursiveFindAllElements((xercesc::DOMElement*)(nodeList->item(i)), field, retVec);
514 bool HttpXmlDocument::loadXmlDocument(
const std::string& filePath)
519 struct stat fileStatus;
521 if(stat(filePath.c_str(), &fileStatus) != 0)
532 xercesc::XercesDOMParser* parser =
new xercesc::XercesDOMParser;
534 parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
535 parser->setDoNamespaces(
true);
536 parser->setDoSchema(
true);
537 parser->useCachedGrammarInParse(
false);
541 parser->parse(filePath.c_str());
544 theDocument_ = parser->adoptDocument();
549 rootElement_ = theDocument_->getDocumentElement();
552 __SS__ <<
"empty XML theDocument_: " << filePath << std::endl;
554 throw(std::runtime_error(
"empty XML theDocument_"));
557 recursiveFixTextFields(rootElement_);
559 xercesc::DOMNodeList* nodeList = theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_));
560 if(nodeList->getLength())
561 headerElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_))->item(0));
565 dataElement_ = (xercesc::DOMElement*)(theDocument_->getElementsByTagName(CONVERT_TO_XML(dataTagName_))->item(0));
567 catch(xercesc::XMLException& e)
569 __SS__ <<
"Error parsing file: " << filePath << std::endl;
571 __COUT__ <<
"Error parsing file." << std::endl;
582 void HttpXmlDocument::recursiveFixTextFields(xercesc::DOMElement* currEl)
584 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
587 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
588 if(nodeList->item(i)->getNodeType() == xercesc::DOMNode::TEXT_NODE)
589 ((xercesc::DOMElement*)(nodeList->item(i)))
590 ->setTextContent(CONVERT_TO_XML(
591 escapeString(XML_TO_CHAR(((xercesc::DOMElement*)(nodeList->item(i)))->getNodeValue()))));
593 recursiveFixTextFields((xercesc::DOMElement*)(nodeList->item(i)));