您面临在 XML 中表示聚合而不是组合关系的问题。当您保持父拥有子关系的父子关系(即组合)时,XML 序列化非常简单。在这种情况下,一本书有一个(或多个)作者,但并不拥有它,因为一个作者可以是许多其他书籍的作者。
在这种情况下,您可以做类似于数据库中所做的事情,即有两个单独的条目并通过外键表达关系。请参阅下面的示例:
[Serializable]
public class Author
{
[XmlAttribute("id")]
public String Id { get; set; }
[XmlElement("name")]
public String Name { get; set; }
}
[Serializable]
public class Book
{
private Author _author;
[XmlIgnore]
public Author Author
{
get { return _author; }
set
{
_author = value;
AuthorId = _author != null ? _author.Id : null;
}
}
[XmlAttribute("id")]
public String Id { get; set; }
[XmlElement("author")]
public String AuthorId { get; set; }
[XmlElement("title")]
public String Title { get; set; }
}
[Serializable]
public class Store
{
[XmlArray("authors")]
[XmlArrayItem("author", Type = typeof(Author))]
public List<Author> Authors { get; set; }
[XmlArray("books")]
[XmlArrayItem("book", Type = typeof(Book))]
public List<Book> Books { get; set; }
public Store()
{
Books = new List<Book>();
Authors = new List<Author>();
}
}
internal class Program
{
private static void Main(string[] args)
{
// Create some authors
var authors = new List<Author>
{
new Author{Id="PK", Name="Philip Kindred"},
new Author{Id="WS", Name="William Shakespeare"},
};
// Create some books linked to the authors
var books = new List<Book>
{
new Book{Id = "U1", Author = authors[0], Title = "Do Androids Dream of Electric Sheep?"},
new Book{Id = "U2", Author = authors[1], Title = "Romeo and Juliet"}
};
var store = new Store {Authors = authors, Books = books};
var success = Serialiser.SerialiseToXml(store, "store.xml");
// Deserialize the data from XML
var store2 = Serialiser.DeserialseFromXml<Store>("store.xml");
// Resolve the actual Author instances from the saved IDs (foreign key equivalent in databases)
foreach (var book in store2.Books)
book.Author = store2.Authors.FirstOrDefault(author => author.Id == book.AuthorId);
// Now variable 'store' and 'store2' have the same equivalent data
}
}
// Helper class to serialize and deserialize the data to XML file
public static class Serialiser
{
public static bool SerialiseToXml(object obj, string filename)
{
try
{
var ws = new XmlWriterSettings
{
NewLineHandling = NewLineHandling.Entitize,
NewLineChars = Environment.NewLine,
Indent = true,
NewLineOnAttributes = false
};
var xs = new XmlSerializer(obj.GetType());
using (var writer = XmlWriter.Create(filename, ws))
xs.Serialize(writer, obj);
return true;
}
catch(Exception ex)
{
return false;
}
}
public static T DeserialseFromXml<T>(string filename) where T : new()
{
var typeofT = typeof(T);
try
{
var xs = new XmlSerializer(typeofT);
using (var reader = XmlReader.Create(filename))
return (T)xs.Deserialize(reader);
}
catch(Exception ex)
{
return default(T);
}
}
}
“store.xml”将如下所示:
<?xml version="1.0" encoding="utf-8"?>
<Store xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<authors>
<author id="PK">
<name>Philip Kindred</name>
</author>
<author id="WS">
<name>William Shakespeare</name>
</author>
</authors>
<books>
<book id="U1">
<author>PK</author>
<title>Do Androids Dream of Electric Sheep?</title>
</book>
<book id="U2">
<author>WS</author>
<title>Romeo and Juliet</title>
</book>
</books>
</Store>