Spec-Zone.ru › Qt 5.15

XQuery

Введение

XQuery — это язык для обхода XML-документов, выбора и агрегирования интересующих элементов, а также преобразования их для вывода в формате XML или другом формате. XPath — это часть XQuery, отвечающая за выбор элементов.

Модуль Qt XML Patterns поддерживает использование XQuery 1.0 и XPath 2.0 в приложениях Qt для запросов к XML-данным и к данным, не являющимся XML, которые могут быть смоделированы как XML. Читатели, не знакомые с языком XQuery/XPath, могут прочитать Краткое введение в XQuery для ознакомления.

Преимущества использования Qt XML Patterns и XQuery

Язык XQuery/XPath упрощает задачи поиска и преобразования данных, исключая необходимость написания большого количества процедурной программы на C++ или Java для каждого нового запроса. Ниже представлен пример XQuery, который строит библиографию содержимого библиотеки:

<bibliography>
{doc("library.xml")/bib/book[publisher="Addison-Wesley" and @year>1991]/<book year="{@year}">{title}</book>}
</bibliography>

Сначала запрос открывает элемент <bibliography> в выводе. Затем встроенное выражение пути загружает XML-документ, описывающий содержимое библиотеки (library.xml), и начинает поиск. Для каждого элемента <book>, где издателем является Addison-Wesley, а год публикации — после 1991 года, он создаёт новый элемент <book> в выводе как дочерний элемент открытого элемента <bibliography>. Каждый новый элемент <book> получает в качестве содержимого название книги и год публикации в качестве атрибута. Наконец, закрывается элемент <bibliography>.

Преимущества использования Qt XML Patterns и XQuery в ваших программах Qt подытожены следующим образом:

  • Простота разработки: Вся программирование на C++, необходимое для выполнения задач запросов к данным, может быть заменено простым XQuery, как в приведённом выше примере.
  • Полный функционал: Синтаксис выражений и богатый набор функций и операторов, предоставляемых XQuery, достаточен для выполнения любых задач поиска, выбора и сортировки данных.
  • Соответствие стандартам: Соответствие всем применимым стандартам XML и XQuery гарантирует, что Qt XML Patterns всегда сможет обрабатывать XML-документы, созданные другими приложениями, соответствующими этим стандартам, и что XML-документы, созданные с помощью Qt XML Patterns, могут быть обработаны другими приложениями, соответствующими этим стандартам.
  • Максимальная гибкость Модуль Qt XML Patterns может использоваться для запросов к XML-данным и к данным, не являющимся XML, которые могут быть смоделированы как XML.

Использование модуля Qt XML Patterns

Существует два способа использования Qt XML Patterns для оценки запросов. Вы можете запустить движок запросов в своём приложении Qt, используя API Qt XML Patterns на C++, или вы можете запустить движок запросов из командной строки, используя утилиту командной строки Qt xmlpatterns.

Запуск движка запросов из вашего приложения Qt

Если мы сохраним пример XQuery, показанный выше, в текстовом файле (например, myquery.xq), мы можем запустить его из приложения Qt, используя стандартную последовательность кода Qt XML Patterns:

    QFile xq("myquery.xq");

    QXmlQuery query;
    query.setQuery(&xq, QUrl::fromLocalFile(xq.fileName()));

    QXmlSerializer serializer(query, myOutputDevice);
    query.evaluateTo(&serializer);

Сначала создайте QFile для текстового файла, содержащего XQuery (myquery.xq). Затем создайте экземпляр QXmlQuery и вызовите его функцию setQuery() для загрузки и разбора файла XQuery. Затем создайте сериализатор XML для вывода набора результатов запроса как неформатированного XML. Наконец, вызовите функцию evaluateTo() для оценки запроса и сериализации результатов в формате XML.

Примечание: Если вы компилируете Qt самостоятельно, модуль Qt XML Patterns не будет скомпилирован, если исключения отключены или если вы компилируете Qt с компилятором, который не поддерживает шаблоны членов, например, MSVC 6.

См. документацию по QXmlQuery для получения дополнительной информации об API Qt XML Patterns на C++.

Запуск движка запросов из утилиты командной строки

