2016-06-30 3 views
0

Я уже пробовал различные возможности, но, возможно, я просто слишком устал видеть решение -.-сериализации: Динамические имена классов

У меня есть структуру 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; 
     } 
    } 

Мне нужно, чтобы иметь возможность сериализации имя класса операции динамически путем добавления номера перед сериализации происходит.

Неужели кто-то знает способ достичь этого?

любая помощь очень ценится :)

Сердечные приветы Сандро

- EDIT

создать всю структуру, начиная с моего корневого класса "Импорт". этот класс затем будет передан в сериализатор. Поэтому я не могу использовать 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); 
        } 
      } 
    } 

Что мне нужно, чтобы иметь возможность создать экземпляр переменное число классы, основанные на основном классе «Хирургия». Класс должен иметь имя переменной, т.е.

surgery1, surgery2, surgery3 и т.д.

Это не может быть изменен, так как это определяется учреждением, определяющим структуру XML.

класс должен быть доступен по его динамическому имени, так как должно быть задано свойство в классе.

так:

surgery1.Property = "блабла";

хирургия2. Свойство = "babla";

т.д.

Я даже думать об использовании методов T4, чтобы создать эту часть кода, но должен быть другой способ достижения динамических имен классов.

Я также думал о создании экземпляров с именами переменных класса с помощью отражения:

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

Но это не работает на самом деле -.-

Есть ли у кого-нибудь намек и может поставить меня в правильном направлении?

+1

Наверняка ваш 'Diagnosis' класс должен иметь список' Surgery' как XML делает? – Jamiec

+1

Чтобы достичь своей цели, я рекомендую либо реализовать свой собственный deserializationlogic, либо очистить ваш xml раньше. '' не должны иметь эти числа. Вместо этого число должно быть anttribute '' – lokusking

+0

Вы можете реализовать 'IXmlSerializable' в соответствии с строками [как получить имя элемента xml из значения атрибута класса с помощью аннотаций?] (Https: // stackoverflow. ком/вопросы/28769495). Или вы можете использовать '[XmlAnyElement]' в строках [Как десериализовать xml-элементы с разными именами, но тот же набор атрибутов для типизированного массива/коллекции] (http://stackoverflow.com/questions/30910834) , – dbc

ответ

0

Я думаю, вы могли бы попробовать реализовать методы из IXmlSerializable в объекте diagnosisList.

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"] 
+0

Благодарю всех вас за подсказки, но, к сожалению, до настоящего времени он не работал. как дополнительная информация: У меня есть эта структура, заданная схемой, мне нужно сериализовать не десериализовать ее :) –

+0

@SandroColletti - Мой плохой. Как правило, лучше всего делать то, что предлагает lokusking с атрибутом id. Я посмотрю, что я могу сделать в вашем случае. –

+0

@SandroColletti - см. Обновление. Я добавил пользовательский XML-писатель. –

Смежные вопросы