using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; namespace Intromat.PersistentModel { public class NodeCollectionModel : IXmlSerializable { public static readonly Dictionary _nodeTypes; public static readonly XmlSerializerNamespaces _nameSpaces; static NodeCollectionModel() { _nodeTypes = typeof(NodeModelBase) .Assembly .GetTypes() .Where(t => typeof(NodeModelBase).IsAssignableFrom(t) && !t.IsAbstract) .Select(type => { var attrib = (XmlRootAttribute)type.GetCustomAttribute(typeof(XmlRootAttribute))!; return (attrib.ElementName, Type: type); }) .ToDictionary(pair => pair.ElementName, pair => pair.Type); _nameSpaces = new XmlSerializerNamespaces(); _nameSpaces.Add(string.Empty, NodeModelBase._namespace); _nameSpaces.Add("x", "http://www.w3.org/2001/XMLSchema-instance"); } public List Items { get; set; } = new(); public XmlSchema? GetSchema() { return null; } public void ReadXml(XmlReader reader) { reader.MoveToContent(); var isEmptyElement = reader.IsEmptyElement; reader.ReadStartElement(); if (!isEmptyElement) { while (reader.NodeType != XmlNodeType.EndElement) { if (_nodeTypes.TryGetValue(reader.Name, out var nodeType)) { var serializer = new XmlSerializer(nodeType); var node = (NodeModelBase)serializer.Deserialize(reader)!; Items.Add(node); } } reader.ReadEndElement(); } } public void WriteXml(XmlWriter writer) { if (Items.Count == 0) return; foreach (var node in Items) { var serializer = new XmlSerializer(node.GetType()); serializer.Serialize(writer, node, _nameSpaces); } } } }