xmlpatterns — это утилита командной строки для запуска XQuery. Она ожидает имя файла, содержащего текст XQuery.

xmlpatterns myQuery.xq

XQuery в myQuery.xq будет оценён, и его вывод будет записан в stdout. Используйте переключатель -help для получения списка входных флагов и их значений.

xmlpatterns можно использовать в скриптах. Однако описания и сообщения, которые он выводит, не предназначались для разбора и могут быть изменены в будущих версиях Qt.

Модель данных XQuery

XQuery представляет элементы данных как атомарные значения или узлы. Атомарное значение — это значение в области одного из встроенных типов данных, определённых во части 2 XML Schema W3C. Узел обычно представляет собой XML-элемент или атрибут, но когда данные, не являющиеся XML, моделируются как XML, узел также может представлять собой элемент данных, не являющийся XML.

Когда вы запускаете XQuery с помощью API C++ в приложении Qt, вы часто захотите привязать переменные программы к $переменным в XQuery. После оценки запроса вам нужно будет интерпретировать последовательность элементов данных в наборе результатов.

Привязка переменных программы к переменным XQuery

Если вы хотите запустить параметризованный XQuery из своего приложения Qt, вам потребуется привязать переменные в вашей программе к переменным $name в вашем XQuery.

Предположим, вы хотите параметризовать XQuery библиографии в приведённом выше примере. Вы можете определить переменные для каталога, содержащего библиотеку ($file), имени издателя ($publisher) и года публикации ($year):

<bibliography>
{
    doc($file)/bib/book[publisher = $publisher and @year > $year]/<book year="{@year}">{title}</book>
}
</bibliography>

Измените код Qt XML Patterns, чтобы использовать одну из функций bindVariable() для привязки переменной программы к каждой переменной $переменной XQuery:

    QFile xq("myquery.xq");
    QString fileName("the filename");
    QString publisherName("the publisher");
    qlonglong year = 1234;

    QXmlQuery query;

    query.bindVariable("file", QVariant(fileName));
    query.bindVariable("publisher", QVariant(publisherName));
    query.bindVariable("year", QVariant(year));

    query.setQuery(&xq, QUrl::fromLocalFile(xq.fileName()));

    QXmlSerializer serializer(query, myOutputDevice);
    query.evaluateTo(&serializer);

Каждая переменная программы передаётся Qt XML Patterns как QVariant типа переменной или константы C++, из которой она создана. Обратите внимание, что Qt XML Patterns предполагает, что тип QVariant в вызове bindVariable() является правильным типом, поэтому переменная $переменная, к которой он привязан, должна использоваться в XQuery соответственно. В следующей таблице показано, как типы QVariant сопоставляются с типами $переменных XQuery:

Тип QVariant Тип $переменной XQuery
QVariant::LongLong xs:integer
QVariant::Int xs:integer
QVariant::UInt xs:nonNegativeInteger
QVariant::ULongLong xs:unsignedLong
QVariant::String xs:string
QVariant::Double xs:double
QVariant::Bool xs:boolean
QVariant::Double xs:decimal
QVariant::ByteArray xs:base64Binary
QVariant::StringList xs:string*
QVariant::Url xs:string
QVariant::Date xs:date.
QVariant::DateTime xs:dateTime
QVariant::Time. xs:time. (см. Привязка к QVariant::Time ниже)
QVariantList (см. Привязка к QVariantList ниже)

Тип, не показанный в таблице, не поддерживается и приведёт к неопределённому поведению XQuery или ошибке привязки $переменной, в зависимости от контекста в XQuery, где используется переменная.

Привязка к QVariant::Time

Поскольку экземпляр QTime, используемый в QVariant::Time, не включает смещение часового пояса, экземпляр QVariant::Time не должен быть привязан к переменной XQuery типа xs:time, если QTime не является UTC. При привязке QTime, не являющейся UTC, к переменной XQuery, её следует сначала передать как строку или преобразовать в QDateTime с произвольной датой, а затем привязать к переменной XQuery типа xs:dateTime.

Привязка к QVariantList

