Парсинг xml-файла с вложенными классами
пытаюсь импортировать xml-файл в MS SQL Server и вроде бы как получилось, но работает не так как нужно. Вот сам xml-файл:
<?xml version="1.0" encoding="utf-8"?>
<DOCTORS>
<DOCTOR>
<surname>Никитина</surname>
<name>Нина</name>
<patronymic>Петровна</patronymic>
<profession>Терапевт</profession>
<category>1</category>
<PATIENT>
<surname>Понамарев</surname>
<name>Олег</name>
<patronymic>Игнатьевич</patronymic>
<date_birth>12.02.1997</date_birth>
<category>Инвалид</category>
<NOTES>
<date_note>01.03.2020</date_note>
<diagnos>ОРВИ</diagnos>
<price>560</price>
</NOTES>
</PATIENT>
<PATIENT>
<surname>Николаев</surname>
<name>Георгий</name>
<patronymic>Николаевич</patronymic>
<date_birth>17.11.1985</date_birth>
</PATIENT>
</DOCTOR>
<DOCTOR>
<surname>Романовна</surname>
<name>Светлана</name>
<patronymic>Николаевна</patronymic>
<profession>Дерматолог</profession>
<category>6</category>
</DOCTOR>
</DOCTORS>
Код:
// импортирую данные доктора
var items_doctor = doc.Descendants("DOCTOR")
.Select(x => new
{
Surname = (string)x.Element("surname"),
Name = (string)x.Element("name"),
Patronymic = (string)x.Element("patronymic"),
Profession = (string)x.Element("profession"),
Category = (string)x.Element("category")
});
foreach (var el in items_doctor)
{
using (var context = new MyDbContext())
{
var doctor = new Doctor
{
Family_name = el.Surname,
Name = el.Name,
Patronymic = el.Patronymic,
Profession = el.Profession,
Category = el.Category
};
context.Doctors.Add(doctor);
context.SaveChanges();
}
}
MessageBox.Show("Операция завершена успешно!");
Проблема в том, что добавляются сперва все доктора без информации о его пациентах, а нужно чтоб информация об одном докторе и о его пациентах загружалась, затем переходим к следующему доктору и т.д.
Не могли бы вы подсказать как можно считать информацию с файла вот таким образом:
DOCTOR считали всю информацию => PATIENT считали всю информацию => NOTES считали всю информацию => PATIENT считали всю информацию
Переходим к следующему:
DOCTOR считали всю информацию => ...
Ответы (1 шт):
вот решение
создаете классы
using System.Collections.Generic;
using System.Xml.Serialization;
namespace WindowsFormsApplication2
{
[XmlRoot(ElementName = "NOTES")]
public class NOTES
{
[XmlElement(ElementName = "date_note")]
public string Date_note { get; set; }
[XmlElement(ElementName = "diagnos")]
public string Diagnos { get; set; }
[XmlElement(ElementName = "price")]
public string Price { get; set; }
}
[XmlRoot(ElementName = "PATIENT")]
public class PATIENT
{
[XmlElement(ElementName = "surname")]
public string Surname { get; set; }
[XmlElement(ElementName = "name")]
public string Name { get; set; }
[XmlElement(ElementName = "patronymic")]
public string Patronymic { get; set; }
[XmlElement(ElementName = "date_birth")]
public string Date_birth { get; set; }
[XmlElement(ElementName = "category")]
public string Category { get; set; }
[XmlElement(ElementName = "NOTES")]
public NOTES NOTES { get; set; }
}
[XmlRoot(ElementName = "DOCTOR")]
public class DOCTOR
{
[XmlElement(ElementName = "surname")]
public string Surname { get; set; }
[XmlElement(ElementName = "name")]
public string Name { get; set; }
[XmlElement(ElementName = "patronymic")]
public string Patronymic { get; set; }
[XmlElement(ElementName = "profession")]
public string Profession { get; set; }
[XmlElement(ElementName = "category")]
public string Category { get; set; }
[XmlElement(ElementName = "PATIENT")]
public List<PATIENT> PATIENT { get; set; }
}
[XmlRoot(ElementName = "DOCTORS")]
public class DOCTORS
{
[XmlElement(ElementName = "DOCTOR")]
public List<DOCTOR> DOCTOR { get; set; }
}
}
Класс Десериализации
//библиотеки
using System; using System.IO; using System.Xml.Serialization;
/// <summary>
/// Класс для XML сериализации/десериализации
/// </summary>
/// <typeparam name="T">Любой тип класса</typeparam>
class XmlSerialization<T>
{
private Object _obj = typeof(T);
/// <summary>
/// Метод десриализует файл в формате XML
/// </summary>
/// <param name="filePath">Путь к файлу</param>
/// <param name="obj">Переменная класса</param>
/// <returns>возврашает object который надо приводить к типу класса (ClassType)</returns>
public Object ReadData(string filePath, Object obj)
{
if (obj == null) throw new ArgumentNullException("obj");
if (File.Exists(filePath))
{
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
XmlSerializer xser = new XmlSerializer(typeof(T));
obj = (T)xser.Deserialize(fs);
fs.Close();
}
return obj;
}
throw new Exception("file does not exist");
}
/// <summary>
/// Метод сериализует класс в формат XML и пишет его в файл
/// </summary>
/// <param name="filePath">путь к файлу для записи</param>
/// <param name="obj">Переменная класса</param>
public void WriteData(string filePath, Object obj)
{
if (File.Exists(filePath)) File.Delete(filePath);
using (FileStream fs = new FileStream(filePath, FileMode.Create))
{
XmlSerializer xser = new XmlSerializer(typeof(T));
xser.Serialize(fs, obj);
fs.Close();
}
}
}
Сам процесс десириализации
Может я не понимаю но NODES у пациента должны быть в списке, а то счас получается что на одного пациента только одна запись , но это уже вам решать
private void Form1_Load(object sender, EventArgs e)
{
XmlSerialization<DOCTORS> xmlSerialization = new XmlSerialization<DOCTORS>();
DOCTORS dc = new DOCTORS();
string filePath = @"S:\t.xml"; // путь к файлу
dc = (DOCTORS)xmlSerialization.ReadData(filePath, dc); //дерсериализация
for (int i = 0; i < dc.DOCTOR.Count; i++)//обходим докторов
{
//добавляете доктора в базу
string doctorName = dc.DOCTOR[i].Name;
string doctorSurname = dc.DOCTOR[i].Surname;
string doctorCategory = dc.DOCTOR[i].Category;
string doctorProfession = dc.DOCTOR[i].Profession;
string doctorPatronymic= dc.DOCTOR[i].Patronymic;
for (int j = 0; j < dc.DOCTOR[i].PATIENT.Count; j++)// обходим пациентов
{
// добавляйте пациента в базу к этому доктору
//пациенты доктора
string patienName = dc.DOCTOR[i].PATIENT[j].Name;
string patienSurname = dc.DOCTOR[i].PATIENT[j].Surname;
string patienCategory = dc.DOCTOR[i].PATIENT[j].Category;
string patienDateBirth = dc.DOCTOR[i].PATIENT[j].Date_birth;
//записи по пацианту (одна запись на пациента ? тоесть больше он не когда балеть не будет ? не понятно должен быть список )
if(dc.DOCTOR[i].PATIENT[j].NOTES!=null)
{
string patiendDateNote = dc.DOCTOR[i].PATIENT[j].NOTES.Date_note;
string patiendDiagnos = dc.DOCTOR[i].PATIENT[j].NOTES.Diagnos;
string patiendPrice = dc.DOCTOR[i].PATIENT[j].NOTES.Price;
}
}
}
}