Files
bluflame/intromat/Intromat/PersistentModel/NodeCollectionModel.cs
2026-04-18 22:31:51 +02:00

74 lines
2.3 KiB
C#

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<string, Type> _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<NodeModelBase> 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);
}
}
}
}