如何读取一个本地Json文件并查询该文件展示其内容

我前一段时间在我的博客里写了一篇文章“如何在QML应用中读写文件”,那篇文章是介绍如何使用C++来读取文件的。那种方法是一个比较通用的方法。但是对于有些应用来说,我们可以通过配置JSON来创建我们的UI,或者对不同的平台进行配置,而不用写一个单独的设置文件来做这件事。那么我们如何不需要通过C++的方法来读取Json文件呢?


我们可以使用我们的SDK创建一个最基本的QML应用。为了能够读取Json文件,我们创建一个叫做“jsonparser.js”的文件:

/* Based on:
 * JSONListModel - a QML ListModel with JSON and JSONPath support
 *
 * Copyright (c) 2012 Romain Pokrzywka (KDAB) (romain@kdab.com)
 * Licensed under the MIT licence
 * (http://opensource.org/licenses/mit-license.php)
 * https://github.com/s3u/JSONPath
 */

//Qt.include("jsonpath.js")

function readJsonFile(source, callback) {

    var xhr = new XMLHttpRequest;
    xhr.open("GET", source);
    xhr.onreadystatechange = function() {
        if (xhr.readyState == XMLHttpRequest.DONE) {
            var doc = xhr.responseText;
//            console.log("JSON: " + json)
            var json = JSON.parse(doc);
            callback.update(json);
        }
    }

   xhr.send();
}


我们通过XMLHttpRequest来完成本地文件的请求工作,并使用callback中的update来传人到QML文件中进行解析。为了能够更加方便地解析我们得到的Json文件,我们使用了

 https://github.com/s3u/JSONPath

里提供的库。我们可以把“jsonpath.js”下载到我们项目的根目录下,以方便使用。具体的使用方法可以在网上查看。

为了显示我们的JSO数据,我们对我们的Main.qml进行了修改:

import QtQuick 2.0
import Ubuntu.Components 1.1
import "jsonparser.js" as API
import "jsonpath.js" as JSONPath

/*!
    \brief MainView with a Label and Button elements.
*/

MainView {
    id: main
    // objectName for functional testing purposes (autopilot-qt5)
    objectName: "mainView"

    // Note! applicationName needs to match the "name" field of the click manifest
    applicationName: "readjsonfile.liu-xiao-guo"

    /*
     This property enables the application to change orientation
     when the device is rotated. The default is false.
    */
    //automaticOrientation: true

    // Removes the old toolbar and enables new features of the new header.
    useDeprecatedToolbar: false

    width: units.gu(60)
    height: units.gu(85)

    function update(json) {
        console.log("it is called in update!");
        // we can start to interpret the returned json
        var authors = JSONPath.jsonPath(json, "$.store.book[*].author");

        console.log("length: " + authors.length);

        for (var i in authors ) {
            console.log("author[" + i +"] " + authors[i]);
            mymodel.append( { "content": authors[i],
                               "type": "Authors"
                           });
        }

        // Get all of the books
        var books = JSONPath.jsonPath(json, "$.store.book[*].title");
        console.log("length: " + books.length);
        for (var j in books ) {
            console.log("author[" + j +"] " + books[j]);
            mymodel.append( { "content": books[j],
                               "type": "Books"
                           });
        }

    }

    Page {
        id: mainPage
        title: i18n.tr("Read Json File")


        ListModel {
            id: mymodel
        }

        Component {
            id: sectionHeading
            Rectangle {
                width: mainPage.width
                height: childrenRect.height
                color: "lightsteelblue"

                Text {
                    text: section
                    font.bold: true
                    font.pixelSize: 20
                }
            }
        }

        ListView {
            id: listview
            anchors.fill: parent
            model: mymodel
            delegate: Text {
                text: content
            }

            section.property: "type"
            section.criteria: ViewSection.FullString
            section.delegate: sectionHeading
        }

        Component.onCompleted: {
            console.log("Start to read JSON file");
            API.readJsonFile("sample.json", main)
        }
    }
}

为了完成我们的实验,我们也创建了一个sample.json文件。内容如下:

{
  "store": {
    "book": [
      {
        "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      {
        "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      },
      {
        "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      {
        "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}


运行我们的应用,我们应用显示的结果如下: