【问题标题】:XmlSerializer Deserialize XML with additional referenceXmlSerializer 使用附加参考反序列化 XML
【发布时间】:2015-09-12 16:01:17
【问题描述】:

我有一个这样的 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>

当我使用 Visual Studio 中的“将 xml 作为类插入”功能时,我会得到这样的类:

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 文件,只需要一位作者对所有书籍的引用。 我怎样才能正确地做到这一点?

【问题讨论】:

    标签: c# .net xml serialization xmlserializer


    【解决方案1】:

    尝试使用 Linq

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

    【讨论】:

    • 为此,我需要像这样在 DataAuthor 中创建一个方法: public DataBook[] books { get { return data.DataBook.Where(x => x.AuthorID == 1).ToArray() ; } } 。但是 DataAuthor 没有引用 Data
    • 你有一个 Data 类,它包含一个 Authors 数组和一个 Books 数组,我的例子是使用 xml 将被反序列化到的那个类,另一种方法是实现一个自定义序列化器\解串器
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      • 2020-12-09
      • 1970-01-01
      • 2018-06-14
      • 2013-04-26
      • 1970-01-01
      相关资源
      最近更新 更多