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 ();
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);
}
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 ()) {
}
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 ()) {
}
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;
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);
}
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;
}
return _content;
}
-string
-cxml::Node::namespace_uri () const
-{
- return _namespace_uri;
-}
-
string
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");
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 ();
}
+
}
- /* 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() */
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);
}
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);
}