Перейти к основному содержимому

Ограничения XML и совместимость с SQL/XML

примечание

Эта страница переведена при помощи нейросети GigaChat.

Значительные изменения в спецификациях, связанных с XML, в стандарте ISO/IEC 9075-14 (SQL/XML), были внесены в SQL: 2006. Реализация типа данных XML и связанных функций в PostgreSQL во многом следует более раннему изданию 2003 года, с некоторыми заимствованиями из последующих изданий. В частности:

  • Там, где текущий стандарт предоставляет семейство типов XML-данных для хранения «документ» или «содержание» в не типизированной или типизированной версии XML-схемы, а также тип XML(SEQUENCE), предназначенный для хранения произвольных фрагментов содержимого XML, PostgreSQL предоставляет единственный тип xml, который может хранить «документ» или «содержимое». Нет эквивалента стандартного типа «последовательность».
  • PostgreSQL предоставляет две функции, представленные в SQL:2006, но в вариантах, которые используют язык XPath 1.0 вместо XML-запроса, указанного для них в стандарте.

В этом разделе представлены некоторые различия, с которыми можно столкнуться.

Запросы ограничены XPath 1.0

PostgreSQL-специфические функции xpath() и xpath_exists() запрашивают документы XML с использованием языка XPath. PostgreSQL также предоставляет варианты только для XPath стандартных функций XMLEXISTS и XMLTABLE, которые официально используют язык XQuery. Для всех этих функций PostgreSQL полагается на библиотеку libxml2, которая предоставляет только XPath 1.0.

Существует сильная связь между языком XQuery и версиями XPath 2.0 и более поздними: любое выражение, которое синтаксически корректно и успешно выполняется в обоих случаях, дает один и тот же результат (с незначительным исключением для выражений, содержащих числовые ссылки на символы или предопределенные ссылки на сущности, которые XQuery заменяет соответствующим символом, а XPath оставляет их без изменений). Но такой связи нет между этими языками и XPath 1.0, это был более ранний язык и отличается во многих отношениях.

Есть два типа ограничений, о которых следует помнить: ограничение от XQuery до XPath для функций, указанных в стандарте SQL, и ограничение XPath до версии 1.0 как для стандартных, так и для PostgreSQL-специфических функций.

Ограничение XQuery до XPath

Функции XQuery, выходящие за рамки XPath, включают:

  • Выражения XQuery могут создавать и возвращать новые узлы XML, а также все возможные значения XPath. XPath может создавать и возвращать значения атомарных типов (числа, строки и т.д.), но может возвращать только узлы XML, которые уже присутствовали в документах, предоставленных в качестве входных данных для выражения.
  • В XQuery есть конструкции управления для итерации, сортировки и группировки.
  • XQuery позволяет объявлять и использовать локальные функции.

Недавние версии XPath начинают предлагать возможности, перекрывающие эти (такие как функциональный стиль for-each и sort, анонимные функции и parse-xml для создания узла из строки), но такие функции не были доступны до XPath 3.0.

Ограничение XPath до версии 1.0

Для разработчиков, знакомых с XQuery и XPath 2.0 или более поздней версией, XPath 1.0 представляет ряд различий, с которыми приходится сталкиваться:

  • Основной тип выражения XQuery/XPath, sequence , который может содержать узлы XML, атомарные значения или и то, и другое, не существует в XPath 1.0. Выражение 1.0 может производить только набор узлов (содержащий ноль или более узлов XML) или одно атомарное значение.

  • В отличие от последовательности XQuery/XPath, которая может содержать любые желаемые элементы в любом желаемом порядке, набор узлов XPath 1.0 не имеет гарантированного порядка и, как любой набор, не допускает многократного появления одного и того же элемента.

    Примечание

    Библиотека libxml2 действительно всегда возвращает наборы узлов для PostgreSQL с их членами в том же относительном порядке, что и во входном документе. Его документация не обязывает к такому поведению, и выражение XPath 1.0 не может контролировать его.

  • Хотя XQuery/XPath предоставляет все типы, определенные в XML-схеме, и многие операторы и функции над этими типами, XPath 1.0 имеет только наборы узлов и три атомарных типа boolean, double и string.

  • В XPath 1.0 нет условного оператора. Выражение XQuery / XPath, такое как if ( hat ) then hat/@size else "no hat", не имеет эквивалента в XPath 1.0.

  • В XPath 1.0 отсутствует оператор упорядоченного сравнения для строк. Оба "cat" < "dog" и "cat" > "dog" ложны, потому что каждый из них является числовым сравнением двух NaNs. В отличие от этого, = и != сравнивают строки как строки.

  • XPath 1.0 размывает различие между сравнениями значений и общими сравнениями, как их определяют XQuery/XPath. Как sale/@hatsize = 7, так и sale/@customer = "alice" являются сравнениями с экзистенциальной квантификацией, истинными, если существует любой sale со значением данного атрибута, но sale/@taxable = false() - это сравнение значения с эффективным логическим значением всего набора узлов. Это верно только в том случае, если ни один sale вообще не имеет атрибута taxable.

  • В модели данных XQuery/XPath узел документа может иметь либо форму документа (т.е. ровно один верхний элемент с комментариями и инструкциями обработки вне его), либо форму содержимого (с ослабленными ограничениями). Его эквивалент в XPath 1.0, корневой узел, может быть только в форме документа. Это часть причины того, что значение xml, переданное в качестве элемента контекста любой функции PostgreSQL, основанной на XPath, должно находиться в форме документа.

