From ddcf9fc80e074c5a9d1ecbbf3c60ca27f250ce98 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Thu, 4 Jul 2013 12:14:44 +0200 Subject: [PATCH] Don't assume that the last step of the XPath is an element name In order to find the number of items in the model, the model did a second query on the document representing the result set. So, suppose the user queried for //a/b/c, the result set would contain all the 'c' elements from the input document. In order to find the number of items in the result set, it did a second query with the expression "count(/dummy:items/c)", where 'c' was extracted from the last step in the original XPath expression For simple expressions, this worked fine. However, if the last step had a predicate such as "//c/parent::b" it didn't work. The solution is to not filter *again* the last step when we query for the count, since we know that all result items are direct children of "dummy:items", and instead just execute the query "count(dummy::items/*)". This should also potentially improve performance. Task-number: QTBUG-17588 Change-Id: Ib2fdf1ec8b91022df0597e089ad34d34b04428b0 Reviewed-by: Alan Alpert --- src/imports/xmllistmodel/qqmlxmllistmodel.cpp | 3 +-- tests/auto/quick/qquickxmllistmodel/data/groups.qml | 10 ++++++++++ tests/auto/quick/qquickxmllistmodel/data/groups.xml | 18 ++++++++++++++++++ .../quick/qquickxmllistmodel/qquickxmllistmodel.pro | 3 +++ .../qquickxmllistmodel/tst_qquickxmllistmodel.cpp | 13 +++++++++++++ 5 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 tests/auto/quick/qquickxmllistmodel/data/groups.qml create mode 100644 tests/auto/quick/qquickxmllistmodel/data/groups.xml diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp index 856c063..7cc4e64 100644 --- a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp +++ b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp @@ -388,8 +388,7 @@ void QQuickXmlQueryEngine::doQueryJob(XmlQueryJob *currentJob, QQuickXmlQueryRes b.open(QIODevice::ReadOnly); QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + currentJob->namespaces; - QString prefix = QLatin1String("doc($inputDocument)/dummy:items") + - currentJob->query.mid(currentJob->query.lastIndexOf(QLatin1Char('/'))); + QString prefix = QLatin1String("doc($inputDocument)/dummy:items/*"); //figure out how many items we are dealing with int count = -1; diff --git a/tests/auto/quick/qquickxmllistmodel/data/groups.qml b/tests/auto/quick/qquickxmllistmodel/data/groups.qml new file mode 100644 index 0000000..c1b574a --- /dev/null +++ b/tests/auto/quick/qquickxmllistmodel/data/groups.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 +import QtQuick.XmlListModel 2.0 + +XmlListModel { + source: "groups.xml" + query: "//animal[@name='Garfield']/parent::group" + + XmlRole { name: "id"; query: "@id/string()" } + XmlRole { name: "name"; query: "@name/string()" } +} diff --git a/tests/auto/quick/qquickxmllistmodel/data/groups.xml b/tests/auto/quick/qquickxmllistmodel/data/groups.xml new file mode 100644 index 0000000..5de4d2e --- /dev/null +++ b/tests/auto/quick/qquickxmllistmodel/data/groups.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro b/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro index 047d8ca..9172a22 100644 --- a/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro +++ b/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro @@ -12,3 +12,6 @@ CONFIG += parallel_test QT += core-private gui-private v8-private qml-private network testlib xmlpatterns DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +OTHER_FILES += \ + data/groups.qml diff --git a/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp b/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp index 847cc50..1f7a802 100644 --- a/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp +++ b/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp @@ -101,6 +101,7 @@ private slots: void threading(); void threading_data(); void propertyChanges(); + void selectAncestor(); void roleCrash(); @@ -964,6 +965,18 @@ void tst_qquickxmllistmodel::propertyChanges() delete model; } +void tst_qquickxmllistmodel::selectAncestor() +{ + QQmlComponent component(&engine, testFileUrl("groups.qml")); + QAbstractItemModel *model = qobject_cast(component.create()); + QVERIFY(model != 0); + QTRY_COMPARE(model->rowCount(), 1); + + QModelIndex index = model->index(0, 0); + QCOMPARE(model->data(index, Qt::UserRole).toInt(), 12); + QCOMPARE(model->data(index, Qt::UserRole+1).toString(), QLatin1String("cats")); +} + void tst_qquickxmllistmodel::roleCrash() { // don't crash -- 2.7.4