40#include <snapdev/not_reached.h>
41#include <snapdev/trim_string.h>
42#include <snapdev/string_replace_many.h>
52#include <snapdev/poison.h>
61node::node(std::string
const & name)
68 + snapdev::string_replace_many(name, {{std::string(
"\0", 1),
"\\0"}})
69 +
"\" is not a valid token for a tag name.");
74std::string
const & node::tag_name()
const
80std::string node::text(
bool trim)
const
84 return snapdev::trim_string(f_text);
90void node::set_text(std::string
const & text)
96void node::append_text(std::string
const & text)
102node::attribute_map_t node::all_attributes()
const
108std::string node::attribute(std::string
const & name)
const
110 auto const it(f_attributes.find(name));
111 if(it == f_attributes.end())
113 return std::string();
119void node::set_attribute(std::string
const & name, std::string
const & value)
123 throw invalid_token(
"\"" + name +
"\" is not a valid token for an attribute name.");
125 f_attributes[name] = value;
129void node::append_child(pointer_t n)
131 if(n->f_next !=
nullptr
132 || n->f_previous.lock() !=
nullptr
133 || n->f_parent.lock() !=
nullptr)
135 throw node_already_in_tree(
"Somehow you are trying to add a child node of a node that was already added to a tree of nodes.");
139 throw node_is_root(
"Trying to append the root node within the sub-tree.");
142 auto l(last_child());
153 n->f_parent = shared_from_this();
157node::pointer_t node::root()
const
159 node::pointer_t result(
const_cast<node *
>(
this)->shared_from_this());
162 node::pointer_t p(result->parent());
169 snapdev::NOT_REACHED();
173node::pointer_t node::parent()
const
175 auto result(f_parent.lock());
180node::pointer_t node::first_child()
const
186node::pointer_t node::last_child()
const
188 if(f_child ==
nullptr)
190 return node::pointer_t();
193 pointer_t l(f_child);
194 while(l->f_next !=
nullptr)
203node::pointer_t node::next()
const
209node::pointer_t node::previous()
const
211 return f_previous.lock();
215std::string convert_to_entity(std::string
const & raw, std::string
const & which)
218 result.reserve(raw.length() + 10);
219 for(
auto const & c : raw)
221 if(which.find(c) == std::string::npos)
255std::ostream & operator << (std::ostream & out, node
const & n)
259 for(
auto const & a : n.all_attributes())
265 char const quote(a.second.find(
'"') != std::string::npos
266 && a.second.find(
'\'') == std::string::npos ?
'\'' :
'"');
272 ? convert_to_entity(a.second,
"&<>\"")
273 : convert_to_entity(a.second,
"&<>"))
276 auto child(n.first_child());
277 bool empty(child ==
nullptr && n.text().empty() && n.parent() !=
nullptr);
285 while(child !=
nullptr)
288 child = child->next();
291 if(!n.text().empty())
295 out << convert_to_entity(n.text(),
"&<>");
Snap! Database exceptions.
Node for the basic XML tree.
bool is_token(std::string const &token)
Verify that token is a valid string.
Database file implementation.