Тип XML

Тип данных xml можно использовать для хранения данных XML. Его преимущество перед хранением данных XML в поле text состоит в том, что он проверяет вводимые значения на формальную правильность, и для выполнения с ним типобезопасных операций существуют вспомогательные функции; см. раздел Функции 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 тип [ [ NO ] INDENT ] )

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

С параметром INDENT результат будет выводиться в структурированном виде, тогда как NO INDENT (по умолчанию) просто выводит исходную входную строку. При приведении значения к символьному типу тоже выводится исходная строка.

Когда значение символьной строки приводится к типу 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 должны дополняться отдельным ключевым полем, например идентификатором. Альтернативное решение для сравнения значений XML — сначала преобразовать их в символьные строки, но обратите внимание, что сравнение этих строк совершенно бесполезно для сравнения XML-данных.

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

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