port from perforce
This commit is contained in:
74
intromat/Intromat/PersistentModel/NodeCollectionModel.cs
Normal file
74
intromat/Intromat/PersistentModel/NodeCollectionModel.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user