序列化:动态类名

时间:2016-06-30 08:36:56

标签: c# class serialization dynamic

我已经尝试了各种可能性,但也许我太厌倦了看到解决方案-.-

我有一个像这样的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元素的“外科手术”。

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”实例化可变数量的类。该类必须有一个变量Name,即

手术1,手术2,手术3等

这是无法更改的,因为这是由定义XML结构的机构提供的。

该类必须可以通过其动态名称访问,因为必须设置类中的属性。

这样:

surgery1.Property =“blabla”;

surgery2。 Property =“babla”;

我甚至考虑使用T4方法来创建这部分代码,但必须有另一种方法来实现动态类名。

我还想过使用反射创建具有类的变量名的实例:

System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)

但这实际上并不起作用-.-

是否有人提示并可以让我朝着正确的方向前进?

2 个答案:

答案 0 :(得分:0)

我认为,你可以在对象包含diagnosisList的{​​{3}}中尝试实现方法。

答案 1 :(得分:0)

尝试使用自定义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"]