QVariantList может быть привязана к переменной XQuery $переменной. Все QVariant в списке должны быть одного атомарного типа, и $переменная, к которой привязан список варианта, должна быть того же атомарного типа. Если QVariant в списке не имеют одинакового атомарного типа, поведение XQuery является неопределённым.

Интерпретация результатов XQuery

Когда результаты XQuery возвращаются в последовательности элементов результатов, атомарные значения в последовательности обрабатываются как экземпляры QVariant. Предположим, что вместо сериализации результатов XQuery как XML мы обрабатываем результаты программно. Измените стандартную последовательность кода Qt XML Patterns, чтобы вызвать перегрузку QXmlQuery::evaluateTo(), которая заполняет последовательность элементов результатов результатами XQuery:

    QFile xq("myquery.xq");
    QString fileName("the filename");
    QString publisherName("the publisher");
    qlonglong year = 1234;

    QXmlQuery query;

    query.bindVariable("file", QVariant(fileName));
    query.bindVariable("publisher", QVariant(publisherName));
    query.bindVariable("year", QVariant(year));

    query.setQuery(&xq, QUrl::fromLocalFile(xq.fileName()));

    QXmlResultItems result;
    query.evaluateTo(&result);
    QXmlItem item(result.next());
    while (!item.isNull()) {
        if (item.isAtomicValue()) {
            QVariant v = item.toAtomicValue();
            switch (v.type()) {
                case QVariant::LongLong:
                    // xs:integer
                    break;
                case QVariant::String:
                    // xs:string
                    break;
                default:
                    // error
                    break;
            }
        }
        else if (item.isNode()) {
#ifdef qdoc
            QXmlNodeModelIndex i = item.toNodeModelIndex();
            // process node
#endif // qdoc
        }
        item = result.next();
    }

Итерируйте элементы результата result items и проверяйте каждый QXmlItem, чтобы определить, является ли он атомным значением или узлом. Если это атомное значение, преобразуйте его в QVariant с помощью toAtomicValue() и переключитесь на его тип значения, чтобы обработать все атомные значения, которые может вернуть ваш XQuery. В следующей таблице показан QVariant тип, ожидаемый для каждого типа атомного значения (или QXmlName):

Тип элемента результата XQuery Тип QVariant, возвращаемый
xs:QName QXmlName (см. Обработка QXmlNames ниже)
xs:integer QVariant::LongLong
xs:string QVariant::String
xs:string* QVariant::StringList
xs:double QVariant::Double
xs:float QVariant::Double
xs:boolean QVariant::Bool
xs:decimal QVariant::Double
xs:hexBinary QVariant::ByteArray
xs:base64Binary QVariant::ByteArray
xs:gYear QVariant::DateTime
xs:gYearMonth QVariant::DateTime
xs:gMonthDay QVariant::DateTime
xs:gDay QVariant::DateTime
xs:gMonth QVariant::DateTime
xs:anyURI QVariant::Url
xs:untypedAtomic QVariant::String
xs:ENTITY QVariant::String
xs:date QVariant::DateTime
xs:dateTime QVariant::DateTime
xs:time (см. Отсутствие соответствия для xs:time ниже)

Обработка QXmlNames

Если ваш XQuery может возвращать атомные значения типа xs:QName, они будут отображаться в ваших QXmlResultItems в виде экземпляров QXmlName. Так как класс QVariant не поддерживает класс QXmlName напрямую, извлечение их из QXmlResultItems требует небольшого ухищрения с использованием системы метатипов Qt. Мы должны изменить наш пример, чтобы использовать несколько шаблонных функций, друга QMetaType (qMetaTypeId<T>()) и друга QVariant (qvariant_cast<T>()):

    QFile xq("myquery.xq");

    QXmlQuery query;
    query.setQuery(&xq, QUrl::fromLocalFile(xq.fileName()));

    QXmlResultItems result;
    query.evaluateTo(&result);
    QXmlItem item(result.next());
    while (!item.isNull()) {
        if (item.isAtomicValue()) {
            QVariant v = item.toAtomicValue();
            switch (v.type()) {
                case QVariant::LongLong:
                    // xs:integer
                    break;
                case QVariant::String:
                    // xs:string
                    break;
                default:
                    if (v.userType() == qMetaTypeId<QXmlName>()) {
#ifdef qdoc
                        QXmlName n = qvariant_cast<QXmlName>(v);
                        // process QXmlName n...
#endif // qdoc
                    }
                    else {
                        // error
                    }
                    break;
            }
        }
        else if (item.isNode()) {
#ifdef qdoc
            QXmlNodeModelIndex i = item.toNodeModelIndex();
            // process node
#endif // qdoc
        }
        item = result.next();
    }

