8.13. Тип XML#
8.13. Тип XML #
Тип данных xml
может использоваться для хранения XML-данных. Его преимущество перед хранением XML-данных в поле text
заключается в том, что он проверяет входные значения на правильность формата, и имеются функции поддержки для выполнения безопасных операций с ним; см. Раздел 9.15. Для использования этого типа данных требуется установка, построенная с использованием configure --with-libxml
.
Тип xml
может хранить правильно оформленные
“документы”, определенные стандартом XML, а также
“фрагменты” содержимого, которые определены ссылаются
на более гибкий
“узел документа”
модели данных XQuery и XPath.
Грубо говоря, это означает, что фрагменты содержимого могут иметь
более одного элемента верхнего уровня или символьного узла. Выражение
может использоваться для определения, является ли конкретное значение xmlvalue
IS DOCUMENTxml
полным документом или только фрагментом содержимого.
Сведения о ограничениях и совместимости для типа данных xml
можно найти в разделе Раздел D.3.
8.13.1. Создание XML-значений #
Для создания значения типа xml
из символьных данных
используйте функцию
xmlparse
:
XMLPARSE ( { DOCUMENT | CONTENT } value
)
Примеры:
XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</title><chapter>...</chapter></book>') XMLPARSE (CONTENT 'abc<foo>bar</foo><bar>foo</bar>')
В то время как это единственный способ преобразования символьных строк в XML значения в соответствии со стандартом SQL, существуют специфичные для PostgreSQL синтаксисы:
xml '<foo>bar</foo>' '<foo>bar</foo>'::xml
может также использоваться.
Тип xml
не проверяет входные значения на соответствие
декларации типа документа
(DTD),
даже когда входное значение указывает на DTD.
В настоящее время также нет встроенной поддержки для проверки по
другим языкам схемы XML, таким как XML Schema.
Обратная операция, создающая символьное строковое значение из
xml
, использует функцию
xmlserialize
:
XMLSERIALIZE ( { DOCUMENT | CONTENT }value
AStype
[ [ NO ] INDENT ] )
type
может быть character
, character varying
или text
(или псевдонимом для одного из них). Согласно стандарту SQL, это единственный способ преобразования между типом xml
и символьными типами, но PostgreSQL также позволяет просто привести значение.
The INDENT
опция приводит к тому, что результат будет
красиво отформатирован, в то время как NO INDENT
(что является
значением по умолчанию) просто выводит исходную строку ввода. Приведение к символьному
типу также производит исходную строку.
Когда строковое значение символов приводится к типу xml
или обратно без использования функций XMLPARSE
или XMLSERIALIZE
, соответственно, выбор между DOCUMENT
и CONTENT
определяется “опцией XML”.
параметр конфигурации сессии, который может быть установлен с помощью
стандартной команды:
SET XML OPTION { DOCUMENT | CONTENT };
или более похожий на PostgreSQL синтаксис
SET xmloption TO { DOCUMENT | CONTENT };
По умолчанию используется CONTENT
, поэтому разрешены все формы XML данных.
8.13.2. Обработка кодировки #
Необходимо быть осторожным при работе с несколькими кодировками символов на клиенте, сервере и в передаваемых через них XML данных. При использовании текстового режима для передачи запросов на сервер и результатов запросов клиенту (что является нормальным режимом), PostgreSQL преобразует все символьные данные, передаваемые между клиентом и сервером, а также наоборот, в кодировку символов соответствующего конца; см. Раздел 22.3. Это включает строковые представления значений XML, такие как в приведенных выше примерах. Это обычно означает, что объявления кодировки, содержащиеся в XML данных, могут стать недействительными, поскольку символьные данные преобразуются в другие кодировки при передвижении между клиентом и сервером, поскольку вложенное объявление кодировки не изменяется. Для справления с этим поведением объявления кодировки, содержащиеся в символьных строках, представленных для ввода в тип xml
, игнорируются, и предполагается, что содержимое находится в текущей кодировке сервера. Следовательно, для правильной обработки символьные строки XML данных должны быть отправлены с клиента в текущей кодировке клиента. Клиенту необходимо либо преобразовывать документы в текущую кодировку клиента перед отправкой их на сервер, либо соответствующим образом настраивать кодировку клиента. При выводе значения типа xml
не будет содержать объявления кодировки, и клиенты должны предполагать, что все данные находятся в текущей кодировке клиента.
При использовании двоичного режима для передачи параметров запроса на сервер и результатов запроса обратно клиенту, не выполняется преобразование кодировки, поэтому ситуация отличается. В этом случае будет учитываться объявление кодировки в XML-данных, и если оно отсутствует, данные будут считаться в кодировке UTF-8 (как требуется стандартом XML; обратите внимание, что PostgreSQL не поддерживает UTF-16). При выводе данные будут иметь объявление кодировки, указывающее кодировку клиента, за исключением случая, когда кодировка клиента является UTF-8, в этом случае оно будет не указано.
Не нужно говорить, что обработка XML-данных с использованием PostgreSQL будет менее подвержена ошибкам и более эффективной, если кодировка XML-данных, кодировка клиента и кодировка сервера совпадают. Поскольку XML-данные обрабатываются внутренне в UTF-8, вычисления будут наиболее эффективными, если кодировка сервера также является UTF-8.
Предостережение
Некоторые функции, связанные с XML, могут не работать совсем с не-ASCII данными, когда кодировка сервера не UTF-8. Это известная проблема для функций xmltable()
и xpath()
в частности.
8.13.3. Доступ к значениям XML #
Тип данных xml
необычен тем, что не предоставляет никаких операторов сравнения. Это связано с отсутствием четко определенного и универсально полезного алгоритма сравнения для данных XML. Одним из следствий этого является то, что нельзя получить строки, сравнивая столбец xml
с поисковым значением. Значения XML, следовательно, обычно должны сопровождаться отдельным ключевым полем, таким как идентификатор. Альтернативным решением для сравнения значений XML является их предварительное преобразование в символьные строки, но следует отметить, что сравнение символьных строк имеет мало общего с полезным методом сравнения XML.
Поскольку для типа данных xml
нет операторов сравнения, невозможно создать индекс непосредственно на столбце этого типа. Если требуются быстрые поиски в данных XML, возможные обходные пути включают приведение выражения к типу символьной строки и индексацию этого выражения или индексацию выражения XPath. Конечно, фактический запрос должен быть скорректирован для поиска по индексированному выражению.
Функциональность полнотекстового поиска в PostgreSQL также может использоваться для ускорения поиска полных документов в XML-данных. Однако необходимая поддержка предварительной обработки пока не доступна в дистрибутиве PostgreSQL.