3 #include <boost/lexical_cast.hpp>
4 #include <boost/filesystem.hpp>
5 #include <boost/algorithm/string.hpp>
6 #include <libxml++/libxml++.h>
10 using namespace boost;
18 cxml::Node::Node (xmlpp::Node const * node)
24 shared_ptr<cxml::Node>
25 cxml::Node::node_child (string name)
27 list<shared_ptr<cxml::Node> > n = node_children (name);
29 throw cxml::Error ("duplicate XML tag " + name);
30 } else if (n.empty ()) {
31 throw cxml::Error ("missing XML tag " + name + " in " + _node->get_name());
37 list<shared_ptr<cxml::Node> >
38 cxml::Node::node_children (string name)
40 /* XXX: using find / get_path should work here, but I can't follow
44 xmlpp::Node::NodeList c = _node->get_children ();
46 list<shared_ptr<cxml::Node> > n;
47 for (xmlpp::Node::NodeList::iterator i = c.begin (); i != c.end(); ++i) {
48 if ((*i)->get_name() == name) {
49 n.push_back (shared_ptr<Node> (new Node (*i)));
53 _taken.push_back (name);
58 cxml::Node::string_child (string c)
60 return node_child(c)->content ();
64 cxml::Node::optional_string_child (string c)
66 list<shared_ptr<Node> > nodes = node_children (c);
67 if (nodes.size() > 1) {
68 throw cxml::Error ("duplicate XML tag " + c);
72 return optional<string> ();
75 return nodes.front()->content();
79 cxml::Node::bool_child (string c)
81 string const s = string_child (c);
82 return (s == "1" || s == "yes");
86 cxml::Node::optional_bool_child (string c)
88 optional<string> s = optional_string_child (c);
90 return optional<bool> ();
93 return (s.get() == "1" || s.get() == "yes");
97 cxml::Node::ignore_child (string name)
99 _taken.push_back (name);
103 cxml::Node::string_attribute (string name)
105 xmlpp::Element const * e = dynamic_cast<const xmlpp::Element *> (_node);
107 throw cxml::Error ("missing attribute");
110 xmlpp::Attribute* a = e->get_attribute (name);
112 throw cxml::Error ("missing attribute");
115 return a->get_value ();
119 cxml::Node::optional_string_attribute (string name)
121 xmlpp::Element const * e = dynamic_cast<const xmlpp::Element *> (_node);
123 return optional<string> ();
126 xmlpp::Attribute* a = e->get_attribute (name);
128 return optional<string> ();
131 return string (a->get_value ());
135 cxml::Node::bool_attribute (string name)
137 string const s = string_attribute (name);
138 return (s == "1" || s == "yes");
142 cxml::Node::optional_bool_attribute (string name)
144 optional<string> s = optional_string_attribute (name);
146 return optional<bool> ();
149 return (s.get() == "1" || s.get() == "yes");
155 xmlpp::Node::NodeList c = _node->get_children ();
156 for (xmlpp::Node::NodeList::iterator i = c.begin(); i != c.end(); ++i) {
157 if (dynamic_cast<xmlpp::Element *> (*i) && find (_taken.begin(), _taken.end(), (*i)->get_name()) == _taken.end ()) {
158 throw cxml::Error ("unexpected XML node " + (*i)->get_name());
164 cxml::Node::content ()
168 xmlpp::Node::NodeList c = _node->get_children ();
169 for (xmlpp::Node::NodeList::const_iterator i = c.begin(); i != c.end(); ++i) {
170 xmlpp::ContentNode const * v = dynamic_cast<xmlpp::ContentNode const *> (*i);
172 content += v->get_content ();
179 cxml::File::File (string file, string root_name)
181 if (!filesystem::exists (file)) {
182 throw cxml::Error ("XML file does not exist");
185 _parser = new xmlpp::DomParser;
186 _parser->parse_file (file);
188 throw cxml::Error ("could not parse XML");
191 _node = _parser->get_document()->get_root_node ();
192 if (_node->get_name() != root_name) {
193 throw cxml::Error ("unrecognised root node");