Работа с XML в C# (.NET): от основ до продвинутых техник
XML (eXtensible Markup Language) остаётся одним из ключевых форматов для хранения и передачи структурированных данных в экосистеме .NET. Независимо от того, создаёте ли вы конфигурационные файлы, обмениваетесь данными с веб-сервисами или обрабатываете документы, встроенные средства C# предоставляют гибкие и производительные инструменты для работы с XML. В этой статье мы разберём три основных подхода: классический XmlDocument, современный XDocument (LINQ to XML) и потоковый XmlReader/XmlWriter.
1. Классический XmlDocument (DOM-модель)
Класс System.Xml.XmlDocument реализует DOM (Document Object Model) — загружает весь XML-документ в оперативную память в виде дерева узлов. Это удобно для небольших и средних документов, когда требуется частая навигация и модификация.
Загрузка и чтение XML
using System.Xml;
XmlDocument doc = new XmlDocument();
doc.Load("books.xml"); // загрузка из файла
// Получение корневого элемента
XmlElement root = doc.DocumentElement;
// Выбор всех элементов book
XmlNodeList books = root.SelectNodes("//book");
foreach (XmlNode book in books)
{
string title = book["title"].InnerText;
string author = book["author"].InnerText;
Console.WriteLine($"{title} — {author}");
}
Создание и сохранение XML
XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement("library");
doc.AppendChild(root);
XmlElement book = doc.CreateElement("book");
book.SetAttribute("id", "1");
XmlElement title = doc.CreateElement("title");
title.InnerText = "Война и мир";
book.AppendChild(title);
root.AppendChild(book);
doc.Save("library.xml");
2. Современный LINQ to XML (XDocument)
Пространство имён System.Xml.Linq предлагает более лаконичный и функциональный API. XDocument и XElement позволяют писать код в стиле LINQ, что особенно удобно при запросах и трансформациях.
Парсинг с помощью XDocument
using System.Xml.Linq;
XDocument doc = XDocument.Load("books.xml");
var books = doc.Descendants("book")
.Select(b => new
{
Title = b.Element("title")?.Value,
Author = b.Element("author")?.Value,
Year = (int)b.Element("year")
});
foreach (var book in books)
{
Console.WriteLine($"{book.Title} ({book.Year})");
}
Создание XML с помощью конструкторов
XDocument doc = new XDocument(
new XElement("library",
new XElement("book",
new XAttribute("id", "1"),
new XElement("title", "Преступление и наказание"),
new XElement("author", "Ф.М. Достоевский")
)
)
);
doc.Save("library.xml");
Преимущества XDocument:
- Поддержка LINQ-запросов для фильтрации и проекции данных.
- Более читаемый синтаксис создания элементов через вложенные конструкторы.
- Автоматическая обработка пространств имён через
XNamespace.
3. Потоковая обработка: XmlReader и XmlWriter
Для работы с большими XML-файлами (сотни мегабайт или гигабайты) использование XmlDocument или XDocument может привести к переполнению памяти. В таких случаях применяются потоковые классы XmlReader и XmlWriter, которые обрабатывают данные последовательно, не загружая весь документ.
Чтение с помощью XmlReader
using (XmlReader reader = XmlReader.Create("large.xml"))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "record")
{
string id = reader.GetAttribute("id");
string value = reader.ReadElementContentAsString();
Console.WriteLine($"ID: {id}, Value: {value}");
}
}
}
Запись с помощью XmlWriter
using (XmlWriter writer = XmlWriter.Create("output.xml"))
{
writer.WriteStartDocument();
writer.WriteStartElement("catalog");
for (int i = 0; i < 1000; i++)
{
writer.WriteStartElement("item");
writer.WriteAttributeString("id", i.ToString());
writer.WriteElementString("name", $"Товар {i}");
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteEndDocument();
}
4. Сериализация объектов в XML
Для преобразования объектов C# в XML и обратно идеально подходит XmlSerializer из System.Xml.Serialization.
using System.Xml.Serialization;
[