74 lines
2.3 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
} |