Для доступа к строкам в QXmlName, возвращаемых результатом вычисления XQuery, необходимо использовать пул имён name pool из экземпляра QXmlQuery, который использовался для вычисления.

Отсутствие соответствия для xs:time

Экземпляр xs:time не может быть правильно представлен как экземпляр QVariant::Time, если xs:time не является временем UTC. Это связано с тем, что xs:time имеет смещение зоны (0 для UTC) помимо значения времени, чего нет в QTime в QVariant::Time. Это означает, что если XQuery пытается вернуть атомное значение типа xs:time, будет возвращён недействительный QVariant. Запрос может вернуть атомное значение типа xs:time, либо преобразовав его в xs:dateTime с произвольной датой, либо в xs:string.

Использование XQuery с данными, не являющимися XML

Хотя язык XQuery был разработан для запросов к XML, с помощью Qt XML Patterns можно использовать XQuery для запросов к любым данным, которые можно смоделировать как XML. Данные, не являющиеся XML, моделируются как XML путём загрузки их в пользовательский подкласс QAbstractXmlNodeModel, где они затем предоставляются движку Qt XML Patterns XQuery через тот же API, который XQuery использует для запросов к XML.

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

<result>
    <para>The following skin care products have shipped, ordered by shipping date(oldest first):</para>
    {
        for $i in doc("myOrders.xml")/orders/order[@product = "Acme Skin Care"]
        order by xs:date($i/@shippingDate) descending
        return $i
    }
</result>

Qt XML Patterns может использоваться без изменений для выполнения этого запроса, если myOrders.xml на самом деле содержит корректный XML. Его можно загрузить напрямую в стандартную модель узлов XML и пройтись по ней. Но предположим, что мы хотим, чтобы Qt XML Patterns выполнял запросы к иерархической структуре локальной файловой системы. Стандартная модель узлов XML в Qt XML Patterns не подходит для навигации по файловой системе, так как нет файла XML для загрузки, содержащего его описание. Такой XML-файл, если бы он существовал, мог бы выглядеть примерно так:

<?xml version="1.0" encoding="UTF-8"?>
<directory name="home">

    <file name="myNote.txt" mimetype="text/plain" size="8" extension="txt" uri="file:///home/frans/myNote.txt">
        <content asBase64Binary="TXkgTm90ZSE=" asStringFromUTF-8="My Note!"/>
    </file>

    <directory name="src">
        ...
    </directory>

    ...

</directory>

Пример файловой системы делает именно это.

Нет такого файла для загрузки в стандартную модель узлов XML, но можно написать подкласс QAbstractXmlNodeModel для представления файловой системы. Эта настраиваемая модель узлов XML, после заполнения всеми описателями каталогов и файлов, полученными непосредственно из системы, предоставляет движку запросов полную иерархию файловой системы через тот же API, который использует стандартная модель узлов XML для представления содержимого XML-файла. Другими словами, после заполнения настраиваемой модели узлов XML она представляет файловую систему движку запросов так, как будто её описание было загружено в стандартную модель узлов XML из XML-файла, как показано выше.

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

<html>
    <body>
        {
            $myRoot//file[@mimetype = 'text/xml' or @mimetype = 'application/xml']
            /
            (if(doc-available(@uri))
             then ()
             else <p>Failed to parse file {@uri}.</p>)
        }
    </body>
</html>

Без Qt XML Patterns нет простого способа решить эту проблему. Вы могли бы написать программу на C++, которая бы обходила файловую систему, выявляла все XML-файлы и отправляла каждый из них в XML-парсер для проверки на валидность XML. Код C++ для написания такой программы, вероятно, будет сложнее, чем код C++ для создания подкласса QAbstractXmlNodeModel, но даже если они сопоставимы, вашу пользовательскую программу на C++ можно использовать только для этой одной задачи, в то время как ваша настраиваемая модель узлов XML может быть использована любым XQuery, который должен перемещаться по файловой системе.

