X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fcxml.cc;h=d3ec9e7fd95f6a27efa9a6eeae6543345cc57da9;hb=5532b044b33f40205c3fed2cd3d1c21dd718507b;hp=ddfa00f3d90ff03411f17bd0e9575a76cb031623;hpb=3b6ddf4b140befd1286af26c34800a50b3ba3f56;p=libcxml.git diff --git a/src/cxml.cc b/src/cxml.cc index ddfa00f..d3ec9e7 100644 --- a/src/cxml.cc +++ b/src/cxml.cc @@ -1,13 +1,32 @@ -#include -#include -#include +/* + Copyright (C) 2012-2016 Carl Hetherington + + This file is part of libcxml. + + libcxml is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + libcxml is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libcxml. If not, see . + +*/ + #include #include #include #include "cxml.h" -using namespace std; -using namespace boost; +using std::string; +using std::list; +using boost::shared_ptr; +using boost::optional; cxml::Node::Node () : _node (0) @@ -24,7 +43,9 @@ cxml::Node::Node (xmlpp::Node* node) string cxml::Node::name () const { - assert (_node); + if (!_node) { + throw Error ("No node to read name from"); + } return _node->get_name (); } @@ -37,7 +58,7 @@ cxml::Node::node_child (string name) const } else if (n.empty ()) { throw cxml::Error ("missing XML tag " + name + " in " + _node->get_name()); } - + return n.front (); } @@ -50,20 +71,42 @@ cxml::Node::optional_node_child (string name) const } else if (n.empty ()) { return shared_ptr (); } - + return n.front (); } list > -cxml::Node::node_children (string name) const +cxml::Node::node_children () const { - xmlpp::NodeSet c = _node->find (name); - + if (!_node) { + throw Error ("No node to read children from"); + } + xmlpp::Node::NodeList c = _node->get_children (); + list > n; - for (xmlpp::NodeSet::iterator i = c.begin (); i != c.end(); ++i) { + for (xmlpp::Node::NodeList::iterator i = c.begin (); i != c.end(); ++i) { n.push_back (shared_ptr (new Node (*i))); } - + + return n; +} + +list > +cxml::Node::node_children (string name) const +{ + /* 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 > n; + for (xmlpp::Node::NodeList::iterator i = c.begin (); i != c.end(); ++i) { + if ((*i)->get_name() == name) { + n.push_back (shared_ptr (new Node (*i))); + } + } + _taken.push_back (name); return n; } @@ -93,7 +136,7 @@ bool cxml::Node::bool_child (string c) const { string const s = string_child (c); - return (s == "1" || s == "yes"); + return (s == "1" || s == "yes" || s == "True"); } optional @@ -103,8 +146,8 @@ cxml::Node::optional_bool_child (string c) const if (!s) { return optional (); } - - return (s.get() == "1" || s.get() == "yes"); + + return (s.get() == "1" || s.get() == "yes" || s.get() == "True"); } void @@ -118,12 +161,12 @@ cxml::Node::string_attribute (string name) const { xmlpp::Element const * e = dynamic_cast (_node); if (!e) { - throw cxml::Error ("missing attribute"); + throw cxml::Error ("missing attribute " + name); } - + xmlpp::Attribute* a = e->get_attribute (name); if (!a) { - throw cxml::Error ("missing attribute"); + throw cxml::Error ("missing attribute " + name); } return a->get_value (); @@ -136,7 +179,7 @@ cxml::Node::optional_string_attribute (string name) const if (!e) { return optional (); } - + xmlpp::Attribute* a = e->get_attribute (name); if (!a) { return optional (); @@ -178,11 +221,11 @@ string cxml::Node::content () const { 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 (*i); - if (v) { + if (v && dynamic_cast(v)) { content += v->get_content (); } } @@ -208,26 +251,38 @@ cxml::Document::Document (string root_name) _parser = new xmlpp::DomParser; } +cxml::Document::Document (string root_name, boost::filesystem::path file) + : _root_name (root_name) +{ + _parser = new xmlpp::DomParser (); + read_file (file); +} + +cxml::Document::Document () +{ + _parser = new xmlpp::DomParser (); +} + cxml::Document::~Document () { delete _parser; } void -cxml::Document::read_file (filesystem::path file) +cxml::Document::read_file (boost::filesystem::path file) { - if (!filesystem::exists (file)) { - throw cxml::Error ("XML file does not exist"); + if (!boost::filesystem::exists (file)) { + throw cxml::Error ("XML file " + file.string() + " does not exist"); } - + _parser->parse_file (file.string ()); take_root_node (); } void -cxml::Document::read_stream (istream& stream) +cxml::Document::read_string (string s) { - _parser->parse_stream (stream); + _parser->parse_memory (s); take_root_node (); } @@ -239,8 +294,9 @@ cxml::Document::take_root_node () } _node = _parser->get_document()->get_root_node (); - if (_node->get_name() != _root_name) { - throw cxml::Error ("unrecognised root node"); + if (!_root_name.empty() && _node->get_name() != _root_name) { + throw cxml::Error ("unrecognised root node " + _node->get_name() + " (expecting " + _root_name + ")"); + } else if (_root_name.empty ()) { + _root_name = _node->get_name (); } } -