125 NODE_ELEMENT_END = 2,
143 virtual std::size_t
read(
char* buff, std::size_t buf_size) = 0;
153 std::unique_ptr<std::istream>
input;
158 template <
typename... Args>
161 std::size_t read(
char* buff, std::size_t buf_size)
override;
178 std::size_t read(
char* buff, std::size_t buf_size)
override;
184 template <
typename EnumT>
197 if (case_insensitive) boost::to_lower(value);
198 auto found = values.find(value);
199 if (found == values.end())
201 return found->second;
213 reader(reader), attr_name(attr_name), case_insensitive(!case_sensitive) {}
222 if (case_insensitive) boost::to_lower(key);
224 if (values.find(key) != values.end())
throw XMLException(reader,
"CODE ERROR: Attribute value \"" + key +
"\" already defined.");
226 help += values.empty()?
"\"" :
", \"";
228 if (
min < key.length()) {
229 std::string skey = key.substr(0,
min);
231 if (values.find(skey) != values.end())
throw XMLException(reader,
"CODE ERROR: Attribute value \"" + skey +
"\" already defined.");
234 help += skey; help +=
"["; help += key.substr(
min); help +=
"]";
253 return parse(std::move(*value));
261 EnumT
get(EnumT default_value) {
263 if (!value)
return default_value;
264 return parse(std::move(*value));
280 std::set<std::string> namesAlreadySeen;
289 void operator()(
const std::string& scope, std::string name) {
291 namesAlreadySeen.insert(std::move(name));
301 namesAlreadySeen.insert(std::move(name));
311 typedef std::function<std::string(
const std::string&)>
Filter;
315 static void startTag(
void *data,
const char *element,
const char **attribute);
316 static void endTag(
void *data,
const char *element);
317 static void characterData(
void* data,
const char *
string,
int string_len);
320 std::unique_ptr<DataSource> source;
322 template <
typename RequiredType>
327 template <
typename RequiredType>
332 throw XMLBadAttrException(*
this, attr_name,
attr_str);
351 std::map<std::string, std::string> attributes;
363 State(NodeType type,
unsigned lineNr,
unsigned columnNr,
const std::string& text): lineNr(lineNr), columnNr(columnNr), text(text), type(type) {}
369 bool hasWhiteText() {
370 for (std::size_t i = 0;
i < text.size(); ++
i)
371 if (!isspace(text[i]))
return false;
381 State& appendState(NodeType type,
const std::string& text);
384 std::deque<State> states;
390 std::vector<std::string> path;
393 mutable std::set<std::string> read_attributes;
417 mutable bool check_if_all_attributes_were_read;
423 bool hasCurrent()
const {
424 if (states.empty())
return false;
425 return states.size() > 1 || states.front().type != NODE_TEXT;
431 void ensureHasCurrent()
const {
432 if (!hasCurrent())
throw XMLException(
"XML reader: no current node (missing first read() call?)");
436 const State& getCurrent()
const {
437 return states.front();
445 static bool strToBool(std::string
str) {
446 boost::algorithm::to_lower(
str);
447 if (
str ==
"yes" ||
str ==
"true" ||
str ==
"1")
return true;
448 else if (
str ==
"no" ||
str ==
"false" ||
str ==
"0")
return false;
449 else throw XMLException(
"\"" +
str +
"\" is not valid bool value.");
458 static unsigned strToUnsigned(std::string
str) {
459 int value = boost::lexical_cast<int>(boost::trim_copy(
str));
460 if (value < 0)
throw XMLException(
"negative value given for unsigned");
490 template <
typename...
Args>
506 XMLReader(std::unique_ptr<DataSource>&& source);
512 XMLReader(std::unique_ptr<std::istream>&& istream);
532#if (__cplusplus >= 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X__)
552 XMLReader& operator=(
const XMLReader&) {
return *
this; }
575 unsigned getLineNr()
const { ensureHasCurrent();
return getCurrent().lineNr; }
581 unsigned getColumnNr()
const { ensureHasCurrent();
return getCurrent().columnNr; }
603 const std::vector<std::string>&
getPath()
const {
return path; }
609 std::size_t
getLevel()
const {
return path.size(); }
617 std::size_t
getAttributeCount()
const { ensureHasCurrent();
return getCurrent().attributes.size(); }
623 const std::map<std::string, std::string> getAttributes()
const;
648 template <
typename EnumT>
656 void removeAlienNamespaceAttr();
664 std::string getNodeName()
const;
672 inline std::string
getTagName()
const {
return getNodeName(); }
678 std::string getTextContent()
const;
684 template <
typename T>
696 template <
typename T>
697 inline T
getAttribute(
const std::string& name,
const T& default_value)
const {
702 return default_value;
720 template <
typename T>
733 std::string requireAttribute(
const std::string& attr_name)
const;
742 template <
typename T>
744 return parse<T>(requireAttribute(name), name);
773 void requireTag(
const std::string& name);
780 bool requireTagOrEnd();
788 bool requireTagOrEnd(
const std::string &name);
793 void requireTagEnd();
799 std::string requireText();
805 std::string requireTextInCurrentTag();
811 template <
typename T>
820 template <
typename T>
822 return parse<T>(requireTextInCurrentTag());
837 bool gotoNextTagOnCurrentLevel();
842 void gotoEndOfCurrentTag();