Spec-Zone.ru › Qt 5.9

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, используя C++ API Qt XML Patterns, или запустить движок запросов из командной строки, используя утилиту командной строки 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 представляет элементы данных как атомные значения или узлы. Атомное значение — это значение в области определения одного из встроенных типов данных, определённых во второй части W3C XML Schema (Часть 2). Узел, как правило, является XML-элементом или атрибутом, но при моделировании не-XML данных как XML, узел может также представлять не-XML элементы данных.

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

Связывание переменных программы с переменными XQuery

Если вы хотите запустить параметризованный XQuery из приложения Qt, вам нужно связать переменные в вашей программе с переменными $имя в вашем 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. При связывании не-UTC QTime с переменной XQuery он должен быть сначала передан как строка или преобразован в QDateTime с произвольной датой, а затем связан с переменной XQuery типа xs:dateTime.

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

QVariantList может быть связана с переменной XQuery $переменная. Все 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-формат.

END_OF_DOCUMENT_MARKER

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

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

Вставка кода

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

В статьях Avoid the dangers of XPath injection, автором Robi Sen, и Blind XPath Injection, автором Amit Klein, подробно рассматривается проблема внедрения кода в 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. Также может быть интересен проект тестирования XQuery W3C, 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% тестового набора XSLT W3C, который фокусируется на функциях, добавленных в 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-схем в значительной степени поддерживает спецификацию версии 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.9/xmlprocessing.html

Spec-Zone.ru

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