XmlSerializer使用其他引用反序列化XML

时间:2015-06-25 20:56:07

标签: c# .net xml serialization xmlserializer

我有这样的XML:

<Data>
<Author>
    <AuthorID>1</AuthorID>
    <Name>Max</Name>
</Author>
<Author>
    <AuthorID>2</AuthorID>
    <Name>Steve</Name>
</Author>
<Book>
    <AuthorID>1</AuthorID>
    <Name>Book name</Name>
</Book>
<Book>
    <AuthorID>2</AuthorID>
    <Name>Book name 2</Name>
</Book>

当我使用&#34;插入xml作为类&#34;视觉工作室的功能我得到这样的课程:

public class Data() {
    private DataAuthor[] dataAuthorFields;
    private DataBook[] dataBookFields;
}
public class DataAuthor() {
    private string AuthorID;
    private string Name;
}

我现在有两个列表,可以轻松显示所有作者和所有书籍。 但另外我想拥有一个数据模型,我可以从一位作者那里获得所有书籍:

public class DataAuthor() {
    private string AuthorID;
    private string Name;
    **private DataBook[] Books;**
}

我无法更改XML文件,只需要一位来自一位作者的书籍参考。 我怎么能这样做呢?

2 个答案:

答案 0 :(得分:0)

尝试使用Linq

var books = data.DataBook.Where(x => x.AuthorID == 1).ToArray();

答案 1 :(得分:0)

您可以在反序列化后调用Data类上的方法将书籍分配给作者,因此您只需支付一次执行该作业的成本并存储结果。或者,如果你想保持调用代码干净,你可以在数据类的Authors属性的getter上进行延迟初始化(因为它只会在反序列化后调用),并在第一次访问时执行该赋值作者的财产。 XmlIgnore属性意味着如果序列化回xml,Books上的Author属性不会弄乱你的xml。

用法:

using (XmlReader xmlReader = new XmlTextReader("somefile.xml"))
{
    XmlSerializer serializer = new XmlSerializer(typeof(Data));
    Data dataModel = serializer.Deserialize(xmlReader) as Data;

    foreach (Author author in dataModel.Authors)
    {
        Console.WriteLine("{0} has {1} books.", author.Name, author.Books.Count());
    }
}         

延迟初始化选项的类看起来像这样:

public class Data
{
    public Data()
    {
        _authorsWithBooks = new Lazy<Author[]>(() => _authorData.Select(a => { a.Books = Books.Where(b => b.AuthorID == a.AuthorID).ToArray(); return a; }).ToArray());
    }

    private Author[] _authorData;
    private Lazy<Author[]> _authorsWithBooks;

    [XmlElement("Author")]
    public Author[] Authors
    {
        get
        {
            return _authorsWithBooks.Value;
        }
        set
        {
            _authorData = value;
        }
    }

    [XmlElement("Book")]
    public Book[] Books { get; set; }
}


public class Author
{
    public string AuthorID { get; set; }
    public string Name { get; set; }
    [XmlIgnore]
    public Book[] Books { get; set; }
}

public class Book
{
    public string AuthorID { get; set;}
    public string Name { get; set; }
}