Spec-Zone.ru › Qt 5.14

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();
    }

Итерируйтесь по элементам результатов и проверяйте каждый 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, к QXmlName необходимо получить доступ с помощью пула имен из экземпляра 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.14/xmlprocessing.html

Spec-Zone.ru

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