REXML¶
REXML — это парсер XML для языка программирования Ruby, написанный целиком на самом Ruby. Он является частью стандартной библиотеки Ruby, начиная с версии 1.8, и предоставляет средства для чтения, создания, обработки и манипулирования XML-документами без необходимости использования внешних библиотек или расширений на C.
¶История
REXML был создан японским разработчиком Шоном О’Брайеном (Sean O’Brien) и впервые включён в стандартную поставку Ruby в 2003 году, с выходом версии 1.8. До этого основным способом работы с XML в Ruby была библиотека XMLParser, которая была обёрткой над libxml2 (написанным на C). REXML был разработан как «чисто Ruby»-решение, что обеспечивало его кроссплатформенность и лёгкость установки — для его использования не требовалось компилировать внешние модули. Это было особенно важно в ранние годы Ruby, когда экосистема расширений на C была менее развита.
С появлением более производительных альтернатив, таких как Nokogiri (обёртка над libxml2), REXML постепенно утратил популярность для высоконагруженных задач. Тем не менее, он остаётся частью стандартной библиотеки Ruby и используется в ситуациях, где важна простота, отсутствие внешних зависимостей или встроенная поддержка без дополнительных gem'ов.
¶Архитектура и компоненты
REXML построен на основе событийно-ориентированной модели (SAX-подобный парсер) и модели объектной модели документа (DOM). Основные классы и модули библиотеки:
- REXML::Document — представляет целый XML-документ. Является корневым узлом дерева.
- REXML::Element — представляет элемент XML (тег). Содержит имя, атрибуты и дочерние узлы.
- REXML::Text — представляет текстовый узел (содержимое между тегами).
- REXML::Attribute — представляет атрибут элемента.
- REXML::Instruction — представляет инструкцию обработки (например,
<?xml version="1.0"?>). - REXML::Comment — представляет комментарий XML.
- REXML::XPath — модуль для выполнения запросов XPath к документу.
- REXML::Parsers::StreamParser — SAX-подобный парсер для потоковой обработки больших XML-файлов без загрузки всего дерева в память.
- REXML::Formatters — модули для форматирования вывода XML (например,
REXML::Formatters::Prettyдля отступов).
¶Возможности
REXML предоставляет полный набор функций для работы с XML:
- Парсинг — чтение XML из строки (
Document.new(xml_string)) или из файла (Document.new(File.read("file.xml"))). - Создание — построение XML-документа программно через создание объектов
Element,Textи т.д. - Навигация — доступ к элементам по имени, по XPath-запросам (
element.elements["//book/title"]). - Модификация — добавление, удаление и изменение элементов, атрибутов и текста.
- Форматирование — вывод XML в читаемом виде с отступами или в компактной форме.
- Валидация — базовая проверка корректности XML (REXML не поддерживает полноценную валидацию по DTD или XSD, но может обнаруживать синтаксические ошибки).
¶Производительность и ограничения
REXML — один из самых медленных парсеров XML для Ruby, что обусловлено его реализацией на чистом Ruby. В тестах производительности он значительно уступает Nokogiri и Ox (написанным на C). Основные ограничения:
- Скорость — при обработке больших документов (сотни мегабайт) REXML может быть в 10-50 раз медленнее Nokogiri.
- Потребление памяти — DOM-модель загружает весь документ в память, что может быть проблематично для очень больших файлов. Для потоковой обработки существует
StreamParser, но он менее удобен для сложных манипуляций. - Поддержка стандартов — REXML не полностью соответствует стандарту XML 1.0 (например, не поддерживает все возможности DTD и пространства имён в полном объёме).
¶Применение
Несмотря на низкую производительность, REXML находит применение в следующих сценариях:
- Образовательные проекты — для изучения работы с XML в Ruby без установки дополнительных библиотек.
- Небольшие конфигурационные файлы — чтение и запись XML-файлов размером до нескольких килобайт.
- Среда без внешних зависимостей — когда требуется минимизировать количество gem'ов (например, в скриптах, запускаемых на серверах с ограниченными правами).
- Тестирование — для создания простых XML-структур в unit-тестах.
- Легаси-проекты — поддержка старого кода, написанного до появления Nokogiri.
¶Пример использования
```ruby require 'rexml/document'
¶Парсинг XML из строки
xml = '<books><book id="1"><title>Ruby Programming</title></book></books>' doc = REXML::Document.new(xml)
¶Доступ к элементу по XPath
title = doc.elements["//book/title"].text puts title # => "Ruby Programming"
¶Создание нового документа
new_doc = REXML::Document.new root = new_doc.add_element("catalog") item = root.add_element("item", {"id" => "123"}) item.add_text("Some item") puts new_doc # => <catalog><item id='123'>Some item</item></catalog> ```
¶Альтернативы
Основные альтернативы REXML в экосистеме Ruby:
- Nokogiri — наиболее популярная библиотека, основанная на libxml2 и libxslt. Обеспечивает высокую производительность, полную поддержку XPath, CSS-селекторов и валидацию. Требует установки gem'а и компиляции C-расширений.
- Ox — высокопроизводительный парсер и генератор XML, написанный на C. Ориентирован на скорость и минимальное потребление памяти.
- LibXML-Ruby — обёртка над libxml2, менее популярная, чем Nokogiri.
- REXML — остаётся встроенным решением для базовых задач.
¶Интересные факты
- REXML — один из немногих парсеров XML, написанных полностью на Ruby, что делает его полностью переносимым между платформами без компиляции.
- В документации Ruby REXML часто приводится как пример для обучения работе с XML, так как его API интуитивно понятен и не требует изучения дополнительных концепций.
- Несмотря на то, что Nokogiri стал стандартом де-факто, REXML по-прежнему входит в стандартную библиотеку Ruby и не планируется к удалению.
