序列化:动态类名
本文关键字:动态 序列化 | 更新日期: 2023-09-27 17:53:14
我已经尝试了各种可能性,但也许我只是厌倦了看到解决方案- -
我有一个这样的xml结构:
<diagnosisList>
<diagnosis>
<surgery1>
<date>1957-08-13</date>
<description>a</description>
<ops301>0-000</ops301>
</surgery1>
<surgery2>
<date>1957-08-13</date>
<description>a</description>
<ops301>0-000</ops301>
</surgery2>
<surgery...>
</surgery...>
</diagnosis>
</diagnosisList>
正如你所看到的,手术的数量是可变的。我有一个包含XML元素的类"surgery"。
class Surgery
{
[XmlElement("date")]
public string date { get; set; }
[XmlElement("description")]
public string description { get; set; }
[XmlElement("ops301")]
public string ops301 { get; set; }
public Surgery()
{
}
}
和类诊断,通过向构造函数中添加手术类来创建结构。
diagnosis.cs
class Diagnosis
{
[XmlElement("surgery")]
public Surgery surgery
{
get;
set;
}
public Diagnosis(Surgery Surgery)
{
surgery = Surgery;
}
}
我需要能够通过在序列化发生之前添加一个数字来动态序列化手术的类名。
有谁知道实现这一点的方法吗?
任何帮助都是非常感激的:)
亲切的问候桑德罗
——编辑
我从根类"Import"开始创建整个结构。然后将这个类传递给序列化器。因此,我不能在结构的创建过程中使用XMLWriter。我需要首先创建整个结构,最后它将被序列化:
private static void XmlFileSerialization(Import import)
{
string filename = @"c:'dump'trauma.xml";
// default file serialization
XmlSerializer<Import>.SerializeToFile(import, filename);
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
namespaces.Add("", "");
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
settings.Indent = true;
settings.IndentChars = "'t";
XmlSerializer<Import>.SerializeToFile(import, filename, namespaces, settings);
}
,然后在方法"SerializeToFile"
public static void SerializeToFile(T source, string filename, XmlSerializerNamespaces namespaces, XmlWriterSettings settings)
{
if (source == null)
throw new ArgumentNullException("source", "Object to serialize cannot be null");
XmlSerializer serializer = new XmlSerializer(source.GetType());
using (XmlWriter xmlWriter = XmlWriter.Create(filename, settings))
{
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(T));
x.Serialize(xmlWriter, source, namespaces);
}
}
}
我需要的是能够实例化基于主类"Surgery"的可变数量的类。类必须有一个变量名,即
手术1,手术2,手术3等
不能更改,因为这是由定义XML结构的机构给出的。
类必须可以通过其动态名称访问,因为必须设置类中的属性。
:
surgery1。Property = "blabla";
surgery2。
等。
我甚至在考虑使用T4方法来创建这部分代码,但是必须有另一种方法来实现动态类名。
我还想到通过使用反射来创建具有类变量名的实例:
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)
但这实际上不起作用-.-
有没有人能给我一个提示,给我一个正确的方向?
我认为,您可以尝试从IXmlSerializable实现方法在对象包含diagnosisList
尝试使用自定义xml写入器和读取器。
public class SurgeryWriter : XmlTextWriter
{
public SurgeryWriter(string url) : base(url, Encoding.UTF8) { }
private int counter = 1;
public override void WriteStartElement(string prefix, string localName, string ns)
{
if (localName == "surgery")
{
base.WriteStartElement(prefix, "surgery" + counter, ns);
counter++;
}
else
base.WriteStartElement(prefix, localName, ns);
}
}
public class SurgeryReader : XmlTextReader
{
public SurgeryReader(string url) : base(url) { }
public override string LocalName
{
get
{
if (base.LocalName.StartsWith("surgery"))
return "surgery";
return base.LocalName;
}
}
}
类:
[XmlRoot("diagnosisList")]
public class DiagnosisList
{
[XmlArray("diagnosis")]
[XmlArrayItem("surgery")]
public Surgery[] Diagnosis { get; set; }
}
[XmlRoot("surgery")]
public class Surgery
{
[XmlElement("date", DataType = "date")]
public DateTime Date { get; set; }
[XmlElement("description")]
public string Description { get; set; }
[XmlElement("ops301")]
public string Ops301 { get; set; }
}
使用:
var xs = new XmlSerializer(typeof(DiagnosisList));
DiagnosisList diagnosisList;
using (var reader = new SurgeryReader("test.xml"))
diagnosisList = (DiagnosisList)xs.Deserialize(reader);
using (var writer = new SurgeryWriter("test2.xml"))
xs.Serialize(writer, diagnosisList);
不要把XML和c#混在一起。
c#代码中不需要动态名称!如果你需要一个类的任意数量的实例,在循环中创建它们,并将其放置在任意集合中。
var surgeries = new List<Surgery>();
for (int i = 0; i < 10; i++)
{
var surgery = new Surgery();
surgeries.Add(surgery);
}
以后您可以通过索引或枚举来访问它们。
surgeries[5]
foreach (var surgery in surgeries)
{
// use surgery
}
正如你所看到的,不需要动态名称!
或者,使用任意名称的字典作为键。
var surgeryDict = new Dictionary<string, Surgery>();
for (int i = 0; i < 10; i++)
{
var surgery = new Surgery();
surgeryDict["surgery" + i] = surgery;
}
按名称访问:
surgeryDict["surgery5"]