Перейти к основному содержимому

XML парсер на C#

XML парсер на C#

XML (eXtensible Markup Language) — это текстовый формат для хранения и передачи структурированных данных. В экосистеме .NET существует несколько способов работы с XML: от низкоуровневого чтения через XmlReader до высокоуровневой десериализации объектов с помощью XmlSerializer. Ниже представлены три основных подхода к парсингу XML-документов на C#.


1. Парсинг через XmlDocument (DOM-подход)

Этот метод загружает весь XML-документ в память как дерево узлов. Он удобен для небольших файлов и случаев, когда требуется многократный доступ к разным частям документа.

Пример XML-файла (books.xml):

<?xml version="1.0" encoding="utf-8"?>
<Library>
<Book id="1">
<Title>Война и мир</Title>
<Author>Лев Толстой</Author>
<Year>1869</Year>
</Book>
<Book id="2">
<Title>1984</Title>
<Author>Джордж Оруэлл</Author>
<Year>1949</Year>
</Book>
</Library>

Код парсера:

using Система;
using Система.Xml;

class XmlDocumentParser
{
static void Main()
{
XmlDocument doc = new();
doc.Load("books.xml");

XmlNodeList books = doc.SelectNodes("/Library/Book");

foreach (XmlNode book in books)
{
string id = book.Attributes?["id"]?.Value ?? "N/A";
string title = book["Title"]?.InnerText ?? "Не указано";
string author = book["Author"]?.InnerText ?? "Не указано";
string year = book["Year"]?.InnerText ?? "Не указан";

Console.WriteLine($"ID: {id}");
Console.WriteLine($"Название: {title}");
Console.WriteLine($"Автор: {author}");
Console.WriteLine($"Год: {year}");
Console.WriteLine(new string('-', 30));
}
}
}

Особенности:

  • Поддержка XPath-выражений через SelectNodes и SelectSingleNode.
  • Полный контроль над структурой документа.
  • Высокое потребление памяти при больших файлах.

2. Парсинг через XmlReader (потоковый подход)

XmlReader читает XML последовательно, не загружая всё в память. Это предпочтительный способ для обработки больших файлов.

using Система;
using Система.Xml;

class XmlStreamReaderParser
{
static void Main()
{
using XmlReader reader = XmlReader.Create("books.xml");

while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "Book")
{
string id = reader.GetAttribute("id") ?? "N/A";
Console.WriteLine($"Книга ID: {id}");

// Читаем дочерние элементы
if (reader.ReadToDescendant("Title"))
{
string title = reader.ReadElementContentAsString();
Console.WriteLine($" Название: {title}");
}

if (reader.ReadToNextSibling("Author"))
{
string author = reader.ReadElementContentAsString();
Console.WriteLine($" Автор: {author}");
}

if (reader.ReadToNextSibling("Year"))
{
string year = reader.ReadElementContentAsString();
Console.WriteLine($" Год: {year}");
}

Console.WriteLine(new string('-', 30));
}
}
}
}

Особенности:

  • Минимальное потребление памяти.
  • Однопроходная обработка — нельзя вернуться к предыдущему узлу.
  • Требует аккуратного управления состоянием чтения.

3. Десериализация в объекты через XmlSerializer

Если структура XML известна заранее, можно описать её с помощью классов и автоматически преобразовать XML в объекты C#.

Шаг 1: Определение моделей

using Система;
using Система.Collections.Generic;
using Система.Xml.Serialization;

[XmlRoot("Library")]
public class Library
{
[XmlElement("Book")]
public List<Book> Books { get; set; } = new();
}

public class Book
{
[XmlAttribute("id")]
public int Id { get; set; }

[XmlElement("Title")]
public string Title { get; set; } = string.Empty;

[XmlElement("Author")]
public string Author { get; set; } = string.Empty;

[XmlElement("Year")]
public int Year { get; set; }
}

Шаг 2: Десериализация

using Система;
using Система.IO;
using Система.Xml.Serialization;

class XmlSerializationParser
{
static void Main()
{
XmlSerializer serializer = new(typeof(Library));

using FileStream fs = File.OpenRead("books.xml");
Library library = (Library)serializer.Deserialize(fs);

foreach (var book in library.Books)
{
Console.WriteLine($"ID: {book.Id}");
Console.WriteLine($"Название: {book.Title}");
Console.WriteLine($"Автор: {book.Author}");
Console.WriteLine($"Год: {book.Year}");
Console.WriteLine(new string('-', 30));
}
}
}

Особенности:

  • Автоматическое сопоставление XML-элементов со свойствами объекта.
  • Требует атрибутов ([XmlElement], [XmlAttribute]) для точного контроля.
  • Не подходит для динамических или неизвестных схем.

Сравнение подходов

КритерийXmlDocumentXmlReaderXmlSerializer
Потребление памятиВысокоеМинимальноеУмеренное
ПроизводительностьСредняяВысокаяСредняя
Удобство использованияВысокоеНизкоеОчень высокое
Поддержка XPathДаНетНет
Подходит для больших файловНетДаОграниченно

Обработка ошибок и валидация

Для надёжной работы рекомендуется оборачивать парсинг в блоки try-catch:

try
{
XmlDocument doc = new();
doc.Load("books.xml");
// ... обработка
}
catch (XmlException ex)
{
Console.WriteLine($"Ошибка XML: {ex.Message}");
}
catch (FileNotFoundException)
{
Console.WriteLine("Файл не найден.");
}
catch (Exception ex)
{
Console.WriteLine($"Неожиданная ошибка: {ex.Message}");
}

Также можно использовать XSD-схемы для валидации XML перед парсингом, но это выходит за рамки базового примера.


См. также

Другие статьи этого же раздела в боковом меню (как на странице «О разделе»).