Read this in English
Первая страничка.
Обо мне
Oracle
Ада
Гостевая книга
Counter
AdaXml API

Предлогаю обсудить SAX интерфейс для Ады.

В двух словах работа SAX парсера заключется в следующем. Программа пользователя регистрирует функции оповещения(обработчик) на парсере SAX и запускает разбор xml передовая url досумента парсеру. Парсер просматривает xml и вызывает зарегистрированные функции в нужные моменты (при начале/конце разбота, начале/конце тега, наличии символьной информации). Так в момент появления нового тега функция пользователя получает имя тега и список его атрибутов.

Рассмотрим общую структуру XML парсера реализованного на Аде.

xml документ, представленный как Ada.Streams.Stream Тип данных: Ada.Streams.Storage_Elenemt
механизм поддержки разных кодировок
буфер парсера Тип данных: Character, Wide_Character
парсер
параметры передаваемые обработчику Тип данных: access String, access Wide_String
обработчик

Для быстрой работы парсера необходимо реализовать эффективную передачу информации внутри этой структуры. Это накладывает следующие ограничения:

  • механизм поддержки разных кодировок должен быть способен преобразовывать масив Storage_Elements в String или Wide_String. Так как Storage_Elements'Size может меняться в различных окружениях, то эта часть является зависимой от окружения.
  • парсер должен эффективно передовать данные обработчику пользователя. Передача имени тега и символьных данных может быть выполнена так - callUserHandler( buffer(10..20) ). При этом мы избежим копирование данных т.к. компилятор выберет передачу по ссылке. Вопрос состоит в передаче списка атрибутов. Рассмотрим следующие варианты:
    • function getAttrValue(al:AttrList;index:Positive) return String; Это требует "копирование в" / "извлечение из" вторичного стека.
    • function getAttrValue(al:AttrList;index:Positive) return access String; Это требует выделения динамической памяти, т.к. buffer(10..20)'Access - не разрешается. Также необходимо соглашение между парсером и обработчиком пользователя об освобождении динамической памяти, чтобы избежать висячих ссылок и утечки памяти.

Другим вопросом является использование символьных типов. Спецификация XML требует от парсера разбирать XML в кодировках UTF8 и Latin-1, как минимум. Логично было бы испоьзовать как символьный тип Wide_Character. Но иногда программисту удобнее использовать CHaracter. Как возможный вариант можно было бы условиться передовать String аргумент в UTF-8 кодировке. Это соответствует стандарту, но усложняут программирование так, как один символ UTF-8 занимает несколько элементов в строке.

В качестве практического примера и основы для дальнейшей работы предлагаю SAX парсер на Аде.