#include <iostream>
#include <boost/lexical_cast.hpp>
#include <boost/filesystem.hpp>
+#include <boost/algorithm/string.hpp>
#include <libxml++/libxml++.h>
#include "xml.h"
#include "exceptions.h"
}
xmlpp::Node *
-XMLNode::xml_node (string name)
+XMLNode::node_child (string name)
{
- list<xmlpp::Node*> n = xml_nodes (name);
+ list<xmlpp::Node*> n = node_children (name);
if (n.size() > 1) {
throw XMLError ("duplicate XML tag " + name);
} else if (n.empty ()) {
- throw XMLError ("missing XML tag " + name);
+ throw XMLError ("missing XML tag " + name + " in " + _node->get_name());
}
return n.front ();
}
list<xmlpp::Node*>
-XMLNode::xml_nodes (string name)
+XMLNode::node_children (string name)
{
/* XXX: using find / get_path should work here, but I can't follow
how get_path works.
}
string
-XMLNode::string_node (string name)
+XMLNode::string_child (string name)
{
- xmlpp::Node* node = xml_node (name);
-
- xmlpp::Node::NodeList c = node->get_children ();
- if (c.size() != 1) {
- throw XMLError ("unexpected content in XML node");
- }
-
- xmlpp::ContentNode const * v = dynamic_cast<xmlpp::ContentNode const *> (c.front());
- if (!v) {
- throw XMLError ("missing content in XML node");
- }
-
- return v->get_content ();
+ return XMLNode (node_child (name)).content ();
}
string
-XMLNode::optional_string_node (string name)
+XMLNode::optional_string_child (string name)
{
- list<xmlpp::Node*> nodes = xml_nodes (name);
+ list<xmlpp::Node*> nodes = node_children (name);
if (nodes.size() > 2) {
throw XMLError ("duplicate XML tag " + name);
}
return "";
}
- return string_node (name);
+ return string_child (name);
}
ContentKind
-XMLNode::kind_node (string name)
+XMLNode::kind_child (string name)
{
- return content_kind_from_string (string_node (name));
+ return content_kind_from_string (string_child (name));
}
Fraction
-XMLNode::fraction_node (string name)
+XMLNode::fraction_child (string name)
{
- return Fraction (string_node (name));
+ return Fraction (string_child (name));
}
int64_t
-XMLNode::int64_node (string name)
+XMLNode::int64_child (string name)
+{
+ string s = string_child (name);
+ erase_all (s, " ");
+ return lexical_cast<int64_t> (s);
+}
+
+int64_t
+XMLNode::optional_int64_child (string name)
+{
+ list<xmlpp::Node*> nodes = node_children (name);
+ if (nodes.size() > 2) {
+ throw XMLError ("duplicate XML tag " + name);
+ }
+
+ if (nodes.empty ()) {
+ return 0;
+ }
+
+ return int64_child (name);
+}
+
+float
+XMLNode::float_child (string name)
{
- return lexical_cast<int64_t> (string_node (name));
+ return lexical_cast<float> (string_child (name));
}
void
-XMLNode::ignore_node (string name)
+XMLNode::ignore_child (string name)
{
_taken.push_back (name);
}
+Time
+XMLNode::time_attribute (string name)
+{
+ return Time (string_attribute (name));
+}
+
+string
+XMLNode::string_attribute (string name)
+{
+ xmlpp::Element const * e = dynamic_cast<const xmlpp::Element *> (_node);
+ if (!e) {
+ throw XMLError ("missing attribute");
+ }
+
+ xmlpp::Attribute* a = e->get_attribute (name);
+ if (!a) {
+ throw XMLError ("missing attribute");
+ }
+
+ return a->get_value ();
+}
+
+string
+XMLNode::optional_string_attribute (string name)
+{
+ xmlpp::Element const * e = dynamic_cast<const xmlpp::Element *> (_node);
+ if (!e) {
+ return "";
+ }
+
+ xmlpp::Attribute* a = e->get_attribute (name);
+ if (!a) {
+ return "";
+ }
+
+ return a->get_value ();
+}
+
+float
+XMLNode::float_attribute (string name)
+{
+ return lexical_cast<float> (string_attribute (name));
+}
+
+int64_t
+XMLNode::int64_attribute (string name)
+{
+ return lexical_cast<int64_t> (string_attribute (name));
+}
+
+int64_t
+XMLNode::optional_int64_attribute (string name)
+{
+ string const s = optional_string_attribute (name);
+ if (s.empty ()) {
+ return 0;
+ }
+
+ return lexical_cast<int64_t> (s);
+}
+
+optional<bool>
+XMLNode::optional_bool_attribute (string name)
+{
+ string const s = optional_string_attribute (name);
+ if (s.empty ()) {
+ return optional<bool> ();
+ }
+
+ if (s == "1" || s == "yes") {
+ return optional<bool> (true);
+ }
+
+ return optional<bool> (false);
+}
+
+optional<Color>
+XMLNode::optional_color_attribute (string name)
+{
+ string const s = optional_string_attribute (name);
+ if (s.empty ()) {
+ return optional<Color> ();
+ }
+
+ return optional<Color> (Color (s));
+}
+
void
XMLNode::done ()
{
}
}
+string
+XMLNode::content ()
+{
+ string content;
+
+ xmlpp::Node::NodeList c = _node->get_children ();
+ for (xmlpp::Node::NodeList::const_iterator i = c.begin(); i != c.end(); ++i) {
+ xmlpp::ContentNode const * v = dynamic_cast<xmlpp::ContentNode const *> (*i);
+ if (v) {
+ content += v->get_content ();
+ }
+ }
+
+ return content;
+}
+
XMLFile::XMLFile (string file, string root_name)
{
if (!filesystem::exists (file)) {