问题
I like XmlSerializer
, because of its fire-and-forget operation. I can give XmlSerializer
the object to serialize and the file to serialize to, and XmlSerializer
will sort out the property names and values.
XmlWriter xmlWriter = XmlWriter.Create(projectPath + "\\" + m_projectDescriptionFileName); // create new project description file (XML)
XmlSerializer xmlSerializer = new XmlSerializer(typeof(CustomerContactInfoViewModel));
xmlSerializer.Serialize(xmlWriter, contactInfo);
xmlWriter.Close();
I like LINQ to XML for its ability to navigate. Here's an example of a method for editing an object that's stored in XML (adapted from Greg's blog. There are also snippets for Insert and Delete.)
public void EditBilling(Billing billing)
{
XElement node = m_billingData.Root.Elements("item").Where(i => (int)i.Element("id") == billing.ID).FirstOrDefault();
node.SetElementValue("customer", billing.Customer);
node.SetElementValue("type", billing.Type);
node.SetElementValue("date", billing.Date.ToShortDateString());
node.SetElementValue("description", billing.Description);
node.SetElementValue("hours", billing.Hours);
m_billingData.Save(HttpContext.Current.Server.MapPath("~/App_Data/Billings.xml"));
}
As you can see, property names and values are written out in the code, unlike XmlSerializer
.
I would like to be able able to store multiple objects of different types in the same XML file (adding them at different times, not all at once). I would like to be able to deserialize them one at a time. I would like to update them one at a time.
- Is there a way to combine the LINQ navigation with fire-and-forget convenience of
XmlSerializer
? - Is
XmlSerializer
a right kind of tool for this? - Is there something better (short of setting up a proper database)?
- Am I looking for something that goes by a different name?
Any suggestion, insight or reference is really appreciated!
回答1:
Using XmlSerializer will not directly allow you to serialize multiple objects of different types into the same file. You need to tweak the reading of the xml file a bit before using XmlSerializer.
You have two options.
Option #1:
The first one being that you have a wrapper class as suggested in comments, which holds your objects. You can then use XmlSerializer to Serialize/Deserialize that specific type. You cannot directly pick a part of the xml and serialize that. This will allow you to directly serialize and deserialize the whole type/class.
Quick sample:
public class Container {
public MyType My {get;set;}
public OtherType Other {get;set;}
}
Container container = new Container();
...
XmlSerializer serializer = new XmlSerializer(typeof(Container));
serializer.Serialize(aWriter, container);
// deserialize
StreamReader reader = new StreamReader("container.xml");
Container c = serializer.Deserialize(reader) as Container;
Option #2:
You can read the xml file using XmlReader
, and use ReadToDecendant(string) to find the current xml representation of your object (let's call it MyType
) and read that xml using ReadSubTree(). Using the result from ReadSubTree()
and push that to the XmlSerializer.Deserialize()
method.
A quick sample would be something like:
XmlReader reader = XmlReader.Create("objects.xml");
if (reader.ReadToDecendant("MyType"))
{
var myTypeXml = reader.ReadSubTree(); // read the whole subtree (type)
XmlSerializer serializer = new XmlSerializer(typeof(MyType)); // define the type
MyType obj = serializer.Deserialize(myTypeXml); //
}
Writing the object would be the oposite way, Serialize() the type into a (xml)string, and then replace the corresponding xml in the file.
You would really be better off using a database as data store, rather than xml. I hope you have a good reason for using files rather than a database.
Option #2 would probably be the best fit and most flexible implementation since it does not rely on wrapper classes.
来源:https://stackoverflow.com/questions/28652889/serializing-objects-into-xml-repository