Общий подход к использованию XQuery для выполнения запросов к данным, не являющимся XML, заключался в трёх шагах. На первом шаге данные загружаются в модель данных, не являющуюся XML. На втором шаге модель данных, не являющаяся XML, сериализуется как XML и выводится в XML-файлы (текст). На третьем шаге инструмент XML загружает XML-файлы во вторую, XML-модель данных, где можно выполнять XQuery. Стоимость разработки реализации этого процесса часто высока, а результирующая система из трёх этапов неэффективна, поскольку две модели данных должны быть построены и поддерживаются отдельно.

С помощью Qt XML Patterns подкласс QAbstractXmlNodeModel устраняет преобразование, необходимое для преобразования модели данных, не являющейся XML, в XML-модель данных, поскольку всегда требуется только одна модель данных. Модель данных, не являющаяся XML, предоставляет данные, не являющиеся XML, движку запросов через API модели XML данных. Кроме того, поскольку движок запросов использует API для доступа к QAbstractXmlNodeModel, подкласс модели данных может создавать элементы, атрибуты и другие данные по требованию, реагируя на конкретные запросы запроса. Это может значительно улучшить эффективность, поскольку это означает, что вся модель, возможно, не должна быть построена. Например, в модели файловой системы выше не нужно создавать экземпляр для целого XML-файла, представляющего всю файловую систему. Вместо этого узлы создаются по требованию, что, скорее всего, является небольшой подмножеством файловой системы.

Примеры других мест, где XQuery мог бы использоваться в Qt XML Patterns для запросов к данным, не являющимся XML:

  • Внутреннее представление документов текстового процессора
  • Набор зависимостей для системы сборки программного обеспечения
  • Иерархия (или граф), связывающая набор HTML-документов из веб-робота
  • Изображения и метаданные в коллекции изображений
  • Набор доступных интерфейсов D-Bus в системе
  • Иерархия QObject.

См. документацию по QAbstractXmlNodeModel для получения информации о том, как реализовать пользовательские модели узлов XML.

Подробнее об использовании Qt XML Patterns с данными, не являющимися XML

Подкласс QAbstractXmlNodeModel для предоставления движку запросов доступа к данным, не являющимся XML, через тот же API, который он использует для XML, — это функция, которая позволяет Qt XML Patterns выполнять запросы к данным, не являющимся XML, с помощью XQuery. Это позволяет XQuery использоваться в качестве уровня отображения между различными моделями узлов, не являющихся XML, или между моделью узлов, не являющейся XML, и встроенной моделью узлов XML. После написания подклассов QAbstractXmlNodeModel, XQuery может использоваться для выбора набора элементов из одной модели узлов, преобразования выбранных элементов и затем записи их, либо в XML с помощью QXmlQuery::evaluateTo() и QXmlSerializer, либо в другом формате с помощью подкласса QAbstractXmlReceiver.

Рассмотрим приложение текстового процессора, которое должно импортировать и экспортировать данные в нескольких разных форматах. Вместо написания большого количества кода на C++ для преобразования каждого входного формата в промежуточную форму и ещё большего количества кода C++ для преобразования промежуточной формы обратно в каждый выходной формат, можно реализовать решение, основанное на Qt XML Patterns, которое использует простые XQuery для преобразования каждого XML-формата или формата, не являющегося XML (например, MathFormula.xml ниже) в промежуточную форму (например, класс модели узла DocumentRepresentation ниже), а также простые XQuery для преобразования промежуточной формы обратно в каждый XML-формат или формат, не являющийся XML.

Поскольку CSV-файлы не являются XML, используется подкласс QAbstractXmlNodeModel, чтобы представить данные CSV для движка XQuery, как если бы они были XML. Не показаны подклассы QAbstractXmlReceiver, которые затем отправят выбранные элементы в модель узлов DocumentRepresentation, и подклассы QAbstractXmlNodeModel, которые в конечном итоге запишут выходные файлы в каждом формате.

Соображения безопасности

Инъекция кода

