XML как добавить новые узлы в определенное место
Структура 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>
К примеру я хочу добавить пациента доктору 'Романовна Светлана Николаевна' Сейчас я добавляю вот таким образом:
XDocument doc = new XDocument(new XElement("DOCTORS"));
// ...
doc.Element("DOCTORS").Element("DOCTOR").Element("DOCTOR").Add(patient);
Вопрос:
Есть ли другой способ добавления ? В частности хочу избавиться от повторяющихся слов
.Element("DOCTOR").Element("DOCTOR")
Ответы (2 шт):
Автор решения: Bulson
→ Ссылка
Берем класс XmlDoctorsService из прошлого моего ответа на ваш вопрос
Вот нужный вам доктор в файле выглядит так
<DOCTOR>
<surname>Романова</surname>
<name>Светлана</name>
<patronymic>Николаевна</patronymic>
<profession>Дерматолог</profession>
<category>6</category>
<PATIENTS />
</DOCTOR>
Пишем такой не хитрый код
static void Main(string[] args)
{
const string file = @"D:\docs.xml";
var xmlDoctors = new XmlDoctorsService();
//получаем коллекцию докторов
List<Doctor> doctors = xmlDoctors.GetDoctors(file);
//создаем нового пациента
var patient = new Patient
{
Surname = "Иванов",
Name = "Иван",
Patronymic = "Петрович",
Birthdate = DateTime.Parse("23.01.1989"),
};
//находим нужного доктора
var docRoman = doctors.FirstOrDefault(d => d.Surname.Equals("Романова"));
if (docRoman != null)
{
//и добавляем пациента к доктору
docRoman.Patients.Add(patient);
}
//сохраняем в файл
xmlDoctors.SaveDoctors(file, doctors);
Console.ReadLine();
}
В итоге получаем так
<DOCTOR>
<surname>Романова</surname>
<name>Светлана</name>
<patronymic>Николаевна</patronymic>
<profession>Дерматолог</profession>
<category>6</category>
<PATIENTS>
<PATIENT>
<surname>Иванов</surname>
<name>Иван</name>
<patronymic>Петрович</patronymic>
<date_birth>23.01.1989</date_birth>
<category />
<NOTES />
</PATIENT>
</PATIENTS>
Автор решения: Yitzhak Khabinsky
→ Ссылка
Это то же самое с использованием LINQ-to-XML. Я добавил проверку, если пациент уже существует.
c#
void Main()
{
const string inputDocument = @"e:\temp\doctors.xml";
const string doctorSurname = "Романовна";
const string PATIENTS = "PATIENTS";
const string PATIENT = "PATIENT";
XDocument xdoc = XDocument.Load(inputDocument);
// создаем нового пациента
XElement patient = new XElement(PATIENT
, new XElement("surname", "Иванов")
, new XElement("name", "Иван")
, new XElement("patronymic", "Петрович")
, new XElement("Birthdate", DateTime.Parse("1989-01-23")));
// находим нужного доктора
var ourDoctor = xdoc.Descendants("DOCTOR")
.Where(x => x.Element("surname")
.Value.Equals(doctorSurname)).FirstOrDefault();
// и добавляем пациента к доктору
if (ourDoctor != null)
{
// Проверка существования тега ELEMENTS
if (!ourDoctor.Elements(PATIENTS).Any())
ourDoctor.Add(new XElement(PATIENTS));
// Проверьте, если пациент уже существует, чтобы избежать дубликатов
bool duplicatePatient = false;
foreach (var elem in ourDoctor.Element(PATIENTS).Elements(PATIENT))
{
duplicatePatient = XNode.DeepEquals(elem, patient);
if (duplicatePatient)
break;
}
// пациент не существует
if(!duplicatePatient)
{
ourDoctor.Element(PATIENTS).Add(patient);
// сохраняем в файл
xdoc.Save(inputDocument);
}
}
}