OpenLB 1.8.1
Loading...
Searching...
No Matches
xmlReader.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2010 Jonas Latt, Jonas Fietz, Mathias Krause
4 * 2024 Dennis Teutscher
5 * E-mail contact: info@openlb.net
6 * The most recent release of OpenLB can be downloaded at
7 * <http://www.openlb.net/>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23*/
24
29#ifndef OLB_IO_XML_READER_H
30#define OLB_IO_XML_READER_H
31
32#include <string>
33#include <vector>
34#include <iostream>
35#include <sstream>
36#include <map>
37#include <typeinfo>
38
39#include <tinyxml2.h>
40
41#include "io/ostreamManager.h"
42#include "xmlReaderOutput.h"
43
44
45namespace olb {
46
47namespace util {
48
49template <class T, unsigned DIM> class ADf;
50
51}
52
53class XMLreader {
54private:
55 friend class XMLreaderOutput;
56
57public:
62 XMLreader(tinyxml2::XMLNode* pParent, OutputChannel outputChannel = OutputChannel::ERRCHANNEL);
64 XMLreader( const std::string& fName, OutputChannel outputChannel = OutputChannel::ERRCHANNEL);
65 ~XMLreader();
71 //bool read(bool& value, bool verbose = true) const;
72 template <typename T> bool read(T& value, bool verboseOn = true, bool exitIfMissing=false) const;
73 template <typename T,unsigned DIM> bool read(util::ADf<T,DIM>& value, bool verboseOn = true, bool exitIfMissing=false) const;
74 template <typename T> bool read(std::vector<T>& value, bool verboseOn = true, bool exitIfMissing=false) const;
75 template <typename T> T get(bool verboseOn = true, bool exitIfMissing=false) const;
78 template<typename ParameterType>
79 bool readOrWarn(std::string name_parameter_1,
80 std::string name_parameter_2, std::string name_parameter_3,
81 ParameterType& var, bool defaultAvailable = true, bool exitIfMissing = false, bool showWarning = true) const;
83 template<typename ParameterType>
84 bool readOrWarn(std::string name_parameter_1,
85 std::string name_parameter_2, std::string name_parameter_3, std::string name_parameter_4,
86 ParameterType& var, bool defaultAvailable = true, bool exitIfMissing = false, bool showWarning = true) const;
88 XMLreader const& operator[] (std::string name) const;
93 std::vector<XMLreader*>::const_iterator begin() const;
98 std::vector<XMLreader*>::const_iterator end() const;
100 void setWarningsOn(bool warnings) const;
102 std::string getName() const;
104 std::string getText() const;
106 std::string getAttribute(const std::string& aName) const;
107
110
111private:
112 void mainProcessorIni(tinyxml2::XMLNode* pParent);
113 XMLreader();
114
115private:
116 OutputChannel _outputChannel;
117 mutable bool _warningsOn;
118 std::string _text;
119 std::string _name;
120 static XMLreader _notFound;
121
122protected:
123 std::map<std::string, std::string> _attributes;
124 std::vector<XMLreader*> _children;
125
126};
127
128// methods with template
129
130template <typename T, unsigned DIM>
131bool XMLreader::read(util::ADf<T,DIM>& value, bool verboseOn, bool exitIfMissing) const
132{
133 std::stringstream valueStr(_text);
134 T tmp = T();
135 if (!(valueStr >> tmp)) {
136 //if ( _verboseOn ) {
137 //clout << std::string("Error: cannot read value from XML element ") << _name << std::endl;
138 //}
139 _output.printWarning(_name, "ADf vector", "", verboseOn, exitIfMissing);
140 return false;
141 }
142 value = util::ADf<T,DIM>(tmp);
143 return true;
144}
145
146template <typename T>
147bool XMLreader::read(std::vector<T>& values, bool verboseOn, bool exitIfMissing ) const
148{
149 std::stringstream multiValueStr(_text);
150 std::string word;
151 std::vector<T> tmp(values);
152 while (multiValueStr>>word) {
153 std::stringstream valueStr(word);
154 T value;
155 if (!(valueStr >> value)) {
156// if ( verboseOn ) {
157// clout << std::string("Error: cannot read value array from XML element ") << _name << std::endl;
158// }
159 _output.printWarning(_name, "std::vector", "", verboseOn, exitIfMissing);
160 return false;
161 }
162 tmp.push_back(value);
163 }
164 values.swap(tmp);
165 return true;
166}
167
168template <typename T>
169T XMLreader::get(bool verboseOn, bool exitIfMissing) const
170{
171 std::stringstream valueStr(_text);
172 T tmp = T();
173 if (!(valueStr >> tmp)) {
174// if ( verboseOn ) {
175// clout << "Error: cannot read value from XML element " << _name << std::endl;
176// }
177 _output.printWarning(_name, typeid(T).name(), "", verboseOn, exitIfMissing);
178 }
179 return tmp;
180}
181
182template<typename ParameterType>
183bool XMLreader::readOrWarn(std::string name_parameter_1,
184 std::string name_parameter_2, std::string name_parameter_3,
185 ParameterType& var, bool defaultAvailable, bool exitIfMissing, bool showWarning) const
186{
187 // deactivate default warnings and show default values instead
188 setWarningsOn(false);
189 if (name_parameter_3 == "") {
190 if (!(*this)[name_parameter_1][name_parameter_2].read<ParameterType>(var, false)) {
191 _output.parameterReading({name_parameter_1, name_parameter_2}, var, defaultAvailable, exitIfMissing, showWarning);
192 return false;
193 }
194 return true;
195 }
196 else{
197 if (!(*this)[name_parameter_1][name_parameter_2][name_parameter_3].read<ParameterType>(var, false)) {
198 _output.parameterReading({name_parameter_1, name_parameter_2, name_parameter_3}, var, defaultAvailable, exitIfMissing, showWarning);
199 return false;
200 }
201 return true;
202 }
203 // turn default warnings on again
204 setWarningsOn(true);
205}
206
207template<typename ParameterType>
208bool XMLreader::readOrWarn(std::string name_parameter_1,
209 std::string name_parameter_2, std::string name_parameter_3, std::string name_parameter_4,
210 ParameterType& var, bool defaultAvailable, bool exitIfMissing, bool showWarning) const
211{
212 // deactivate default warnings and show default values instead
213 setWarningsOn(false);
214 if (name_parameter_3 == "") {
215 if (!(*this)[name_parameter_1][name_parameter_2].read<ParameterType>(var, false)) {
216 _output.parameterReading({name_parameter_1, name_parameter_2}, var, defaultAvailable, exitIfMissing, showWarning);
217 return false;
218 }
219 return true;
220 }
221 else if(name_parameter_4 == ""){
222 if (!(*this)[name_parameter_1][name_parameter_2][name_parameter_3].read<ParameterType>(var, false)) {
223 _output.parameterReading({name_parameter_1, name_parameter_2, name_parameter_3}, var, defaultAvailable, exitIfMissing, showWarning);
224 return false;
225 }
226 return true;
227 }
228 else {
229 if (!(*this)[name_parameter_1][name_parameter_2][name_parameter_3][name_parameter_4].read<ParameterType>(var, false)) {
230 _output.parameterReading({name_parameter_1, name_parameter_2,name_parameter_3,name_parameter_4},
231 var, defaultAvailable, exitIfMissing, showWarning);
232 return false;
233 }
234 return true;
235 }
236 // turn default warnings on again
237 setWarningsOn(true);
238}
239
240XMLreader XMLreader::_notFound;
241
242XMLreader::XMLreader()
243{
244 _name = "XML node not found";
245 _warningsOn = true;
247}
248
249XMLreader::XMLreader( tinyxml2::XMLNode* pParent, OutputChannel outputChannel) : _output(outputChannel)
250{
251 _outputChannel = outputChannel;
252 _warningsOn = true;
253
254 mainProcessorIni(pParent);
255}
256
257XMLreader::XMLreader(const std::string& fName, OutputChannel outputChannel)
258 : _output(outputChannel), _outputChannel(outputChannel), _warningsOn(true)
259{
260 tinyxml2::XMLDocument doc(true, tinyxml2::COLLAPSE_WHITESPACE); // Create an instance of TinyXML2's XMLDocument
261 bool loadOK = (doc.LoadFile(fName.c_str()) == tinyxml2::XML_SUCCESS); // Load the XML file and check for success
262 _output.loadFile(loadOK, fName); // Call the output's loadFile method
263 mainProcessorIni(&doc);
264}
265
267{
268 for (unsigned int iNode=0; iNode<_children.size(); ++iNode) {
269 delete _children[iNode];
270 }
271}
272
273void XMLreader::mainProcessorIni(tinyxml2::XMLNode* pParent)
274{
275 OstreamManager clout("mainProcessorIni");
276 assert(pParent != nullptr); // Ensure pParent is not null
277 // Check if the parent is a document or element
278 tinyxml2::XMLElement* element = pParent->ToElement();
279 if (element == nullptr && pParent->ToDocument() == nullptr) {
280 // If neither, return or handle the error
281 return; // Handle accordingly
282 }
283
284 if (pParent->ToDocument() != nullptr) {
285 // Ignore the surrounding PARAM-block by getting the first child element
286 element = pParent->FirstChildElement();
287 if (element == nullptr) return; // Safety check
288 }
289
290 _name = element->Name(); // Get the name of the element
291
292 // Process attributes
293 const tinyxml2::XMLAttribute* attr = element->FirstAttribute();
294 while (attr != nullptr) {
295 _attributes[attr->Name()] = attr->Value(); // Store attribute name and value
296 attr = attr->Next();
297 }
298
299
300 // Process child nodes
301 for (tinyxml2::XMLNode* pChild = element->FirstChild(); pChild != nullptr; pChild = pChild->NextSibling()) {
302 if (pChild->ToElement()) { // Check if the child is an element
303 _children.push_back(new XMLreader(pChild->ToElement(), _outputChannel));
304 }
305 else if (pChild->ToText()) { // Check if the child is text
306 _text = pChild->ToText()->Value();
307 }
308 }
309}
310
311XMLreader const& XMLreader::operator[] (std::string fName) const
312{
313 for (unsigned int iNode=0; iNode<_children.size(); ++iNode) {
314 if (_children[iNode]->_name == fName) {
315 return *_children[iNode];
316 }
317 }
318 _output.readValue(_warningsOn, _name, fName);
319 return _notFound;
320}
321
322std::vector<XMLreader*>::const_iterator XMLreader::begin() const
323{
324 return _children.begin();
325}
326
327std::vector<XMLreader*>::const_iterator XMLreader::end() const
328{
329 return _children.end();
330}
331
332std::string XMLreader::getName() const
333{
334 return _name;
335}
336
337std::string XMLreader::getText() const
338{
339 return _text;
340}
341
342void XMLreader::setWarningsOn(bool warnings) const
343{
344 _warningsOn = warnings;
345 for (unsigned int iNode=0; iNode<_children.size(); ++iNode) {
346 _children[iNode]->setWarningsOn(warnings);
347 }
348}
349
350// templatde specialization for T=bool
351template <>
352bool XMLreader::read<bool>(bool& value, bool verboseOn, bool exitIfMissing) const
353{
354 std::stringstream valueStr(_text);
355 std::string word;
356 valueStr >> word;
357 // Transform to lower-case, so that "true" and "false" are case-insensitive.
358 std::transform(word.begin(), word.end(), word.begin(), ::tolower);
359 if (!word.compare("true") || (word=="1")) {
360 value = true;
361 return true;
362 }
363 else if (!word.compare("false") || (word=="0")) {
364 value=false;
365 return true;
366 }
367 else {
368 if ( verboseOn ) {
369 std::stringstream ss;
370 ss << ( value ? "true" : "false" );
371 _output.printWarning(_name, "bool", ss.str(), verboseOn, exitIfMissing);
372 }
373 }
374 return false;
375}
376
377// template specialization for T=int
378template <>
379bool XMLreader::read<int>(int& value, bool verboseOn, bool exitIfMissing) const
380{
381 std::stringstream valueStr(_text);
382 int tmp = int();
383 if (!(valueStr >> tmp)) {
384 std::stringstream ss;
385 ss << value;
386 _output.printWarning(_name, "int", ss.str(), verboseOn, exitIfMissing);
387 return false;
388 }
389 value = tmp;
390 return true;
391}
392
393// template specialization for T=std::size_t
394template <>
395bool XMLreader::read<std::size_t>(std::size_t& value, bool verboseOn, bool exitIfMissing) const
396{
397 std::stringstream valueStr(_text);
398 std::size_t tmp = std::size_t();
399 if (!(valueStr >> tmp)) {
400 std::stringstream ss;
401 ss << value;
402 _output.printWarning(_name, "std::size_t", ss.str(), verboseOn, exitIfMissing);
403 return false;
404 }
405 value = tmp;
406 return true;
407}
408
409// template specialization for T=double
410template <>
411bool XMLreader::read<double>(double& value, bool verboseOn, bool exitIfMissing) const
412{
413 std::stringstream valueStr(_text);
414 double tmp = double();
415 if (!(valueStr >> tmp)) {
416 _output.printWarning(_name, "double", std::to_string(value), verboseOn, exitIfMissing);
417 return false;
418 }
419 value = tmp;
420 return true;
421}
422
423// template specialization for T=long double
424template <>
425bool XMLreader::read<long double>(long double& value, bool verboseOn, bool exitIfMissing) const
426{
427 std::stringstream valueStr(_text);
428 std::string tmp {};
429 if (!(valueStr >> tmp)) {
430 _output.printWarning(_name, "long double", std::to_string(value), verboseOn, exitIfMissing);
431 return false;
432 }
433 value = std::stold(tmp);
434 return true;
435}
436
437template <>
438bool XMLreader::read<float>(float& value, bool verboseOn, bool exitIfMissing) const
439{
440 std::stringstream valueStr(_text);
441 float tmp = float();
442 if (!(valueStr >> tmp)) {
443 std::stringstream ss;
444 ss << value;
445 _output.printWarning(_name, "float", ss.str(), verboseOn, exitIfMissing);
446 return false;
447 }
448 value = tmp;
449 return true;
450}
451
452template <>
453bool XMLreader::read<std::string>(std::string& entry, bool verboseOn, bool exitIfMissing) const
454{
455 if (_name == "XML node not found") {
456 return false;
457 }
458 std::stringstream valueStr(_text);
459 std::string tmp = std::string();
460 if (!(valueStr >> tmp)) {
461 std::stringstream ss;
462 ss << entry;
463 _output.printWarning(_name, "string", ss.str(), verboseOn, exitIfMissing);
464 return false;
465 }
466
467 entry = _text;
468 return true;
469}
470
471std::string XMLreader::getAttribute(const std::string& aName) const
472{
473 std::map<std::string, std::string>::const_iterator it = _attributes.find(aName);
474 if ( it == _attributes.end()) {
475 return "Attribute not found.";
476 }
477 return it->second;
478}
479
481template<typename S>
482std::vector<S> getDataFromTag(const XMLreader& reader, std::string attrName, int nData)
483{
484 std::vector<S> values(nData, S());
485 std::stringstream extstr(reader.getAttribute(attrName));
486 for (auto& valueI: values) {
487 extstr >> valueI;
488 }
489 return values;
490}
491
492
493
494}
495
496#endif // OLB_IO_XML_READER_H
class for marking output with some text
void loadFile(bool loadOK, std::string fName) const
void parameterReading(std::vector< std::string > parameters, ParameterType &var, bool defaultAvailable, bool exitIfMissing, bool showWarning) const
void printWarning(std::string name, std::string typeName, std::string value, bool verboseOn, bool exitIfMissing) const
print warning if verbose mode is on and exit, if exItMissing is true
void readValue(bool warningsOn, std::string name, std::string fName) const
std::string getAttribute(const std::string &aName) const
Definition xmlReader.h:471
std::vector< XMLreader * > _children
Definition xmlReader.h:124
friend class XMLreaderOutput
Definition xmlReader.h:55
std::vector< XMLreader * >::const_iterator begin() const
Returns an iterator.begin() of the child XMLreader This means an iterator to the next level on an XML...
Definition xmlReader.h:322
std::string getName() const
return the name of the element
Definition xmlReader.h:332
T get(bool verboseOn=true, bool exitIfMissing=false) const
Definition xmlReader.h:169
XMLreaderOutput _output
handling all the output for the XMLreader
Definition xmlReader.h:109
bool readOrWarn(std::string name_parameter_1, std::string name_parameter_2, std::string name_parameter_3, ParameterType &var, bool defaultAvailable=true, bool exitIfMissing=false, bool showWarning=true) const
This wrapper function reads the given parameter from the "type_parameter" and "name_parameter_1" or "...
Definition xmlReader.h:183
void setWarningsOn(bool warnings) const
switch warnings on/off
Definition xmlReader.h:342
std::vector< XMLreader * >::const_iterator end() const
Returns an iterator.end() of the child XMLreader This means an iterator to the next level on an XML t...
Definition xmlReader.h:327
bool read(T &value, bool verboseOn=true, bool exitIfMissing=false) const
Read a value from the xml file.
XMLreader const & operator[](std::string name) const
Definition xmlReader.h:311
XMLreader(tinyxml2::XMLNode *pParent, OutputChannel outputChannel=OutputChannel::ERRCHANNEL)
Constructs a new XMLreader from another XMLreader.
Definition xmlReader.h:249
std::map< std::string, std::string > _attributes
Definition xmlReader.h:123
std::string getText() const
return the text of the element
Definition xmlReader.h:337
Definition of a description of a algoritmic differentiation data type using the forward method.
Top level namespace for all of OpenLB.
std::vector< S > getDataFromTag(const XMLreader &reader, std::string attrName, int nData)
Helper Function to retrieve nData-dimensional std::vector of type S from space separated tag.
Definition xmlReader.h:482