Работа с XML в Rust: парсинг, создание и сериализация данных

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с XML в Rust: библиотеки и инструменты

XML (eXtensible Markup Language) остаётся одним из ключевых форматов для обмена данными, конфигурационных файлов и документооборота. Экосистема Rust предлагает несколько зрелых решений для работы с XML — от высокопроизводительного потокового парсинга до удобной сериализации через serde. В этой статье мы разберём три наиболее популярных инструмента: quick-xml, roxmltree и serde-xml-rs.

Почему Rust для работы с XML?

Rust сочетает скорость C/C++ с безопасностью памяти. При обработке больших XML-файлов (например, медицинских записей или геоданных) это критично. Библиотеки для XML в Rust написаны с нуля на Rust (без привязок к C), что гарантирует потокобезопасность и предсказуемую производительность.

Библиотеки для работы с XML в Rust

  • quick-xml — высокопроизводительный потоковый парсер (SAX-стиль) и writer. Минимальное потребление памяти, идеален для больших файлов.
  • roxmltree — DOM-парсер, строящий дерево документа. Удобен для навигации и модификации.
  • serde-xml-rs — сериализация/десериализация структур Rust в/из XML через крейт serde. Максимальная интеграция с типовой системой.

Установка

Добавьте зависимости в Cargo.toml:

[dependencies]
quick-xml = "0.36"        # потоковый парсер
roxmltree = "0.20"        # DOM-парсер
serde-xml-rs = "0.6"      # сериализация (в паре с serde)
serde = { version = "1.0", features = ["derive"] }

Парсинг XML с помощью quick-xml

quick-xml работает в режиме Reader — последовательно читает токены (открытие тега, текст, закрытие тега). Это экономит память: вы обрабатываете документ по частям, не загружая его целиком.

Пример: чтение RSS-ленты

use quick_xml::Reader;
use quick_xml::events::Event;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let xml = r#"
    <rss version="2.0">
        <channel>
            <title>Новости Rust</title>
            <item>
                <title>Вышел Rust 1.78</title>
                <link>https://example.com/rust-1.78</link>
            </item>
        </channel>
    </rss>"#;

    let mut reader = Reader::from_str(xml);
    reader.trim_text(true);

    let mut buf = Vec::new();
    let mut in_item = false;

    loop {
        match reader.read_event_into(&mut buf) {
            Ok(Event::Start(ref e)) => {
                if e.name().as_ref() == b"item" {
                    in_item = true;
                }
            }
            Ok(Event::Text(ref e)) => {
                if in_item {
                    let text = e.unescape()?;
                    println!("{}", text);
                }
            }
            Ok(Event::End(ref e)) => {
                if e.name().as_ref() == b"item" {
                    in_item = false;
                }
            }
            Ok(Event::Eof) => break,
            Err(e) => eprintln!("Ошибка: {}", e),
            _ => ()
        }
        buf.clear();
    }
    Ok(())
}

Вывод: заголовки всех <item>.

DOM-парсинг с roxmltree

roxmltree загружает весь XML в дерево. Это удобно, когда нужно многократно обращаться к разным узлам или модифицировать структуру.

Пример: извлечение атрибутов и текста

use roxmltree::Document;

fn main() {
    let data = r#"
    <config version="1.0">
        <database>
            <host>localhost</host>
            <port>5432</port>
        </database>
    </config>"#;

    let doc = Document::parse(data).unwrap();

    // Получаем атрибут корневого элемента
    if let Some(root) = doc.root_element() {
        let version = root.attribute("version").unwrap_or("?");
        println!("Версия конфига: {}", version);
    }

    // Ищем элемент <host>
    if let Some(host) = doc.descendants().find(|n| n.has_tag_name("host")) {
        let text = host.text().unwrap_or("");
        println!("Хост                    

Рекомендаций