1 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
2 #include "otsdaq-core/Macros/CoutMacros.h"
3 #include "otsdaq-core/MessageFacility/MessageFacility.h"
4 #include "otsdaq-core/XmlUtilities/ConvertFromXML.h"
5 #include "otsdaq-core/XmlUtilities/ConvertToXML.h"
8 #include <xercesc/dom/DOM.hpp>
9 #include <xercesc/dom/DOMDocument.hpp>
10 #include <xercesc/dom/DOMDocumentType.hpp>
11 #include <xercesc/dom/DOMElement.hpp>
12 #include <xercesc/dom/DOMImplementation.hpp>
13 #include <xercesc/dom/DOMImplementationLS.hpp>
14 #include <xercesc/dom/DOMImplementationRegistry.hpp>
17 #include <xercesc/dom/DOMNodeIterator.hpp>
18 #include <xercesc/dom/DOMNodeList.hpp>
19 #include <xercesc/dom/DOMText.hpp>
20 #include <xercesc/validators/common/Grammar.hpp>
22 #include <xercesc/parsers/XercesDOMParser.hpp>
23 #include <xercesc/util/XMLUni.hpp>
24 #include <xercesc/util/XercesDefs.hpp>
26 #include <xercesc/framework/LocalFileFormatTarget.hpp>
27 #include <xercesc/util/OutOfMemoryException.hpp>
35 #include <sys/types.h>
52 HttpXmlDocument::HttpXmlDocument(std::string cookieCode, std::string displayName)
56 , headerTagName_(
"HEADER")
57 , dataTagName_(
"DATA")
58 , cookieCodeTagName_(
"CookieCode")
59 , displayNameTagName_(
"DisplayName")
63 if(cookieCode !=
"" || displayName !=
"")
65 headerElement_ = theDocument_->createElement(CONVERT_TO_XML(headerTagName_));
66 rootElement_->appendChild(headerElement_);
68 addTextElementToParent(cookieCodeTagName_, cookieCode, headerElement_);
70 addTextElementToParent(displayNameTagName_, displayName, headerElement_);
74 dataElement_ = theDocument_->createElement(CONVERT_TO_XML(dataTagName_));
75 rootElement_->appendChild(dataElement_);
84 , headerTagName_(doc.headerTagName_)
85 , dataTagName_(doc.dataTagName_)
86 , cookieCodeTagName_(doc.cookieCodeTagName_)
87 , displayNameTagName_(doc.displayNameTagName_)
98 recursiveElementCopy(doc.rootElement_, rootElement_);
99 if(doc.headerElement_ != 0)
100 headerElement_ = (xercesc::DOMElement*)rootElement_
101 ->getElementsByTagName(CONVERT_TO_XML(headerTagName_))
103 dataElement_ = (xercesc::DOMElement*)rootElement_
104 ->getElementsByTagName(CONVERT_TO_XML(dataTagName_))
111 HttpXmlDocument::~HttpXmlDocument(
void) {}
113 void HttpXmlDocument::setHeader(std::string cookieCode, std::string displayName)
117 std::stringstream ss;
118 ss << __COUT_HDR_FL__
119 <<
"Can NOT set header to doc with a header! Only allowed for docs without "
124 if(cookieCode !=
"" || displayName !=
"")
126 headerElement_ = theDocument_->createElement(CONVERT_TO_XML(headerTagName_));
127 rootElement_->appendChild(headerElement_);
129 addTextElementToParent(cookieCodeTagName_, cookieCode, headerElement_);
130 if(displayName !=
"")
131 addTextElementToParent(displayNameTagName_, displayName, headerElement_);
136 xercesc::DOMElement* HttpXmlDocument::addTextElementToData(
const std::string& childName,
137 const std::string& childValue)
141 return addTextElementToParent(childName, childValue, dataElement_);
145 xercesc::DOMElement* HttpXmlDocument::addBinaryStringToData(
const std::string& childName,
146 const std::string& binary)
148 std::string convertStr =
"";
150 for(
unsigned int i = 0; i < binary.length(); ++i)
153 sprintf(hexStr,
"%2.2X", ((
unsigned char)binary[i]));
155 convertStr += hexStr;
158 return addTextElementToParent(childName, convertStr, dataElement_);
164 unsigned int HttpXmlDocument::getChildrenCount(xercesc::DOMElement* parent)
167 parent = dataElement_;
169 xercesc::DOMNodeList* nodeList =
170 parent->getChildNodes();
171 unsigned int count = 0;
173 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
175 if(nodeList->item(i)->getNodeType() !=
176 xercesc::DOMNode::TEXT_NODE)
187 void HttpXmlDocument::removeDataElement(
unsigned int dataChildIndex)
189 xercesc::DOMNodeList* nodeList =
190 dataElement_->getChildNodes();
192 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
194 if(nodeList->item(i)->getNodeType() ==
195 xercesc::DOMNode::TEXT_NODE)
200 recursiveRemoveChild((xercesc::DOMElement*)(nodeList->item(i)), dataElement_);
216 xercesc::DOMNodeList* nodeList =
217 document.dataElement_->getChildNodes();
218 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
220 if(nodeList->item(i)->getNodeType() ==
221 xercesc::DOMNode::TEXT_NODE)
224 recursiveAddElementToParent(
225 (xercesc::DOMElement*)(nodeList->item(i)), dataElement_,
true);
233 void HttpXmlDocument::outputXmlDocument(std::ostringstream* out,
235 bool allowWhiteSpace)
237 recursiveOutputXmlDocument(
238 theDocument_->getDocumentElement(), out, dispStdOut,
"", allowWhiteSpace);
244 void HttpXmlDocument::recursiveOutputXmlDocument(xercesc::DOMElement* currEl,
245 std::ostringstream* out,
248 bool allowWhiteSpace)
252 std::cout << __COUT_HDR_FL__ << tabStr <<
"<"
253 << XML_TO_CHAR(currEl->getNodeName());
255 *out << tabStr <<
"<" << XML_TO_CHAR(currEl->getNodeName());
258 if(currEl->getFirstChild() != NULL &&
259 currEl->getFirstChild()->getNodeType() ==
260 xercesc::DOMNode::TEXT_NODE)
264 std::cout <<
" value='"
266 XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()),
271 << escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()),
276 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
280 std::cout << ((nodeList->getLength() == 0 ||
281 (nodeList->getLength() == 1 &&
282 currEl->getFirstChild()->getNodeType() ==
283 xercesc::DOMNode::TEXT_NODE))
287 <<
" len:" << nodeList->getLength() << std::endl;
289 *out << ((nodeList->getLength() == 0 ||
290 (nodeList->getLength() == 1 &&
291 currEl->getFirstChild()->getNodeType() == xercesc::DOMNode::TEXT_NODE))
297 std::string newTabStr = tabStr +
"\t";
298 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
299 if(nodeList->item(i)->getNodeType() !=
300 xercesc::DOMNode::TEXT_NODE)
301 recursiveOutputXmlDocument((xercesc::DOMElement*)(nodeList->item(i)),
308 if(nodeList->getLength() > 1 ||
309 (nodeList->getLength() == 1 &&
310 currEl->getFirstChild()->getNodeType() != xercesc::DOMNode::TEXT_NODE))
313 std::cout << __COUT_HDR_FL__ << tabStr <<
"</"
314 << XML_TO_CHAR(currEl->getNodeName()) <<
">" << std::endl;
316 *out << tabStr <<
"</" << XML_TO_CHAR(currEl->getNodeName()) <<
">"
325 std::string HttpXmlDocument::getMatchingValue(
const std::string& field,
326 const unsigned int occurance)
328 unsigned int count = 0;
329 return recursiveFindElementValue(
330 theDocument_->getDocumentElement(), field, occurance, count);
336 std::string HttpXmlDocument::recursiveFindElementValue(xercesc::DOMElement* currEl,
337 const std::string& field,
338 const unsigned int occurance,
341 if(XML_TO_CHAR(currEl->getNodeName()) == field &&
342 occurance == count++)
344 if(currEl->getFirstChild() != NULL &&
345 currEl->getFirstChild()->getNodeType() ==
346 xercesc::DOMNode::TEXT_NODE)
348 return escapeString(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
355 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
356 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
357 if(nodeList->item(i)->getNodeType() !=
358 xercesc::DOMNode::TEXT_NODE)
360 retStr = recursiveFindElementValue(
361 (xercesc::DOMElement*)(nodeList->item(i)), field, occurance, count);
373 void HttpXmlDocument::getAllMatchingValues(
const std::string& field,
374 std::vector<std::string>& retVec)
376 recursiveFindAllElements(theDocument_->getDocumentElement(), field, &retVec);
382 void HttpXmlDocument::recursiveFindAllElements(xercesc::DOMElement* currEl,
383 const std::string& field,
384 std::vector<std::string>* retVec)
386 if(XML_TO_CHAR(currEl->getNodeName()) == field && currEl->getFirstChild() != NULL &&
387 currEl->getFirstChild()->getNodeType() ==
388 xercesc::DOMNode::TEXT_NODE)
390 retVec->push_back(XML_TO_CHAR(currEl->getFirstChild()->getNodeValue()));
393 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
394 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
395 if(nodeList->item(i)->getNodeType() !=
396 xercesc::DOMNode::TEXT_NODE)
397 recursiveFindAllElements(
398 (xercesc::DOMElement*)(nodeList->item(i)), field, retVec);
405 xercesc::DOMElement* HttpXmlDocument::getMatchingElement(
const std::string& field,
406 const unsigned int occurance)
408 return getMatchingElementInSubtree(
409 theDocument_->getDocumentElement(), field, occurance);
417 xercesc::DOMElement* HttpXmlDocument::getMatchingElementInSubtree(
418 xercesc::DOMElement* parentEl,
const std::string& field,
const unsigned int occurance)
420 unsigned int count = 0;
421 return recursiveFindElement(parentEl, field, occurance, count);
427 xercesc::DOMElement* HttpXmlDocument::recursiveFindElement(xercesc::DOMElement* currEl,
428 const std::string& field,
429 const unsigned int occurance,
432 if(XML_TO_CHAR(currEl->getNodeName()) == field &&
433 occurance == count++)
435 if(currEl->getFirstChild() != NULL &&
436 currEl->getFirstChild()->getNodeType() ==
437 xercesc::DOMNode::TEXT_NODE)
444 xercesc::DOMElement* retEl;
446 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
447 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
448 if(nodeList->item(i)->getNodeType() !=
449 xercesc::DOMNode::TEXT_NODE)
451 retEl = recursiveFindElement(
452 (xercesc::DOMElement*)(nodeList->item(i)), field, occurance, count);
464 void HttpXmlDocument::recursiveAddElementToParent(xercesc::DOMElement* child,
465 xercesc::DOMElement* parent,
468 std::string childText =
"";
470 std::string childName =
471 XML_TO_CHAR(child->getNodeName());
473 if(child->getFirstChild() != NULL &&
474 child->getFirstChild()->getNodeType() ==
475 xercesc::DOMNode::TEXT_NODE)
478 childText = XML_TO_CHAR(child->getFirstChild()->getNodeValue());
480 childText = escapeString(childText);
486 xercesc::DOMElement* newParent = addTextElementToParent(childName, childText, parent);
489 xercesc::DOMNodeList* nodeList =
490 child->getChildNodes();
491 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
493 if(nodeList->item(i)->getNodeType() ==
494 xercesc::DOMNode::TEXT_NODE)
497 recursiveAddElementToParent(
498 (xercesc::DOMElement*)(nodeList->item(i)), newParent, html);
506 void HttpXmlDocument::getAllMatchingElements(
const std::string& field,
507 std::vector<xercesc::DOMElement*>& retVec)
509 recursiveFindAllElements(theDocument_->getDocumentElement(), field, &retVec);
515 void HttpXmlDocument::recursiveFindAllElements(xercesc::DOMElement* currEl,
516 const std::string& field,
517 std::vector<xercesc::DOMElement*>* retVec)
519 if(XML_TO_CHAR(currEl->getNodeName()) == field && currEl->getFirstChild() != NULL &&
520 currEl->getFirstChild()->getNodeType() ==
521 xercesc::DOMNode::TEXT_NODE)
523 retVec->push_back(currEl);
526 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
527 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
528 if(nodeList->item(i)->getNodeType() !=
529 xercesc::DOMNode::TEXT_NODE)
530 recursiveFindAllElements(
531 (xercesc::DOMElement*)(nodeList->item(i)), field, retVec);
568 bool HttpXmlDocument::loadXmlDocument(
const std::string& filePath)
573 struct stat fileStatus;
575 if(stat(filePath.c_str(), &fileStatus) != 0)
577 std::cout << __COUT_HDR_FL__ <<
"File not accessible." << std::endl;
585 xercesc::XercesDOMParser* parser =
new xercesc::XercesDOMParser;
587 parser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
588 parser->setDoNamespaces(
true);
589 parser->setDoSchema(
true);
590 parser->useCachedGrammarInParse(
false);
594 parser->parse(filePath.c_str());
597 theDocument_ = parser->adoptDocument();
602 rootElement_ = theDocument_->getDocumentElement();
604 throw(std::runtime_error(
"empty XML theDocument_"));
606 recursiveFixTextFields(
609 xercesc::DOMNodeList* nodeList =
610 theDocument_->getElementsByTagName(CONVERT_TO_XML(headerTagName_));
611 if(nodeList->getLength())
613 (xercesc::DOMElement*)(theDocument_
614 ->getElementsByTagName(
615 CONVERT_TO_XML(headerTagName_))
620 dataElement_ = (xercesc::DOMElement*)(theDocument_
621 ->getElementsByTagName(
622 CONVERT_TO_XML(dataTagName_))
625 catch(xercesc::XMLException& e)
627 std::cout << __COUT_HDR_FL__ <<
"Error parsing file." << std::endl;
638 void HttpXmlDocument::recursiveFixTextFields(xercesc::DOMElement* currEl)
640 xercesc::DOMNodeList* nodeList = currEl->getChildNodes();
643 for(
unsigned int i = 0; i < nodeList->getLength(); ++i)
644 if(nodeList->item(i)->getNodeType() ==
645 xercesc::DOMNode::TEXT_NODE)
646 ((xercesc::DOMElement*)(nodeList->item(i)))
647 ->setTextContent(CONVERT_TO_XML(
648 escapeString(XML_TO_CHAR(
649 ((xercesc::DOMElement*)(nodeList->item(i)))->getNodeValue()))));
651 recursiveFixTextFields((xercesc::DOMElement*)(nodeList->item(i)));