lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [4805] Don't append duplicate xml elements (VS)


From: Greg Chicares
Subject: [lmi-commits] [4805] Don't append duplicate xml elements (VS)
Date: Tue, 23 Mar 2010 11:47:53 +0000

Revision: 4805
          http://svn.sv.gnu.org/viewvc/?view=rev&root=lmi&revision=4805
Author:   chicares
Date:     2010-03-23 11:47:53 +0000 (Tue, 23 Mar 2010)
Log Message:
-----------
Don't append duplicate xml elements (VS)

Modified Paths:
--------------
    lmi/trunk/xml_serialize.hpp
    lmi/trunk/xml_serialize_test.cpp

Modified: lmi/trunk/xml_serialize.hpp
===================================================================
--- lmi/trunk/xml_serialize.hpp 2010-03-22 17:28:17 UTC (rev 4804)
+++ lmi/trunk/xml_serialize.hpp 2010-03-23 11:47:53 UTC (rev 4805)
@@ -64,6 +64,8 @@
 
     static void to_xml(xml::element& e, T const& t)
     {
+        // XMLWRAPP !! Add a clear() function.
+        e.erase(e.begin(), e.end());
         // XMLWRAPP !! Someday, this might be rewritten thus:
         //   e.set_content(value_cast<std::string>(t).c_str());
         // but for now that doesn't work with embedded ampersands.
@@ -92,12 +94,13 @@
 
     static void to_xml(xml::element& e, T const& t)
     {
-        LMI_ASSERT(e.elements("item").empty());
+        // XMLWRAPP !! Add a clear() function.
+        e.erase(e.begin(), e.end());
         typedef typename T::const_iterator tci;
         for(tci i = t.begin(); i != t.end(); ++i)
             {
-            // This is equivalent to calling set_element();
-            // it's written out to avoid obscurity.
+            // This is not equivalent to calling set_element():
+            // multiple <item> elements are expressly permitted.
             xml::element z("item");
             xml_io<item_t>::to_xml(z, *i);
             e.push_back(z);
@@ -106,7 +109,7 @@
 
     static void from_xml(xml::element const& e, T& t)
     {
-        LMI_ASSERT(t.empty());
+        t.clear();
         xml::const_nodes_view const items(e.elements("item"));
         typedef xml::const_nodes_view::const_iterator cnvi;
         for(cnvi i = items.begin(); i != items.end(); ++i)
@@ -125,20 +128,13 @@
 
 /// Serialize a datum into a subelement of the given xml element.
 ///
-/// Many elements should be unique: e.g.,
-///   <DateOfBirth>19990101</DateOfBirth>
-///   <DateOfBirth>19871230</DateOfBirth>
-/// is a semantic error because one's birthdate is single-valued;
-/// however, it's valid syntactically, and indeed class template
-/// xml_sequence_io must support multiple <item> elements. Therefore,
-///   parent.erase(name.c_str());
-/// would be incorrect here, and an assertion that it returns zero
-/// would fail. Semantic correctness is the responsibility of code
-/// that uses the present facility.
+/// Precondition: parent has no element with the given tagname.
+/// Throws, via assertion failure, upon precondition violation.
 
 template<typename T>
 void set_element(xml::element& parent, std::string const& name, T const& t)
 {
+    LMI_ASSERT(parent.end() == parent.find(name.c_str()));
     xml::element z(name.c_str());
     xml_io<T>::to_xml(z, t);
     parent.push_back(z);
@@ -146,7 +142,8 @@
 
 /// Deserialize a datum from a subelement of the given xml element.
 ///
-/// retrieve_element() throws if the element isn't found.
+/// Precondition: parent has an element with the given tagname.
+/// Throws, via retrieve_element(), upon precondition violation.
 
 template<typename T>
 void get_element(xml::element const& parent, std::string const& name, T& t)

Modified: lmi/trunk/xml_serialize_test.cpp
===================================================================
--- lmi/trunk/xml_serialize_test.cpp    2010-03-22 17:28:17 UTC (rev 4804)
+++ lmi/trunk/xml_serialize_test.cpp    2010-03-23 11:47:53 UTC (rev 4805)
@@ -77,16 +77,24 @@
     xml_serialize::get_element(root, "v", v1);
 }
 
+void write_erroneous()
+{
+    xml_lmi::xml_document document("eraseme");
+    xml::element& root = document.root_node();
+    xml_serialize::set_element(root, "d", d0);
+    xml_serialize::set_element(root, "d", d0); // Error: duplicate element.
+}
+
 void read_erroneous()
 {
-    float f1; // Erroneous because there's no <f> in the xml.
+    float f1;
 
     xml_lmi::dom_parser parser(dom_string.c_str(), dom_string.size());
     xml::element const& root = parser.root_node("eraseme");
     xml_serialize::get_element(root, "d", d1);
     xml_serialize::get_element(root, "s", s1);
     xml_serialize::get_element(root, "v", v1);
-    xml_serialize::get_element(root, "f", f1);
+    xml_serialize::get_element(root, "f", f1); // Error: no <f> element.
 }
 
 // These /mete_[write|read]/ functions are like write() and read()
@@ -117,6 +125,7 @@
     xml::element& root = document.root_node();
     for(int j = 0; j < number_of_elements; ++j)
         {
+        root.erase("s");
         xml_serialize::set_element(root, "s", s0);
         }
     dom_string = document.str();
@@ -138,6 +147,7 @@
     xml::element& root = document.root_node();
     for(int j = 0; j < number_of_elements; ++j)
         {
+        root.erase("d");
         xml_serialize::set_element(root, "d", d0);
         }
     dom_string = document.str();
@@ -159,6 +169,7 @@
     xml::element& root = document.root_node();
     for(int j = 0; j < number_of_elements; ++j)
         {
+        root.erase("v");
         xml_serialize::set_element(root, "v", v0);
         }
     dom_string = document.str();
@@ -170,7 +181,6 @@
     xml::element const& root = parser.root_node("eraseme");
     for(int j = 0; j < number_of_elements; ++j)
         {
-        v1.clear();
         xml_serialize::get_element(root, "v", v1);
         }
 }
@@ -191,14 +201,11 @@
     BOOST_TEST(v0 == v1);
     BOOST_TEST_EQUAL(v0.size(), v1.size());
 
-    // Reading into a nonempty vector is forbidden because it probably
-    // indicates an error.
-    std::string not_empty("Assertion 't.empty()' failed.");
-    BOOST_TEST_THROW(read(), std::runtime_error, not_empty);
-    v1.clear();
-    read();
+    std::string found
+        ("Assertion 'parent.end() == parent.find(name.c_str())' failed."
+        );
+    BOOST_TEST_THROW(write_erroneous(), std::runtime_error, found);
 
-    v1.clear();
     std::string not_found("Required element 'f' not found.");
     BOOST_TEST_THROW(read_erroneous(), std::runtime_error, not_found);
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]