XQuery уязвим для атак с инъекцией кода так же, как и язык SQL. Если XQuery строится путём конкатенации строк, а строки взяты из пользовательского ввода, то созданный XQuery может быть злонамеренным. Лучший способ предотвратить атаки с инъекцией кода — не создавать XQuery из пользовательских строк, а принимать пользовательские данные только с использованием QVariant и связывания переменных. См. QXmlQuery::bindVariable().

В статьях Avoid the dangers of XPath injection Роби Сена и Blind XPath Injection Амита Кляйна проблема инъекции кода в XQuery рассматривается подробнее.

Атаки типа «отказ в обслуживании»

Приложения, использующие Qt XML Patterns, подвержены тем же ограничениям программного обеспечения, что и другие системы. Как правило, их нельзя проверить. Это означает, что Qt XML Patterns не предотвращает несанкционированные запросы, потребляющие слишком много ресурсов. Например, запрос может потребовать слишком много времени для выполнения или попытаться передать слишком много данных. Запрос также может выполнить слишком много рекурсий, что может привести к сбою системы. XQuery могут делать это случайно, но их также можно использовать как преднамеренные атаки типа «отказ в обслуживании».

Функциональные возможности и соответствие

XQuery 1.0

Qt XML Patterns стремится быть соответствующим процессором XQuery. Он соответствует Минимальному соответствию и поддерживает Функцию сериализации и Полную функцию осей. Qt XML Patterns в настоящее время проходит 97 % тестов в тестовом наборе XML Query. Области, где соответствие может быть сомнительным и где поведение может быть изменено в будущих версиях, включают:

  • Некоторые частные случаи, связанные с именами пространств и конструкторами элементов, являются неверными.
  • XPath является подмножеством XQuery, и реализация Qt XML Patterns использует XPath 2.0 с XQuery 1.0.

В спецификациях соответствие обсуждается более подробно: XQuery 1.0: Язык запросов XML. Также может быть интересна работа W3C по тестированию XQuery: XML Query Test Suite.

В настоящее время fn:collection() не обращается к никакому набору данных, и нет API для предоставления данных через коллекцию. В результате вычисление fn:collection() возвращает пустую последовательность. Мы планируем реализовать эту функциональность в будущей версии Qt.

Поддерживаются только запросы, закодированные в UTF-8.

XSLT 2.0

Частичная поддержка XSLT была добавлена в Qt 4.5. Будущие версии Qt XML Patterns будут направлены на поддержку следующих функций XSLT:

  • Базовый процессор XSLT 2.0
  • Функция сериализации
  • Функция обратной совместимости

Подробности см. в XSL Transformations (XSLT) Version 2.0, 21 Conformance.

Примечание: В этой версии поддержка XSLT считается экспериментальной.

Неподдерживаемые или частично поддерживаемые функции XSLT документированы в следующей таблице. Реализация XSLT в Qt 4.5 может рассматриваться как XSLT 1.0, но с моделью данных XPath 2.0 и XSLT 2.0, а также с использованием функциональности XPath 2.0 и соответствующей библиотеки функций. Когда Qt XML Patterns сталкивается с неподдерживаемой или частично поддерживаемой функцией, она либо сообщает об ошибке синтаксиса, либо молча продолжает, если не указано иное в таблице.

Реализация в настоящее время проходит 42 % тестов тестового набора W3C по XSLT, которые сосредоточены на функциях, введённых в XSLT 2.0.

