diff options
| author | Carl Hetherington <cth@carlh.net> | 2012-07-30 23:47:57 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2012-07-30 23:47:57 +0100 |
| commit | 9a9d4e014c16be88d72914a9480343445bc785a5 (patch) | |
| tree | 1857fcdd8963d51ac50f1467d9ae81d4d9be5f8e /src/xml.cc | |
| parent | 34a25d89b16a33b5f619ae0eaaa03c17f93980af (diff) | |
Various.
Diffstat (limited to 'src/xml.cc')
| -rw-r--r-- | src/xml.cc | 151 |
1 files changed, 131 insertions, 20 deletions
@@ -1,34 +1,145 @@ +#include <sstream> +#include <iostream> +#include <boost/lexical_cast.hpp> +#include <libxml++/libxml++.h> #include "xml.h" +#include "exceptions.h" +#include "util.h" -XMLFile::XMLFile (string file, string root_id) +using namespace std; +using namespace boost; +using namespace libdcp; + +XMLNode::XMLNode () + : _node (0) { - xmlpp::DomParser parser; - parser.parse_file (file); - if (!parser) { - throw XMLError ("could not parse XML"); + +} + +XMLNode::XMLNode (xmlpp::Node const * node) + : _node (node) +{ + +} + +xmlpp::Node * +XMLNode::xml_node (string name) +{ + list<xmlpp::Node*> n = xml_nodes (name); + if (n.size() > 1) { + throw XMLError ("duplicate XML tag " + name); + } else if (n.empty ()) { + throw XMLError ("missing XML tag " + name); } + + return n.front (); +} - _root = parser.get_document()->get_root_node (); - if (_root->get_name() != root_id) { - throw XMLError ("unrecognised root node"); +list<xmlpp::Node*> +XMLNode::xml_nodes (string name) +{ + /* XXX: using find / get_path should work here, but I can't follow + how get_path works. + */ + + xmlpp::Node::NodeList c = _node->get_children (); + + list<xmlpp::Node*> n; + for (xmlpp::Node::NodeList::iterator i = c.begin (); i != c.end(); ++i) { + if ((*i)->get_name() == name) { + n.push_back (*i); + } + } + + _taken.push_back (name); + return n; +} + +string +XMLNode::string_node (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 (); } string -XMLFile::string_tag (string id) +XMLNode::optional_string_node (string name) +{ + list<xmlpp::Node*> nodes = xml_nodes (name); + if (nodes.size() > 2) { + throw XMLError ("duplicate XML tag " + name); + } + + if (nodes.empty ()) { + return ""; + } + + return string_node (name); +} + +ContentKind +XMLNode::kind_node (string name) +{ + return content_kind_from_string (string_node (name)); +} + +Fraction +XMLNode::fraction_node (string name) +{ + return Fraction (string_node (name)); +} + +int +XMLNode::int_node (string name) +{ + return lexical_cast<int> (string_node (name)); +} + +void +XMLNode::ignore_node (string name) +{ + _taken.push_back (name); +} + +void +XMLNode::done () +{ + xmlpp::Node::NodeList c = _node->get_children (); + for (xmlpp::Node::NodeList::iterator i = c.begin(); i != c.end(); ++i) { + if (dynamic_cast<xmlpp::Element *> (*i) && find (_taken.begin(), _taken.end(), (*i)->get_name()) == _taken.end ()) { + throw XMLError ("unexpected XML node " + (*i)->get_name()); + } + } +} + +XMLFile::XMLFile (string file, string root_name) { - stringstream x; - x << _root->get_name() << "/" << id; - xmlpp::NodeSet n = _root->find (x.str ()); - if (n.empty ()) { - throw XMLError ("missing XML tag"); - } else if (n.size() > 1) { - throw XMLError ("duplicate XML tag"); + _parser = new xmlpp::DomParser; + _parser->parse_file (file); + if (!_parser) { + throw XMLError ("could not parse XML"); + } + + _node = _parser->get_document()->get_root_node (); + if (_node->get_name() != root_name) { + throw XMLError ("unrecognised root node"); } - xml::Node::NodeList c = n.front()->get_children (); - if (c.empty() - + cout << this << " root node is " << _node->get_name() << "\n"; +} - return n.front()->get_name (); +XMLFile::~XMLFile () +{ + delete _parser; } |
