Various API tidying.
authorCarl Hetherington <cth@carlh.net>
Fri, 10 Oct 2014 18:13:01 +0000 (19:13 +0100)
committerCarl Hetherington <cth@carlh.net>
Fri, 10 Oct 2014 18:13:01 +0000 (19:13 +0100)
src/cxml.cc
src/cxml.h
test/ref/a.xml
test/ref/b.xml
test/tests.cc

index 810cf92aaeafde75534955a7b457acec8a4ffa48..3285fe6e195aa4a69cb5e6bb79ae7c25d4beb9b5 100644 (file)
@@ -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;
        }
@@ -239,12 +244,6 @@ cxml::Node::content () const
        return _content;
 }
 
-string
-cxml::Node::namespace_uri () const
-{
-       return _namespace_uri;
-}
-
 string
 cxml::Node::namespace_prefix () const
 {
@@ -252,47 +251,22 @@ cxml::Node::namespace_prefix () const
 }
 
 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 ();
 }
+
index e358b9cdba3f54925b5b2afa5207abd6c3d6e90f..1c98bbf237e18d119db87f48e2ac18397abaa790 100644 (file)
@@ -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);
 
 }
 
index 10900aa3b984e78e1d784286d7123130c1d01d57..8e397ce8731ccc946441341bf932a54540cd19d4 100644 (file)
@@ -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>
index d1917557f7aa3be8a3f9fa70ac2a2461468ad957..d0a416c1eda5b6fbdbd6b47f7e3b402f7e61ae0b 100644 (file)
@@ -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>
index bd6e4c961acdcb383d59dbc6d90105f7e3eec33b..8b3249888eedc8a7d1bee215bfd70dfdbb632e4b 100644 (file)
@@ -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);
 }