xml_node.cpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi 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 GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 
26 #include "xml_node.hpp"
27 #include "casadi_misc.hpp"
28 
29 namespace casadi {
30 
31 bool XmlNode::has_attribute(const std::string& att_name) const {
32  return this->attributes.find(att_name) != this->attributes.end();
33 }
34 
35 bool XmlNode::has_child(const std::string& childname) const {
36  // Linear search over the elements
37  for (auto& c : this->children) {
38  if (c.name == childname) return true;
39  }
40  // Not found
41  return false;
42 }
43 
44 XmlNode& XmlNode::operator[](const std::string& childname) {
45  // Linear search over the elements
46  auto it = this->children.begin();
47  for (; it != this->children.end(); ++it) {
48  if (it->name == childname) break;
49  }
50  // Check that the child was indeed found
51  casadi_assert(it != this->children.end(), "Could not find " + childname);
52  // Return a reference to the child
53  return *it;
54 }
55 
56 const XmlNode& XmlNode::operator[](const std::string& childname) const {
57  return const_cast<XmlNode*>(this)->operator[](childname); // NOLINT
58 }
59 
60 void XmlNode::set_attribute(const std::string& attribute_name, const std::string& attribute) {
61  this->attributes[attribute_name] = attribute;
62 }
63 
64 void XmlNode::set_attribute(const std::string& att_name, const std::vector<casadi_int>& att) {
65  std::stringstream ss;
66  if (!att.empty()) {
67  ss << att.at(0);
68  for (size_t i = 1; i < att.size(); ++i) ss << " " << att.at(i);
69  }
70  return set_attribute(att_name, ss.str());
71 }
72 
73 void XmlNode::set_attribute(const std::string& att_name, double att) {
74  std::stringstream ss;
75  ss << std::scientific << std::setprecision(std::numeric_limits<double>::digits10 + 1) << att;
76  set_attribute(att_name, ss.str());
77 }
78 
79 std::ostream& operator<<(std::ostream &stream, const XmlNode& node) {
80  node.dump(stream);
81  return stream;
82 }
83 
84 void XmlNode::dump(std::ostream &stream, casadi_int indent) const {
85  // Print name
86  stream << std::string(indent, ' ') << "Node: " << this->name << std::endl;
87 
88  // Print comment
89  if (!this->comment.empty()) {
90  stream << std::string(indent, ' ') << "----- comment starts ----- " << std::endl;
91  stream << this->comment << std::endl;
92  stream << std::string(indent, ' ') << "----- comment ends ----- " << std::endl;
93  }
94 
95  // Print text
96  if (!this->text.empty())
97  stream << std::string(indent+2, ' ') << "Text: " << this->text << std::endl;
98 
99  // Print attributes
100  for (auto it = this->attributes.begin(); it != this->attributes.end(); ++it)
101  stream << std::string(indent+2, ' ') << "attribute " << it->first
102  << " = " << it->second << std::endl;
103 
104  // Print Children
105  for (casadi_int i=0; i < size(); ++i) {
106  stream << std::string(indent, ' ') << "Child " << i << ":" << std::endl;
107  (*this)[i].dump(stream, indent+2);
108  }
109 }
110 
111 void XmlNode::read(const std::string& str, std::string* val) {
112  *val = str;
113 }
114 
115 void XmlNode::read(const std::string& str, bool* val) {
116  if (str == "true") {
117  *val = true;
118  } else if (str == "false") {
119  *val = false;
120  } else {
121  casadi_error("XML argument not 'true' or 'false'");
122  }
123 }
124 
125 void XmlNode::read(const std::string& str, size_t* val) {
126  std::istringstream buffer(str);
127  buffer >> *val;
128 }
129 
130 void XmlNode::read(const std::string& str, casadi_int* val) {
131  std::istringstream buffer(str);
132  buffer >> *val;
133 }
134 
135 void XmlNode::read(const std::string& str, double* val) {
136  std::istringstream buffer(str);
137  buffer >> *val;
138 }
139 
140 void XmlNode::read(const std::string& str, std::vector<casadi_int>* val) {
141  val->clear();
142  std::istringstream buffer(str);
143  while (true) {
144  casadi_int v;
145  buffer >> v;
146  if (buffer.fail()) break;
147  val->push_back(v);
148  }
149 }
150 
151 void XmlNode::read(const std::string& str, std::vector<std::string>* val) {
152  val->clear();
153  std::istringstream buffer(str);
154  while (true) {
155  std::string v;
156  buffer >> v;
157  if (buffer.fail()) break;
158  val->push_back(v);
159  }
160 }
161 
162 std::vector<std::string> XmlNode::child_names() const {
163  std::vector<std::string> ret;
164  ret.reserve(this->children.size());
165  for (auto& c : this->children) ret.push_back(c.name);
166  return ret;
167 }
168 
169 std::vector<std::string> XmlNode::attribute_names() const {
170  std::vector<std::string> ret;
171  ret.reserve(this->attributes.size());
172  for (auto& a : this->attributes) ret.push_back(a.first);
173  return ret;
174 }
175 
176 } // namespace casadi
The casadi namespace.
Definition: archiver.cpp:28
std::ostream & operator<<(std::ostream &stream, const XmlNode &node)
Definition: xml_node.cpp:79
std::string str(const T &v)
String representation, any type.
std::vector< std::string > attribute_names() const
Names of attributes.
Definition: xml_node.cpp:169
void set_attribute(const std::string &att_name, const std::string &att)
Add an attribute.
Definition: xml_node.cpp:60
std::vector< XmlNode > children
Definition: xml_node.hpp:44
std::vector< std::string > child_names() const
Names of children.
Definition: xml_node.cpp:162
T attribute(const std::string &att_name) const
Get an attribute by its name.
Definition: xml_node.hpp:99
bool has_child(const std::string &childname) const
Check if a child is present.
Definition: xml_node.cpp:35
std::string comment
Definition: xml_node.hpp:50
std::string text
Definition: xml_node.hpp:56
bool has_attribute(const std::string &att_name) const
Check if an attribute is present.
Definition: xml_node.cpp:31
std::map< std::string, std::string > attributes
Definition: xml_node.hpp:41
const XmlNode & operator[](size_t i) const
Get a reference to a child by its index.
Definition: xml_node.hpp:130
size_t size() const
Get the number of children.
Definition: xml_node.hpp:155
static void read(const std::string &str, std::string *val)
Read the string value of a string (i.e. copy)
Definition: xml_node.cpp:111
void dump(std::ostream &stream, casadi_int indent=0) const
Dump representation.
Definition: xml_node.cpp:84
std::string name
Definition: xml_node.hpp:47