11 #include <utl/Reader.h>
12 #include <utl/Branch.h>
13 #include <utl/XercesUtil.h>
15 #include <utl/ErrorLogger.h>
16 #include <utl/UnitGrammar.h>
17 #include <utl/ExpressionParser.h>
18 #include <utl/AugerException.h>
19 #include <utl/UTCDateTime.h>
20 #include <utl/StringCompare.h>
22 #include <utl/Function.h>
24 #include <xercesc/util/XercesVersion.hpp>
25 #if _XERCES_VERSION >= 30000
27 # include <xercesc/dom/DOMLSSerializer.hpp>
29 # include <xercesc/framework/MemBufFormatTarget.hpp>
31 #include <xercesc/dom/DOMImplementation.hpp>
32 #include <xercesc/dom/DOMImplementationLS.hpp>
35 #include <utl/ReaderErrorReporter.h>
37 #include <boost/tokenizer.hpp>
38 #include <boost/lexical_cast.hpp>
39 #include <boost/algorithm/string/trim.hpp>
40 #include <boost/lambda/lambda.hpp>
43 using namespace xercesc;
56 const string err =
"Operating on null-Branch. " + fWarning;
67 const auto ownerDoc = GetDOMNode()->getOwnerDocument();
69 return Branch(fOwner, ownerDoc->getDocumentElement());
72 b.
SetWarning(
"Owner document (top branch) not found.");
84 if (fDOMNode->getNodeType() != DOMNode::ELEMENT_NODE)
86 DOMNode*
const parentNode = fDOMNode->getParentNode();
87 if (!parentNode || parentNode->getNodeType() != DOMNode::ELEMENT_NODE)
89 return Branch(fOwner, parentNode);
103 DOMNode* childNode = fDOMNode->getFirstChild();
104 while (childNode && childNode->getNodeType() != DOMNode::ELEMENT_NODE)
105 childNode = childNode->getNextSibling();
110 warn <<
"First child in branch '" << GetName() <<
"' not found.";
130 requestedAttributeMap.erase(
"unit");
131 requestedAttributeMap.erase(
"UNIT");
132 requestedAttributeMap.erase(
"Unit");
133 requestedAttributeMap.erase(
"variables");
134 requestedAttributeMap.erase(
"VARIABLES");
135 requestedAttributeMap.erase(
"Variables");
137 for (DOMNode* childNode = fDOMNode->getFirstChild();
138 childNode; childNode = childNode->getNextSibling())
140 if (childNode->getNodeType() == DOMNode::ELEMENT_NODE) {
142 const string foundName =
AsString(childNode->getNodeName());
144 if (foundName == requestedName) {
148 const DOMNamedNodeMap*
const attributes = childNode->getAttributes();
150 for (
unsigned int i = 0; i < attributes->getLength(); ++i) {
152 const DOMNode*
const attr = attributes->item(i);
154 foundAttributeMap.insert(make_pair(
AsString(attr->getNodeName()),
161 foundAttributeMap.erase(
"unit");
162 foundAttributeMap.erase(
"UNIT");
163 foundAttributeMap.erase(
"Unit");
164 foundAttributeMap.erase(
"variables");
165 foundAttributeMap.erase(
"VARIABLES");
166 foundAttributeMap.erase(
"Variables");
170 if (foundAttributeMap.size() == requestedAttributeMap.size()) {
175 for (
auto foundIter = foundAttributeMap.begin();
176 foundIter != foundAttributeMap.end(); ++foundIter) {
178 const auto requestedIter = requestedAttributeMap.find(foundIter->first);
179 if (requestedIter == requestedAttributeMap.end() ||
180 foundIter->second != requestedIter->second) {
188 return Branch(fOwner, childNode);
198 warn <<
"Child <" << requestedName <<
"> in branch <"
199 << GetName() <<
"> not found";
216 return GetChild(requestedName, dummy);
226 using namespace boost;
229 return GetChild(requestedName);
231 char_separator<char> aSep(
" ");
232 char_separator<char> kvSep(
"=");
233 typedef tokenizer<char_separator<char> > Tokenizer;
234 Tokenizer aTok(att, aSep);
236 for (Tokenizer::const_iterator aIt = aTok.begin(); aIt != aTok.end(); ++aIt) {
239 Tokenizer kvTok(*aIt, kvSep);
240 Tokenizer::const_iterator kvIt = kvTok.begin();
241 if (kvIt != kvTok.end()) {
244 if (kvIt != kvTok.end())
250 return GetChild(requestedName, attMap);
274 const DOMNamedNodeMap*
const attributes = fDOMNode->getAttributes();
275 for (
unsigned int i = 0; i < attributes->getLength(); ++i) {
276 const DOMNode*
const attr = attributes->item(i);
289 DOMNode* siblingNode = fDOMNode->getNextSibling();
291 while (siblingNode && siblingNode->getNodeType() != DOMNode::ELEMENT_NODE)
292 siblingNode = siblingNode->getNextSibling();
297 warn <<
"Next sibling of branch <" << GetName() <<
"> not found";
310 DOMNode* siblingNode = fDOMNode->getPreviousSibling();
312 while (siblingNode && siblingNode->getNodeType() != DOMNode::ELEMENT_NODE)
313 siblingNode = siblingNode->getPreviousSibling();
318 warn <<
"Next sibling of branch <" << GetName() <<
"> not found";
332 DOMNode*
const parentNode = fDOMNode->getParentNode();
334 Branch parentBranch(fOwner, parentNode);
338 warn <<
"Parent of branch <" << GetName() <<
"> not found";
342 return parentBranch.
GetChild(requestedName, attributeMap);
352 return GetSibling(requestedName, dummy);
369 return GetSibling(requestedName, idMap);
379 return AsString(fDOMNode->getNodeName());
396 const DOMNodeList*
const dataNodes = fDOMNode->getChildNodes();
403 for (
unsigned int k = 0; k < dataNodes->getLength(); ++k) {
405 const DOMNode*
const currentNode = dataNodes->item(k);
412 if (currentNode->getNodeType() == DOMNode::TEXT_NODE)
413 dataString +=
AsString(currentNode->getNodeValue());
417 boost::trim(dataString);
435 const DOMNamedNodeMap*
const attributes = fDOMNode->getAttributes();
440 for (
unsigned int j = 0; j < attributes->getLength(); ++j) {
441 const DOMNode*
const attribute = attributes->item(j);
442 const string name =
AsString(attribute->getNodeName());
444 unitString =
AsString(attribute->getNodeValue());
451 if (!unitString.empty()) {
453 unit = up.Evaluate(unitString);
469 const DOMNamedNodeMap*
const attributes = fDOMNode->getAttributes();
471 vector<string> variables;
476 for (
unsigned int i = 0; i < attributes->getLength(); ++i) {
477 const DOMNode*
const attr = attributes->item(i);
478 const string nodeName =
AsString(attr->getNodeName());
480 const string s =
AsString(attr->getNodeValue());
484 variables.push_back(word);
533 ERROR(
"This method requires user to call free() after "
534 "done with the char*! Disabled for the moment.");
545 time = boost::lexical_cast<
UTCDateTime>(GetDataString()).GetTimeStamp();
559 func =
Function(GetDataString(), GetListOfVariables());
569 const string dataString = GetDataString();
570 istringstream iss(dataString);
573 vt.push_back(boost::lexical_cast<UTCDateTime>(word).GetTimeStamp());
585 const Reader r(readerInput);
601 DOMImplementationLS*
const impl =
602 DOMImplementationRegistry::getDOMImplementation(
607 XercesPtrC dom(XMLString::transcode(serializer->writeToString(fDOMNode)));
608 const string res(dom.
Get());
612 MemBufFormatTarget memForm;
613 writer->writeNode(&memForm, *fDOMNode);
614 return string((
const char*)memForm.getRawBuffer());
623 const vector<double> x = GetChild(
"x").Get<vector<double>>();
624 vector<double> y = GetChild(
"y").Get<vector<double>>();
625 Branch scaleYB = GetChild(
"scaleY");
627 const double s = scaleYB.Get<
double>();
628 transform(y.begin(), y.end(), y.begin(), [&
s](
const auto& elem) {
return elem *
s; });
631 for (
unsigned int i = 0, n = x.size(); i < n; ++i)
636 #define UTL_BRANCH_GETDATA_WITH_CAST_ONLY(_Type_...) \
638 Branch::GetData(_Type_& t) \
650 #undef UTL_BRANCH_GETDATA_WITH_CAST_ONLY
Branch GetTopBranch() const
void SetWarning(const std::string &wrn)
std::string AsString(const XMLCh *const xStr)
std::string String() const
Dump the branch into a string.
Class to hold collection (x,y) points and provide interpolation between them.
std::map< std::string, std::string > AttributeMap
std::vector< std::string > GetListOfVariables() const
Get the list of variables of a function.
void PushBack(const double x, const double y)
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Exception for errors encountered when parsing XML.
bool StringEquivalent(const std::string &a, const std::string &b, Predicate p)
Utility to compare strings for equivalence. It takes a predicate to determine the equivalence of indi...
A TimeStamp holds GPS second and nanosecond for some event.
Branch GetTopBranch() const
Get the top Branch (represents same entity as document node)
AttributeMap GetAttributes() const
Get a map<string, string> containing all the attributes of this Branch.
Branch GetNextSibling() const
Get next sibling of this branch.
Branch & operator=(const Branch &b)
Utility for parsing XML files.
Class representing a document branch.
xercesc::DOMNode * fDOMNode
unsigned int GetNChildren() const
void ZeroBranchCheck() const
#define WARNING(message)
Macro for logging warning messages.
void GetData(bool &b) const
Overloads of the GetData member template function.
std::string GetName() const
function to get the Branch name
Evaluate functions given in a string. The real work is done by the ExpressionParser class...
std::string GetDataString() const
function to get the data inside an element as one big string
Branch Clone() const
returns a clone of this branch.
XercesPtr< XMLCh > XercesPtrX
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
Branch GetFirstChild() const
Get first child of this Branch.
Branch GetPreviousSibling() const
Get previous sibling of this branch.
Branch GetSibling(const std::string &childName) const
Get sibling by name.
boost::shared_ptr< BranchOwner > fOwner
#define ERROR(message)
Macro for logging error messages.
#define UTL_BRANCH_GETDATA_WITH_CAST_ONLY(_Type_...)
double GetUnit() const
Get the unit of the token.