Тип XML

Тип данных xml можно использовать для хранения данных XML. Его преимущество перед хранением данных XML в текстовом поле состоит в том, что он проверяет вводимые значения на корректность, а кроме того для выполнения над ним типобезопасных операций существуют вспомогательные функции; см. раздел Функции XML. Для использования этого типа данных установку необходимо скомпилировать с конфигурацией configure --with-libxml.

Тип xml может сохранять правильно оформленные «документы», в соответствии со стандартом XML, а также фрагменты «содержимого», характеризующиеся как менее ограниченные «узлы документа» в модели данных XQuery и XPath. Грубо говоря, это означает, что в фрагментах содержимого может быть более одного элемента верхнего уровня или символьного узла. Определить, является ли конкретное значение xml полным документом или только фрагментом содержимого, можно при помощи выражения xml-значение IS DOCUMENT.

Информацию об ограничениях и совместимости для типа данных xml можно найти в подразделе Ограничения XML и соответствие SQL/XML.


Создание значений XML

Чтобы получить значение типа xml из символьных данных, используйте функцию xmlparse:

XMLPARSE ( { DOCUMENT | CONTENT } значение)

Примеры:

XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</title><chapter>...</chapter></book>')
XMLPARSE (CONTENT 'abc<foo>bar</foo><bar>foo</bar>')

Хотя в соответствии со стандартом SQL это единственный способ преобразовать символьные строки в значения XML, также можно использовать форматы, специфичные для QHB:

xml '<foo>bar</foo>'
'<foo>bar</foo>'::xml

Тип xml не проверяет входные значения по схеме объявления типа документа (DTD), даже когда они указывают на DTD. В настоящее время также отсутствует встроенная поддержка проверки на соответствие другим языкам схем XML, например XML Schema.

Обратная операция, получение символьного строкового значения из xml, выполняется с помощью функции xmlserialize:

XMLSERIALIZE ( { DOCUMENT | CONTENT } значение AS тип )

тип может быть иметь значение character, character varying или text (или их псевдонимы). Опять же, согласно стандарту SQL, это единственный способ преобразования между типами xml и символьными типами, но QHB позволяет просто приводить значение к нужному типу.

Когда значение символьной строки приводится к типу xml или наоборот без помощи функций XMLPARSE или XMLSERIALIZE соответственно, выбор режима DOCUMENT или CONTENT определяется параметром конфигурации сеанса «XML option», который можно установить с помощью стандартной команды:

SET XML OPTION { DOCUMENT | CONTENT };

или записью, более характерной для QHB:

SET xmloption TO { DOCUMENT | CONTENT };

По умолчанию установлен режим CONTENT, поэтому допускаются все формы XML-данных.


Обработка кодировки

При работе с разными кодировками символов на стороне клиента и сервера, а также в передаваемых через них XML-данных необходимо соблюдать осторожность. Когда передача запросов на сервер и возврат результатов клиенту происходит в текстовом режиме (это нормальный режим), QHB преобразует все символьные данные, передаваемые от клиента серверу и наоборот, в кодировку для соответствующей стороны; см. раздел Поддержка кодировок. Сюда входят и строковые представления значений XML, такие как, например, в приведенных выше примерах. Обычно это означает, что объявления кодировки, содержащиеся в XML-данных, могут стать недействительными при преобразовании символьных данных в другие кодировки в процессе перемещения между клиентом и сервером, поскольку объявление встроенной кодировки не изменяется. Для решения этой проблемы объявления кодировки, содержащиеся в символьных строках, представленных для ввода в тип xml, игнорируются, и предполагается, что содержимое находится в текущей серверной кодировке. Следовательно, для правильной обработки таких строк XML-данных клиент должен передавать их в своей текущей кодировке. Именно клиент перед отправкой документов на сервер должен либо преобразовать их в свою текущую кодировку, либо изменить эту кодировку соответствующим образом. При выводе значения типа xml не будут содержать объявления кодировки, и клиент должен предполагать, что все данные находятся в его текущей кодировке.

Когда передача параметров запроса на сервер и возврат результатов клиенту происходит в двоичном режиме, преобразование кодировки не выполняется, поэтому возникает другая ситуация. В этом случае будет наблюдаться объявление кодировки в XML-данных, а при его отсутствии предполагается, что данные закодированы в UTF-8 (что соответствует стандарту XML; обратите внимание, что QHB не поддерживает UTF-16). При выводе данные будут содержать объявление кодировки, выбранной на стороне клиента, однако если это UTF-8, объявление будет опущено.

Нет необходимости говорить, что обработка XML-данных с помощью QHB будет менее подвержена ошибкам и более эффективна, если и в XML-данных, и на стороне клиента, и на стороне сервера будет использована одна кодировка. Поскольку внутри XML-данные закодированы в UTF-8, вычисления будут наиболее эффективными, если на сервере также выбрана кодировка UTF-8.

ВНИМАНИЕ!
Некоторые функции, связанные с XML, могут вообще не работать с данными, отличными от ASCII, если кодировка сервера не соответствует UTF-8. В частности, известно, что эта проблема есть у функций xmltable() и xpath().


Обращение к значениям XML

Тип данных xml необычен тем, что не предоставляет операторов сравнения. Это связано с тем, что для XML-данных не существует четко определенного и универсально полезного алгоритма сравнения. Одним из следствий этого является то, что вы не можете получить строки, сравнивая столбец xml со значением поиска. Поэтому обычно значения XML должны дополняться отдельным ключевым полем, например ID. Альтернативное решение для сравнения значений XML — сначала преобразовать их в символьные строки, но обратите внимание, что сравнение этих строк совершенно бесполезно для сравнения XML-данных.

Поскольку для типа данных xml нет операторов сравнения, невозможно создать индекс непосредственно для столбца этого типа. Если требуется быстрый поиск в XML-данных, это ограничение можно обойти, приведя выражение к типу символьной строки и проиндексировав его, либо проиндексировав выражение XPath. Конечно, фактический запрос следует скорректировать для поиска по индексируемому выражению.

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