0

Normally I use SQL Server or Oracle for storage, so serializing to XML is a little new for me. I've had trouble locating answers that mirror what I'm doing enough for me to grasp what I've done wrong.

I have object MyObject and it has multiple properties. it is serializable. I need to store an IEnumerable<MyObject> to an xml file. This file is overwritten by a new list when saving, and when read needs to read directly back to an IEnumerable<MyObject> again.

I've managed to suppress the XML declaration and everything just fine on writes past the first, but I'm stuck on how to store this in a way I can read it back. Existing code (partially from searching around on here):

 foreach (var i in items)
        {
            bool append = File.Exists(fileName);
            using (var file = new StreamWriter(fileName,append))
            {
                ///don't add XML declarative headers if the file already exists. 
                if (append == true)
                {
                    ///check to see if the 
                    var emptyNamespaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
                    var settings = new XmlWriterSettings();
                    settings.Indent = true;
                    settings.OmitXmlDeclaration = true;
                    using (var writer = XmlWriter.Create(file, settings))
                    {
                        xml.Serialize(writer, i, emptyNamespaces);
                    }
                }
                else
                {
                    xml.Serialize(file, i);
                    //append = true;
                }
            }
        }

Obviously, I'm looping through the list, with only the first item having the XML header information. The problem is, I get multiple root nodes this way. if I create a new root node manually, I can't seem to serialize back to MyObject> because it doesn't match a property or class. What approach should I use to be able to serialize and deserialize this list of objects?

CDove
  • 1,940
  • 10
  • 19
  • A well-formed XML document must have exactly one [root element](https://en.wikipedia.org/wiki/Root_element). Why not just deserialize and later serialize a `List` and be done with it? Do you have some requirement to be able to append new objects to the file without deserializing and re-serializing the entire file? – dbc Dec 18 '18 at 19:26
  • These store configuration information for certain plugins at runtime that can be changed by the user. They need to persist across multiple sessions (thus the storage), but also accept changes on the fly. Eventually, there may be hundreds of "myObject" stored in one XML file and read back. If I could use a database for this I would, but the case specifically requires no database backend. – CDove Dec 18 '18 at 19:51
  • Given the requirement for a single root element, XML may not be the best choice for you then. [NDJson](http://ndjson.org/) might be better. But if you have to use XML you should test whether, **in practice**, deserializing and re-serializing a `List` with hundreds of objects is too slow. With a modern computer, serializing and deserializing *hundreds* of objects is often no problem at all. Things get trickier when you have tens of thousands. – dbc Dec 18 '18 at 20:01
  • Or, does the file really need to be a single well-formed XML document? You could go with a concatenated sequence of XML fragments, see [Read nodes of a xml file in C#](https://stackoverflow.com/a/46476652) for an example of reading a concatenated sequence of XML fragments from a file. – dbc Dec 18 '18 at 20:03
  • But there are some questions already about doing incremental insertions into an XML file. An XML file is just a text file, and there's no easy way to insert in the middle of a text file. See [Adding a Line to the Middle of a File with .NET](https://stackoverflow.com/q/2044365/3744182). But since you're inserting immediately before the ending tag of the root element, see [Fastest way to add new node to end of an xml?](https://stackoverflow.com/q/849043/3744182). – dbc Dec 18 '18 at 20:12

0 Answers0