Интерфейс SAX
SAX — это стандартный интерфейс на основе событий для парсеров XML. Интерфейс Qt следует структуре реализации SAX2 на Java. Его схема именования была адаптирована для соответствия соглашениям об именовании Qt. Подробности о SAX2 можно найти по адресу http://www.saxproject.org.
Поддержка фильтров SAX2 и фабрики читателей находится в разработке. Реализация Qt не включает классы совместимости SAX1, присутствующие в интерфейсе Java.
Введение в SAX2
Интерфейс SAX2 — это механизм обработки событий, предоставляющий пользователю информацию о документе. «Событие» в данном контексте — это нечто, сообщаемое парсером, например, он обнаружил открывающий тег или закрывающий тег и т. д.
Для большей наглядности рассмотрим следующий пример:
<quote>A quotation.</quote>
При чтении (парсер SAX2 обычно называется «читателем») вышеуказанного документа будут сгенерированы три события:
- Возникает открывающий тег (
<quote>). - Найдены данные символов (т. е. текст) «A quotation».
- Обработан закрывающий тег (
</quote>).
Каждый раз, когда возникает такое событие, парсер сообщает о нём; вы можете настроить обработчики событий для реагирования на эти события.
Хотя это быстрый и простой подход к чтению XML-документов, манипулирование данными затруднено, поскольку данные не хранятся, а обрабатываются и отбрасываются последовательно. Интерфейс DOM считывает и хранит весь документ в структуре дерева; это требует больше памяти, но упрощает манипулирование структурой документа.
Модуль Qt XML предоставляет абстрактный класс QXmlReader, определяющий интерфейс для потенциальных читателей SAX2. Qt включает реализацию читателя QXmlSimpleReader, которую легко адаптировать путём наследования.
Читатель сообщает о событиях обработки посредством специальных классов-обработчиков:
| Класс обработчика | Описание |
|---|---|
| QXmlContentHandler | Сообщает о событиях, связанных с содержимым документа (например, открывающий тег или символы). |
| QXmlDTDHandler | Сообщает о событиях, связанных с DTD (например, объявления обозначений). |
| QXmlErrorHandler | Сообщает об ошибках или предупреждениях, возникших во время обработки. |
| QXmlEntityResolver | Сообщает о внешних сущностях во время обработки и позволяет пользователям разрешать внешние сущности самостоятельно вместо передачи этой задачи читателю. |
| QXmlDeclHandler | Сообщает о дополнительных событиях, связанных с DTD (например, объявления атрибутов). |
| QXmlLexicalHandler | Сообщает о событиях, связанных с лексической структурой документа (начало DTD, комментарии и т. д.). |
Эти классы — абстрактные классы, описывающие интерфейс. Класс QXmlDefaultHandler предоставляет реализацию по умолчанию «ничего не делать» для всех из них. Поэтому пользователям необходимо только переопределять функции QXmlDefaultHandler, которые их интересуют.
Для чтения входных XML-данных используется специальный класс QXmlInputSource.
Помимо уже упомянутых, следующие классы поддержки SAX2 обеспечивают дополнительную полезную функциональность:
| Класс | Описание |
|---|---|
| QXmlAttributes | Используется для передачи атрибутов в событии открытия элемента. |
| QXmlLocator | Используется для получения фактического положения обработки события. |
| QXmlNamespaceSupport | Используется для реализации поддержки пространств имён для читателя. Обратите внимание, что пространства имён не изменяют поведение обработки. Они просто сообщаются через обработчик. |
Пример SAX-закладок иллюстрирует, как наследовать от QXmlDefaultHandler для чтения XML-файла закладок (XBEL) и как создавать XML вручную.
Функции SAX2
Поведение XML-читателя зависит от поддержки им определённых дополнительных функций. Например, читатель может иметь функцию «сообщать об атрибутах, используемых для объявления пространств имён и префиксов, наряду с локальным именем тега». Как и любая другая функция, она имеет уникальное имя, представленное URI: оно называется http://xml.org/sax/features/namespace-prefixes.
Реализация SAX2 в Qt может сообщить, обладает ли читатель определённой функциональностью, используя функцию QXmlReader::hasFeature(). Доступные функции можно проверить с помощью QXmlReader::feature(), и включать или выключать с помощью QXmlReader::setFeature().
Рассмотрим пример
<document xmlns:book = 'http://example.com/fnord/book/'
xmlns = 'http://example.com/fnord/' > Читатель, который не поддерживает функцию http://xml.org/sax/features/namespace-prefixes, будет сообщать об имени элемента document, но не об его атрибутах xmlns:book и xmlns со значениями. Читатель с функцией http://xml.org/sax/features/namespace-prefixes сообщает об атрибутах пространства имён, если функция feature включена.
Другие функции включают http://xml.org/sax/features/namespace (обработка пространств имён, подразумевает http://xml.org/sax/features/namespace-prefixes) и http://xml.org/sax/features/validation (возможность сообщать об ошибках валидации).
Хотя SAX2 предоставляет пользователю возможность определять и реализовывать необходимые функции, поддержка http://xml.org/sax/features/namespace (и, следовательно, http://xml.org/sax/features/namespace-prefixes) является обязательной. Реализация QXmlSimpleReader интерфейса QXmlReader поддерживает их и может выполнять обработку пространств имён.
QXmlSimpleReader не является валидирующей, поэтому не поддерживает http://xml.org/sax/features/validation.
Поддержка пространств имён через функции
Как мы видели в предыдущем разделе, мы можем настроить поведение читателя, когда дело доходит до обработки пространств имён. Это делается путём включения и выключения функций http://xml.org/sax/features/namespaces и http://xml.org/sax/features/namespace-prefixes.
Они влияют на поведение отчёта следующим образом:
- Можно сообщать о префиксах и локальных частях элементов и атрибутов пространств имён.
- Сообщаются квалифицированные имена элементов и атрибутов.
- Читатель вызывает QXmlContentHandler::startPrefixMapping() и QXmlContentHandler::endPrefixMapping().
- Сообщаются атрибуты, объявляющие пространства имён (т. е. атрибут xmlns и атрибуты, начинающиеся с xmlns:).
Рассмотрим следующий элемент:
<author xmlns:fnord = 'http://example.com/fnord/'
title="Ms"
fnord:title="Goddess"
name="Eris Kallisti"/> Если http://xml.org/sax/features/namespace-prefixes установлено в значение true, читатель сообщит о четырёх атрибутах; но если функция namespace-prefixes установлена в false, то только о трёх, при этом атрибут xmlns:fnord, определяющий пространство имён, будет «невидимым» для читателя.
Функция http://xml.org/sax/features/namespaces отвечает за отчёт о локальных именах, префиксах пространств имён и URI. Если http://xml.org/sax/features/namespaces установлено в значение true, парсер сообщит о title как о локальном имени атрибута fnord:title, fnord — префикс пространства имён, а http://example.com/fnord/ — URI пространства имён. Если http://xml.org/sax/features/namespaces установлено в false, ни одно из них не сообщается.
В текущей реализации классы Qt XML следуют определению, что префикс xmlns сам по себе не связан ни с каким пространством имён (см. http://www.w3.org/TR/1999/REC-xml-names-19990114/#ns-using). Следовательно, даже при установленных в значение true обеих функций http://xml.org/sax/features/namespaces и http://xml.org/sax/features/namespace-prefixes читатель не вернёт ни локальное имя, ни префикс, ни URI пространства имён для xmlns:fnord.
В будущем это может быть изменено, следуя предложению W3C http://www.w3.org/2000/xmlns/ для связывания xmlns со пространством имён http://www.w3.org/2000/xmlns.
Как предписывает стандарт SAX2, QXmlSimpleReader по умолчанию имеет http://xml.org/sax/features/namespaces, установленное в значение true, а http://xml.org/sax/features/namespace-prefixes — в значение false. При изменении этого поведения с помощью QXmlSimpleReader::setFeature() обратите внимание, что комбинация обоих функций, установленных в значение false, является незаконной.
Резюме
QXmlSimpleReader реализует следующее поведение:
| (namespaces, namespace-prefixes) | Префикс и локальная часть пространства имён | Квалифицированные имена | Сопоставление префиксов | Атрибуты xmlns |
|---|---|---|---|---|
| (true, false) | Да | Да* | Да | Нет |
| (true, true) | Да | Да | Да | Да |
| (false, true) | Нет* | Да | Нет* | Да |
| (false, false) | Незаконно | |||
Поведение записей, помеченных звёздочкой (*), не определено в SAX.
Свойства
Свойства — более общее понятие. Они имеют уникальное имя, представленное URI, но их значение — void*. Таким образом, в качестве значения свойства может использоваться практически всё. Однако это понятие сопряжено с некоторыми опасностями: нет способа обеспечить тип безопасности; пользователь должен следить за тем, чтобы он передавал правильный тип. Свойства полезны, если читатель поддерживает специальные классы обработчиков.
URI, используемые для функций и свойств, часто напоминают URL, например, http://xml.org/sax/features/namespace. Это не означает, что требуемые данные находятся по этому адресу. Это просто способ определения уникальных имён.
Любой может определять и использовать новые свойства SAX2 для своих читателей. Поддержка свойств необязательна.
Для установки или запроса свойств предоставляются следующие функции: QXmlReader::setProperty(), QXmlReader::property() и QXmlReader::hasProperty().
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.13/xml-sax.html