Функция XSL Статус поддержки
xsl:key и fn:key() не поддерживается
xsl:include не поддерживается
xsl:import не поддерживается
xsl:copy У атрибутов copy-namespaces и inherit-namespaces нет эффекта. Для скопированных комментариев, атрибутов и инструкций обработки копии есть тот же идентификатор узла, что и у оригинала.
xsl:copy-of У атрибута copy-namespaces нет эффекта.
fn:format-number() не поддерживается
xsl:message не поддерживается
xsl:use-when не поддерживается
Tunnel Параметры не поддерживается
xsl:attribute-set не поддерживается
xsl:decimal-format не поддерживается
xsl:fallback не поддерживается
xsl:apply-imports не поддерживается
xsl:character-map не поддерживается
xsl:number не поддерживается
xsl:namespace-alias не поддерживается
xsl:output не поддерживается
xsl:output-character не поддерживается
xsl:preserve-space не поддерживается
xsl:result-document не поддерживается
Шаблоны Сложные шаблоны или шаблоны с предикатами имеют проблемы.
2.0 Режим совместимости Стили обрабатываются как стили XSLT 2.0, даже если атрибут version в источнике XSLT равен 1.0. Другими словами, атрибут версии игнорируется.
Группировка fn:current-group(), fn:grouping-key() и xsl:for-each-group.
Элементы regexp xsl:analyze-string, xsl:matching-substring, xsl:non-matching-substring, и fn:regex-group()
Форматирование даты и времени fn:format-dateTime(), fn:format-date() и fn:format-time().
Соответствие XPath Поскольку XPath является подмножеством XSLT, его проблемы также имеют отношение.

Реализация XPath Data Model в Qt XML Patterns не включает сущностей (из-за того, что QXmlStreamReader их не сообщает). Это означает, что функции unparsed-entity-uri() и unparsed-entity-public-id() всегда возвращают отрицательные значения.

XPath 2.0

Поскольку XPath 2.0 является подмножеством XQuery 1.0, поддерживается XPath 2.0. Области, где соответствие может быть сомнительным, и, следовательно, где поведение может быть изменено в будущих версиях, включают:

  • Поддержка регулярных выражений в настоящее время не соответствует стандарту, но следует синтаксису Qt QRegExp.
  • Операторы для xs:time, xs:date, и xs:dateTime неполные.
  • Форматирование очень больших или очень маленьких значений xs:double, xs:float, и xs:decimal может быть некорректным.

xml:id

Обработка XML-файлов поддерживает xml:id. Это позволяет эффективно искать элементы, имеющие атрибут с именем xml:id, с помощью функции fn:id(). Подробности см. в xml:id Version 1.0.

XML Schema 1.0

Существует два способа использования Qt XML Patterns для проверки схем: Вы можете использовать API C++ в приложении Qt с помощью классов QXmlSchema и QXmlSchemaValidator или использовать утилиту командной строки xmlpatternsvalidator (расположенную в каталоге «bin» вашей сборки Qt).

Реализация валидации схемы XML в Qt XML Patterns в значительной степени поддерживает спецификацию схемы версии 1.0. Известные проблемы реализации и области, где соответствие может быть сомнительным, включают:

  • Большие значения minOccurs или maxOccurs или глубоко вложенные значения требуют большого объёма памяти, что может привести к зависанию системы. Такую схему следует переписать, чтобы использовать unbounded в качестве значения вместо больших чисел. Это ограничение, к счастью, будет исправлено в будущих выпусках.
  • Сравнение очень маленьких или очень больших значений с плавающей запятой может привести к неправильным результатам в некоторых случаях. Однако такие числа не должны быть важны для повседневного использования.
  • Поддержка регулярных выражений в настоящее время не соответствует стандарту, но следует синтаксису Qt QRegExp.
  • Проверки ограничений тождества не могут использовать значения по умолчанию или фиксированных определений атрибутов.

Загрузка ресурсов

При загрузке Qt XML Patterns XML-ресурса, например, с использованием функции fn:doc(), поддерживаются следующие схемы:

Имя схемы Описание
file Локальные файлы.
data Байты закодированы в самом URI. Например, data:application/xml,%3Ce%2F%3E это <e/>.
ftp Ресурсы, полученные через FTP.
http Ресурсы, полученные через HTTP.
https Ресурсы, полученные через HTTPS. Это будет выполнено, если ошибки SSL не возникнут.
qrc Файлы ресурсов Qt. Использование пустой схемы, :/..., не поддерживается.

XML

Поддерживаются XML 1.0 и XML Namespaces 1.0, в отличие от версий 1.1. Если строка передаётся в запрос как QString, символы должны быть символами XML 1.0. В противном случае поведение не определено. Это не проверяется.

URI сначала передаются в QAbstractUriResolver. Проверьте QXmlQuery::setUriResolver() для возможных переписываний.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.15/xmlprocessing.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API