Spec-Zone.ru › Qt 5.11

XQuery

Введение

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

Модуль Qt XML Patterns поддерживает использование XQuery 1.0 и XPath 2.0 в приложениях Qt для запросов к 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 для получения дополнительной информации о C++ API Qt XML Patterns.

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

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

xmlpatterns myQuery.xq

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

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

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

XQuery представляет элементы данных как атомные значения или узлы. Атомное значение — это значение в области одного из встроенных типов данных, определённых во части 2 спецификации W3C XML Schema. Узел обычно представляет собой 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() для связывания переменной программы с каждой переменной $variable 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. При связывании не-UTC QTime с переменной XQuery его следует сначала передать как строку или преобразовать в QDateTime с произвольной датой, а затем связать с переменной XQuery типа xs:dateTime.

Связывание с QVariantList

QVariantList может быть связана с переменной XQuery $variable. Все QVariant в списке должны быть одного атомного типа, и $переменная, к которой привязано список вариантов, должна быть этого же атомного типа. Если QVariants в списке не все одного атомного типа, поведение 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, 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, где они затем представляются двигателю XQuery Qt XML Patterns через тот же API, который XQuery двигатель использует для запросов к XML.

Когда Qt XML Patterns загружает и выполняет запросы к файлам XML и генерирует выход XML, он всегда может загружать данные XML в свою модель узлов 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, для представления данных CSV в движке XQuery так, как будто это XML, используется подкласс QAbstractXmlNodeModel. Не показаны подклассы 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.

В настоящее время 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, его проблемы также актуальны.

Реализация Qt XML Patterns модели данных XPath не включает сущности (из-за того, что 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).

Реализация Qt XML Patterns валидации XML Schema в значительной степени поддерживает спецификацию версии 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/archives/qt-5.11/xmlprocessing.html

Spec-Zone.ru

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