diff options
| author | Carl Hetherington <cth@carlh.net> | 2014-10-10 19:13:01 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2014-10-10 19:13:01 +0100 |
| commit | ed60523d354af3b18150da1e183e80dc52ee851a (patch) | |
| tree | 82e4467cbb3f4f410423ee3a9b9483658edddfe5 | |
| parent | 80a970c3f0c2265f8df0643947ed38134a46a85f (diff) | |
Various API tidying.
| -rw-r--r-- | src/cxml.cc | 142 | ||||
| -rw-r--r-- | src/cxml.h | 90 | ||||
| -rw-r--r-- | test/ref/a.xml | 6 | ||||
| -rw-r--r-- | test/ref/b.xml | 6 | ||||
| -rw-r--r-- | test/tests.cc | 186 |
5 files changed, 162 insertions, 268 deletions
diff --git a/src/cxml.cc b/src/cxml.cc index 810cf92..3285fe6 100644 --- a/src/cxml.cc +++ b/src/cxml.cc @@ -49,7 +49,6 @@ void cxml::Node::read (xmlpp::Node const * node) { _name = node->get_name (); - _namespace_uri = node->get_namespace_uri (); _namespace_prefix = node->get_namespace_prefix (); xmlpp::Node::NodeList content = node->get_children (); @@ -74,7 +73,7 @@ cxml::Node::read (xmlpp::Node const * node) void cxml::Node::write (xmlpp::Node* parent) const { - xmlpp::Element* node = parent->add_child (_name); + xmlpp::Element* node = parent->add_child (_name, _namespace_prefix); if (!_content.empty ()) { node->add_child_text (_content); @@ -90,9 +89,9 @@ cxml::Node::write (xmlpp::Node* parent) const } cxml::NodePtr -cxml::Node::node_child (string name) const +cxml::Node::child (string name) const { - NodeList n = node_children (name); + NodeList n = children (name); if (n.size() > 1) { throw cxml::Error ("duplicate XML tag " + name); } else if (n.empty ()) { @@ -103,9 +102,9 @@ cxml::Node::node_child (string name) const } cxml::NodePtr -cxml::Node::optional_node_child (string name) const +cxml::Node::optional_child (string name) const { - NodeList n = node_children (name); + NodeList n = children (name); if (n.size() > 1) { throw cxml::Error ("duplicate XML tag " + name); } else if (n.empty ()) { @@ -116,7 +115,13 @@ cxml::Node::optional_node_child (string name) const } cxml::NodeList -cxml::Node::node_children (string name) const +cxml::Node::children () const +{ + return _children; +} + +cxml::NodeList +cxml::Node::children (string name) const { NodeList n; @@ -133,13 +138,13 @@ cxml::Node::node_children (string name) const string cxml::Node::string_child (string c) const { - return node_child(c)->content (); + return child(c)->content (); } optional<string> cxml::Node::optional_string_child (string c) const { - NodeList nodes = node_children (c); + NodeList nodes = children (c); if (nodes.size() > 1) { throw cxml::Error ("duplicate XML tag " + c); } @@ -178,7 +183,7 @@ cxml::Node::ignore_child (string name) const string cxml::Node::string_attribute (string name) const { - list<pair<string, string> >::const_iterator i; + list<pair<string, string> >::const_iterator i = _attributes.begin (); while (i != _attributes.end() && i->first != name) { ++i; } @@ -240,59 +245,28 @@ cxml::Node::content () const } string -cxml::Node::namespace_uri () const -{ - return _namespace_uri; -} - -string cxml::Node::namespace_prefix () const { return _namespace_prefix; } void -cxml::Node::set_string_content (string c) -{ - _content = c; -} - -void -cxml::Node::set_bool_content (bool c) +cxml::Node::set_attribute (string name, string value) { - _content = c ? "1" : "0"; -} + list<pair<string, string> >::iterator i = _attributes.begin (); + while (i != _attributes.end() && i->first != name) { + ++i; + } -void -cxml::Node::add_string_attribute (string name, string value) -{ + if (i != _attributes.end ()) { + _attributes.erase (i); + } + _attributes.push_back (make_pair (name, value)); } -void -cxml::Node::add_bool_attribute (string name, bool value) -{ - add_string_attribute (name, value ? "1" : "0"); -} - -cxml::NodePtr -cxml::Node::add_string_child (string name, string content) -{ - NodePtr n = add_child (name); - n->set_string_content (content); - return n; -} - cxml::NodePtr -cxml::Node::add_bool_child (std::string name, bool content) -{ - NodePtr n = add_child (name); - n->set_bool_content (content); - return n; -} - -void -cxml::Document::read_file (boost::filesystem::path file) +cxml::read_file (boost::filesystem::path file) { if (!boost::filesystem::exists (file)) { throw cxml::Error ("XML file does not exist"); @@ -300,63 +274,79 @@ cxml::Document::read_file (boost::filesystem::path file) xmlpp::DomParser parser; parser.parse_file (file.string ()); - read (parser.get_document()->get_root_node ()); + cxml::NodePtr node (new cxml::Node); + node->read (parser.get_document()->get_root_node ()); + return node; } -void -cxml::Document::read_stream (istream& stream) +cxml::NodePtr +cxml::read_stream (istream& stream) { xmlpp::DomParser parser; parser.parse_stream (stream); - read (parser.get_document()->get_root_node ()); + cxml::NodePtr node (new cxml::Node); + node->read (parser.get_document()->get_root_node ()); + return node; } -void -cxml::Document::read_string (string s) +cxml::NodePtr +cxml::read_string (string s) { xmlpp::DomParser parser; stringstream t (s); parser.parse_stream (t); - read (parser.get_document()->get_root_node ()); + cxml::NodePtr node (new cxml::Node); + node->read (parser.get_document()->get_root_node ()); + return node; } -void -cxml::Document::check_root_name (string r) +static void +write_to_xmlpp_document (cxml::ConstNodePtr node, xmlpp::Document& doc) { - if (name() != r) { - throw cxml::Error ("unrecognised root node"); + xmlpp::Element* root = doc.create_root_node (node->name ()); + cxml::NodeList children = node->children (); + for (cxml::NodeList::const_iterator i = children.begin(); i != children.end(); ++i) { + (*i)->write (root); } } void -cxml::Document::write_to_file_formatted (boost::filesystem::path path) const +cxml::write_to_file (cxml::ConstNodePtr node, boost::filesystem::path path) { xmlpp::Document doc; - write_to_xmlpp_document (doc); + write_to_xmlpp_document (node, doc); + doc.write_to_file (path.string ()); +} + +void +cxml::write_to_file_formatted (cxml::ConstNodePtr node, boost::filesystem::path path) +{ + xmlpp::Document doc; + write_to_xmlpp_document (node, doc); doc.write_to_file_formatted (path.string ()); } void -cxml::Document::write_to_stream_formatted (ostream& stream, string coding) const +cxml::write_to_stream_formatted (cxml::ConstNodePtr node, ostream& stream) { xmlpp::Document doc; - write_to_xmlpp_document (doc); - doc.write_to_stream_formatted (stream, coding); + write_to_xmlpp_document (node, doc); + doc.write_to_stream_formatted (stream); } string -cxml::Document::write_to_string (std::string coding) const +cxml::write_to_string (cxml::ConstNodePtr node) { xmlpp::Document doc; - write_to_xmlpp_document (doc); - return doc.write_to_string (coding); + write_to_xmlpp_document (node, doc); + return doc.write_to_string (); } -void -cxml::Document::write_to_xmlpp_document (xmlpp::Document& doc) const +string +cxml::write_to_string_formatted (cxml::ConstNodePtr node) { - xmlpp::Element* root = doc.create_root_node (name ()); - for (NodeList::const_iterator i = _children.begin(); i != _children.end(); ++i) { - (*i)->write (root); - } + xmlpp::Document doc; + write_to_xmlpp_document (node, doc); + return doc.write_to_string_formatted (); } + @@ -178,69 +178,33 @@ public: } - /* Setting content */ - - void set_string_content (std::string content); - void set_bool_content (bool content); - - template <class T> - void set_number_content (T content) - { - std::stringstream u; - u.imbue (std::locale::classic ()); - u << content; - u >> _content; - } - - - /* Adding attributes */ - - void add_string_attribute (std::string name, std::string value); - void add_bool_attribute (std::string name, bool value); - - template <class T> - void add_number_attribute (std::string name, T value) - { - std::stringstream u; - u.imbue (std::locale::classic ()); - u << value; - add_string_attribute (name, u.str ()); - } - - - /* Short-cuts to add nodes with content */ - - NodePtr add_string_child (std::string name, std::string content); - NodePtr add_bool_child (std::string name, bool content); - - template <class T> - NodePtr add_number_child (std::string name, T content) - { - NodePtr n = add_child (name); - n->set_number_content (content); - return n; - } - - /* Access to child nodes */ - boost::shared_ptr<Node> node_child (std::string) const; - boost::shared_ptr<Node> optional_node_child (std::string) const; - NodeList node_children (std::string) const; + boost::shared_ptr<Node> child (std::string) const; + boost::shared_ptr<Node> optional_child (std::string) const; + NodeList children () const; + NodeList children (std::string) const; /** Add a child node with a given name */ - NodePtr add_child (std::string name) + NodePtr add_child (std::string name, std::string namespace_prefix = "") { NodePtr n (new cxml::Node ()); + n->set_namespace_prefix (namespace_prefix); n->set_name (name); _children.push_back (n); return n; } + void set_content (std::string c) { + _content = c; + } + /** @return The content of this node */ std::string content () const; - /** @return namespace URI of this node */ - std::string namespace_uri () const; + void set_attribute (std::string name, std::string value); + void set_namespace_prefix (std::string p) { + _namespace_prefix = p; + } /** @return namespace prefix of this node */ std::string namespace_prefix () const; /** This will mark a child as to be ignored when calling done() */ @@ -272,30 +236,20 @@ protected: private: std::string _name; std::string _content; - std::string _namespace_uri; std::string _namespace_prefix; std::list<std::pair<std::string, std::string> > _attributes; mutable std::list<std::string> _taken; }; -class Document : public Node -{ -public: - Document () {} - - void read_file (boost::filesystem::path); - void read_stream (std::istream &); - void read_string (std::string); +cxml::NodePtr read_file (boost::filesystem::path); +cxml::NodePtr read_stream (std::istream &); +cxml::NodePtr read_string (std::string); - void check_root_name (std::string root_name); - - void write_to_file_formatted (boost::filesystem::path) const; - void write_to_stream_formatted (std::ostream& stream, std::string coding) const; - std::string write_to_string (std::string) const; - -private: - void write_to_xmlpp_document (xmlpp::Document &) const; -}; +void write_to_file (cxml::ConstNodePtr, boost::filesystem::path); +void write_to_file_formatted (cxml::ConstNodePtr, boost::filesystem::path); +void write_to_stream_formatted (cxml::ConstNodePtr, std::ostream& stream); +std::string write_to_string (cxml::ConstNodePtr); +std::string write_to_string_formatted (cxml::ConstNodePtr); } diff --git a/test/ref/a.xml b/test/ref/a.xml index 10900aa..8e397ce 100644 --- a/test/ref/a.xml +++ b/test/ref/a.xml @@ -3,9 +3,9 @@ <B>42</B> <C>fred</C> <D>42.9</D> - <E>yes</E> - <F>1</F> - <F>2</F> + <E foo="bar">yes</E> + <F fred="4">1</F> + <F jim="yes">2</F> <H> <I>testing</I> <I>more testing</I> diff --git a/test/ref/b.xml b/test/ref/b.xml index d191755..d0a416c 100644 --- a/test/ref/b.xml +++ b/test/ref/b.xml @@ -3,9 +3,9 @@ <B>42</B> <C>fred</C> <D>42.9</D> - <E>1</E> - <F>1</F> - <F>2</F> + <E foo="bar">1</E> + <F fred="4">1</F> + <F jim="1">2</F> <H> <I>testing</I> <I>more testing</I> diff --git a/test/tests.cc b/test/tests.cc index bd6e4c9..8b32498 100644 --- a/test/tests.cc +++ b/test/tests.cc @@ -33,130 +33,80 @@ using std::vector; using std::list; using boost::shared_ptr; - -void -check_xml (xmlpp::Element* ref, xmlpp::Element* test, list<string> ignore) -{ - BOOST_CHECK_EQUAL (ref->get_name (), test->get_name ()); - BOOST_CHECK_EQUAL (ref->get_namespace_prefix (), test->get_namespace_prefix ()); - - if (find (ignore.begin(), ignore.end(), ref->get_name()) != ignore.end ()) { - return; - } - - xmlpp::Element::NodeList ref_children = ref->get_children (); - xmlpp::Element::NodeList test_children = test->get_children (); - BOOST_CHECK_EQUAL (ref_children.size (), test_children.size ()); - - xmlpp::Element::NodeList::iterator k = ref_children.begin (); - xmlpp::Element::NodeList::iterator l = test_children.begin (); - while (k != ref_children.end ()) { - - /* XXX: should be doing xmlpp::EntityReference, xmlpp::XIncludeEnd, xmlpp::XIncludeStart */ - - xmlpp::Element* ref_el = dynamic_cast<xmlpp::Element*> (*k); - xmlpp::Element* test_el = dynamic_cast<xmlpp::Element*> (*l); - BOOST_CHECK ((ref_el && test_el) || (!ref_el && !test_el)); - if (ref_el && test_el) { - check_xml (ref_el, test_el, ignore); - } - - xmlpp::ContentNode* ref_cn = dynamic_cast<xmlpp::ContentNode*> (*k); - xmlpp::ContentNode* test_cn = dynamic_cast<xmlpp::ContentNode*> (*l); - BOOST_CHECK ((ref_cn && test_cn) || (!ref_cn && !test_cn)); - if (ref_cn && test_cn) { - BOOST_CHECK_EQUAL (ref_cn->get_content(), test_cn->get_content ()); - } - - xmlpp::Attribute* ref_at = dynamic_cast<xmlpp::Attribute*> (*k); - xmlpp::Attribute* test_at = dynamic_cast<xmlpp::Attribute*> (*l); - BOOST_CHECK ((ref_at && test_at) || (!ref_at && !test_at)); - if (ref_at && test_at) { - BOOST_CHECK_EQUAL (ref_at->get_name(), test_at->get_name ()); - BOOST_CHECK_EQUAL (ref_at->get_value(), test_at->get_value ()); - } - - ++k; - ++l; - } -} - -void -check_xml (boost::filesystem::path ref, boost::filesystem::path test, list<string> ignore) -{ - xmlpp::DomParser* ref_parser = new xmlpp::DomParser (ref.string ()); - xmlpp::Element* ref_root = ref_parser->get_document()->get_root_node (); - xmlpp::DomParser* test_parser = new xmlpp::DomParser (test.string ()); - xmlpp::Element* test_root = test_parser->get_document()->get_root_node (); - - check_xml (ref_root, test_root, ignore); -} - BOOST_AUTO_TEST_CASE (read_test) { - cxml::Document document; - document.read_file ("test/ref/a.xml"); - document.check_root_name ("A"); - - BOOST_CHECK_EQUAL (document.string_child("B"), "42"); - BOOST_CHECK_EQUAL (document.number_child<int>("B"), 42); - BOOST_CHECK_EQUAL (document.number_child<float>("B"), 42); - BOOST_CHECK_EQUAL (document.string_child("C"), "fred"); - BOOST_CHECK_EQUAL (document.number_child<double>("D"), 42.9); - BOOST_CHECK_EQUAL (document.string_child("E"), "yes"); - BOOST_CHECK_EQUAL (document.bool_child("E"), true); - BOOST_CHECK_THROW (document.bool_child("F"), cxml::Error); - - BOOST_CHECK (document.optional_string_child("B")); - BOOST_CHECK_EQUAL (document.optional_string_child("B").get(), "42"); - BOOST_CHECK (document.optional_number_child<int>("B")); - BOOST_CHECK_EQUAL (document.optional_number_child<int>("B").get(), 42); - BOOST_CHECK (document.optional_number_child<float>("B")); - BOOST_CHECK_EQUAL (document.optional_number_child<float>("B").get(), 42); - BOOST_CHECK (document.optional_string_child("C")); - BOOST_CHECK_EQUAL (document.optional_string_child("C").get(), "fred"); - BOOST_CHECK (document.optional_number_child<double>("D")); - BOOST_CHECK_EQUAL (document.optional_number_child<double>("D").get(), 42.9); - BOOST_CHECK (document.optional_string_child("E")); - BOOST_CHECK_EQUAL (document.optional_string_child("E").get(), "yes"); - BOOST_CHECK (document.optional_bool_child("E")); - BOOST_CHECK_EQUAL (document.optional_bool_child("E").get(), true); - BOOST_CHECK_THROW (document.optional_bool_child("F"), cxml::Error); - - BOOST_CHECK_EQUAL (document.node_children("F").size(), 2); - BOOST_CHECK_EQUAL (document.node_children("F").front()->content(), "1"); - BOOST_CHECK_EQUAL (document.node_children("F").back()->content(), "2"); - - BOOST_CHECK (!document.optional_bool_child("G")); - - list<shared_ptr<cxml::Node> > h = document.node_children ("H"); + cxml::NodePtr document = cxml::read_file ("test/ref/a.xml"); + + BOOST_CHECK_EQUAL (document->string_child("B"), "42"); + BOOST_CHECK_EQUAL (document->number_child<int>("B"), 42); + BOOST_CHECK_EQUAL (document->number_child<float>("B"), 42); + BOOST_CHECK_EQUAL (document->string_child("C"), "fred"); + BOOST_CHECK_EQUAL (document->number_child<double>("D"), 42.9); + BOOST_CHECK_EQUAL (document->string_child("E"), "yes"); + BOOST_CHECK_EQUAL (document->bool_child("E"), true); + BOOST_CHECK_THROW (document->bool_child("F"), cxml::Error); + + BOOST_CHECK (document->optional_string_child("B")); + BOOST_CHECK_EQUAL (document->optional_string_child("B").get(), "42"); + BOOST_CHECK (document->optional_number_child<int>("B")); + BOOST_CHECK_EQUAL (document->optional_number_child<int>("B").get(), 42); + BOOST_CHECK (document->optional_number_child<float>("B")); + BOOST_CHECK_EQUAL (document->optional_number_child<float>("B").get(), 42); + BOOST_CHECK (document->optional_string_child("C")); + BOOST_CHECK_EQUAL (document->optional_string_child("C").get(), "fred"); + BOOST_CHECK (document->optional_number_child<double>("D")); + BOOST_CHECK_EQUAL (document->optional_number_child<double>("D").get(), 42.9); + BOOST_CHECK_THROW (document->child("D")->string_attribute ("foo"), cxml::Error); + BOOST_CHECK (document->optional_string_child("E")); + BOOST_CHECK_EQUAL (document->optional_string_child("E").get(), "yes"); + BOOST_CHECK_EQUAL (document->child("E")->string_attribute ("foo"), "bar"); + BOOST_CHECK (document->optional_bool_child("E")); + BOOST_CHECK_EQUAL (document->optional_bool_child("E").get(), true); + BOOST_CHECK_THROW (document->optional_bool_child("F"), cxml::Error); + + BOOST_CHECK_EQUAL (document->children("F").size(), 2); + BOOST_CHECK_EQUAL (document->children("F").front()->content(), "1"); + BOOST_CHECK_EQUAL (document->children("F").front()->number_attribute<int>("fred"), 4); + BOOST_CHECK_EQUAL (document->children("F").back()->content(), "2"); + BOOST_CHECK_EQUAL (document->children("F").back()->bool_attribute("jim"), true); + + BOOST_CHECK (!document->optional_bool_child("G")); + + list<shared_ptr<cxml::Node> > h = document->children ("H"); BOOST_CHECK_EQUAL (h.size(), 1); - BOOST_CHECK_EQUAL (h.front()->node_children("I").size(), 2); - BOOST_CHECK_EQUAL (h.front()->node_children("I").front()->content(), "testing"); - BOOST_CHECK_EQUAL (h.front()->node_children("I").back()->content(), "more testing"); + BOOST_CHECK_EQUAL (h.front()->children("I").size(), 2); + BOOST_CHECK_EQUAL (h.front()->children("I").front()->content(), "testing"); + BOOST_CHECK_EQUAL (h.front()->children("I").back()->content(), "more testing"); - BOOST_CHECK_EQUAL (document.node_children("J").size(), 1); - BOOST_CHECK_EQUAL (document.node_children("J").front()->node_children("K").size(), 1); - BOOST_CHECK_EQUAL (document.node_children("J").front()->node_children("K").front()->content(), "jim"); + BOOST_CHECK_EQUAL (document->children("J").size(), 1); + BOOST_CHECK_EQUAL (document->children("J").front()->children("K").size(), 1); + BOOST_CHECK_EQUAL (document->children("J").front()->children("K").front()->content(), "jim"); } BOOST_AUTO_TEST_CASE (write_test) { - cxml::Document document; - document.set_name ("A"); - - document.add_number_child<int> ("B", 42); - document.add_string_child ("C", "fred"); - document.add_number_child<double> ("D", 42.9); - document.add_bool_child ("E", true); - document.add_number_child<int> ("F", 1); - document.add_number_child<int> ("F", 2); - cxml::NodePtr h = document.add_child ("H"); - h->add_string_child ("I", "testing"); - h->add_string_child ("I", "more testing"); - document.add_child ("J")->add_string_child ("K", "jim"); - - document.write_to_file_formatted ("build/test/b.xml"); - - check_xml ("test/ref/b.xml", "build/test/b.xml", list<string> ()); + cxml::NodePtr document (new cxml::Node); + document->set_name ("A"); + + document->add_child("B")->set_content ("42"); + document->add_child("C")->set_content ("fred"); + document->add_child("D")->set_content ("42.9"); + cxml::NodePtr E = document->add_child("E"); + E->set_content ("1"); + E->set_attribute ("foo", "bar"); + cxml::NodePtr F1 = document->add_child("F"); + F1->set_content ("1"); + F1->set_attribute ("fred", "4"); + cxml::NodePtr F2 = document->add_child("F"); + F2->set_content ("2"); + F2->set_attribute ("jim", "1"); + cxml::NodePtr h = document->add_child ("H"); + h->add_child("I")->set_content ("testing"); + h->add_child("I")->set_content ("more testing"); + document->add_child("J")->add_child("K")->set_content ("jim"); + + write_to_file_formatted (document, "build/test/b.xml"); + + int r = system ("diff -u test/ref/b.xml build/test/b.xml"); + BOOST_CHECK_EQUAL (WEXITSTATUS (r), 0); } |