Различия, выделенные здесь, не все из них. В XQuery и версиях XPath 2.0 и более поздних существует режим совместимости с XPath 1.0, а списки функций библиотеки W3C изменений и языковых изменений, применяемых в этом режиме, предлагают более полный (но все еще не исчерпывающий) отчет о различиях. Режим совместимости не может сделать более поздние языки точно эквивалентными XPath 1.0.

Преобразования между типами данных SQL и XML и значениями

В SQL:2006 и позже оба направления преобразования между стандартными типами данных SQL и типами схемы XML указаны точно. Однако правила выражены с использованием типов и семантики XQuery/XPath и не имеют прямого применения к другой модели данных XPath 1.0.

Когда PostgreSQL сопоставляет значения данных SQL с XML (как в xmlelement), или XML с SQL (как в выходных столбцах xmltable), за исключением нескольких случаев, рассматриваемых особо, PostgreSQL просто предполагает, что форма строки XPath 1.0 типа данных XML будет действительна в виде текстового ввода для типа данных SQL и наоборот. Это правило обладает простотой при создании результатов, аналогичных указанным в стандарте, для многих типов данных.

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

Непреднамеренные ограничения реализации

Этот раздел касается ограничений, которые не присущи библиотеке libxml2, но применимы к текущей реализации в PostgreSQL.

Поддерживается только механизм передачи BY VALUE

Стандарт SQL определяет два механизма передачи, которые применяются при передаче аргумента XML из SQL в функцию XML или получении результата: BY REF, в котором конкретное значение XML сохраняет свою узловую идентичность, и BY VALUE, в котором передается содержимое XML, но узловая идентичность не сохраняется. Механизм может быть указан перед списком параметров в качестве механизма по умолчанию для всех них или после любого параметра для замены значения по умолчанию.

Чтобы проиллюстрировать разницу, если x является значением XML, эти два запроса в среде SQL:2006 дали бы истинный и ложный результаты соответственно:

SELECT XMLQUERY('$a is $b' PASSING BY REF x AS a, x AS b NULL ON EMPTY);
SELECT XMLQUERY('$a is $b' PASSING BY VALUE x AS a, x AS b NULL ON EMPTY);

PostgreSQL примет BY VALUE или BY REF в конструкции XMLEXISTS или XMLTABLE, но игнорирует их. Тип данных xml содержит сериализованное представление символьной строки, поэтому нет идентичности узла, которую нужно сохранить, и передача всегда эффективно BY VALUE.

Невозможно передать именованные параметры запросам

Функции на основе XPath поддерживают передачу одного параметра для использования в качестве контекстного элемента выражения XPath, но не поддерживают передачу дополнительных значений, доступных выражению в виде именованных параметров.

Нет типа XML(SEQUENCE)

Тип данных PostgreSQL xml может содержать значение только в форме DOCUMENT или CONTENT. Элемент контекста выражения XQuery/XPath должен быть единственным узлом XML или атомарным значением, но XPath 1.0 дополнительно ограничивает его до единственного узла XML и не имеет типа узлов, допускающего CONTENT. В итоге хорошо сформированный DOCUMENT является единственной формой значения XML, которую PostgreSQL может предоставить в качестве элемента контекста XPath.