如何在QML应用中使用Javascript来解析XML

我们知道有很多的web services是使用XML格式的,我们可以通过使用XmlListModel来解析我们的XML。但是在有些情况下,我们可能需要使用Javascript来解析XML,这样使得我们可以更加灵活地解析我们所需要的XML数据。比如,通过一个请求,我们可以来解析XML结果中的多个数据。比较而言,XmlListModel只能对XPath路经下(由source属性定义)的数据进行解析。如果需要多个路径,可以通过多次对不同的路径进行查询。当然,我们可能需要一些方法来同步这些查询(如果最终的数据有互相联系的话)。

我们这里就使用我们已经有的一个教程“构建首个QML应用程序”。在这个应用中,它使用了XmlListModel来解析所得到的XML数据。API的接口为:http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
<gesmes:subject>Reference rates</gesmes:subject>
<gesmes:Sender>
<gesmes:name>European Central Bank</gesmes:name>
</gesmes:Sender>
<Cube>
<Cube time="2015-04-29">
<Cube currency="USD" rate="1.1002"/>
<Cube currency="JPY" rate="131.20"/>
<Cube currency="BGN" rate="1.9558"/>
<Cube currency="CZK" rate="27.435"/>
<Cube currency="DKK" rate="7.4619"/>
<Cube currency="GBP" rate="0.71610"/>
<Cube currency="HUF" rate="302.55"/>
<Cube currency="PLN" rate="4.0120"/>
<Cube currency="RON" rate="4.4125"/>
<Cube currency="SEK" rate="9.2723"/>
<Cube currency="CHF" rate="1.0491"/>
<Cube currency="NOK" rate="8.3850"/>
<Cube currency="HRK" rate="7.5763"/>
<Cube currency="RUB" rate="56.7850"/>
<Cube currency="TRY" rate="2.9437"/>
<Cube currency="AUD" rate="1.3762"/>
<Cube currency="BRL" rate="3.2467"/>
<Cube currency="CAD" rate="1.3262"/>
<Cube currency="CNY" rate="6.8211"/>
<Cube currency="HKD" rate="8.5278"/>
<Cube currency="IDR" rate="14212.78"/>
<Cube currency="ILS" rate="4.2601"/>
<Cube currency="INR" rate="69.7841"/>
<Cube currency="KRW" rate="1179.14"/>
<Cube currency="MXN" rate="16.8221"/>
<Cube currency="MYR" rate="3.9178"/>
<Cube currency="NZD" rate="1.4310"/>
<Cube currency="PHP" rate="48.743"/>
<Cube currency="SGD" rate="1.4557"/>
<Cube currency="THB" rate="36.142"/>
<Cube currency="ZAR" rate="13.0682"/>
</Cube>
</Cube>
</gesmes:Envelope>

为了能够解析我们的XML数据,我们可以通过如下的方法来解析:

function startParse() {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState == XMLHttpRequest.HEADERS_RECEIVED) {
        } else if (xhr.readyState == XMLHttpRequest.DONE) {
            var doc = xhr.responseXML.documentElement;
            showRequestInfo("xhr length: " + doc.childNodes.length );

            for (var i = 0; i < doc.childNodes.length; ++i) {
                var child = doc.childNodes[i];

                for (var j = 0; j < child.childNodes.length; ++j) {
                    if ( child.nodeName ===  "Cube") {

                        var kid = child.childNodes[j];
                        var length = kid.childNodes.length;

                        for ( var k = 0; k < length; k ++) {
                            var cube = kid.childNodes[k];

                            if ( cube.nodeName === "Cube") {
                                var len = cube.attributes.length;
                                var currency = cube.attributes[0].nodeValue;
                                var rate = cube.attributes[1].nodeValue;
                                currencies.append({"currency": currency, "rate": parseFloat(rate)})
                            }
                        }
                    }

                }
            }
        }
    }

    xhr.open("GET", URL);
    xhr.send();
}

这里我们使用了“XMLHttpRequest”来发送我们的请求,并通过“nodeName”及“nodeValue”来遍历我们的XML数据。最终,我们完成解析我们的XML数据。在项目中,我们定义了“xmlparser.js”文件。

Main.qml

import QtQuick 2.0
import Ubuntu.Components 1.1
import QtQuick.XmlListModel 2.0
import Ubuntu.Components.ListItems 0.1
import Ubuntu.Components.Popups 0.1
import "xmlparser.js" as API

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

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

    // Note! applicationName needs to match the "name" field of the click manifest
    applicationName: "currencyconverterxml.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

    property real margins: units.gu(2)
    property real buttonWidth: units.gu(9)

    width: units.gu(50)
    height: units.gu(75)

    function convert(from, fromRateIndex, toRateIndex) {
        var fromRate = currencies.getRate(fromRateIndex);
        if (from.length <= 0 || fromRate <= 0.0)
            return "";
        return currencies.getRate(toRateIndex) * (parseFloat(from) / fromRate);
    }

    function update() {
        indicator.running = false;
    }

    Page {
        title: i18n.tr("Currency Converter")

        ListModel {
            id: currencies
            ListElement {
                currency: "EUR"
                rate: 1.0
            }

            function getCurrency(idx) {
                return (idx >= 0 && idx < count) ? get(idx).currency: ""
            }

            function getRate(idx) {
                return (idx >= 0 && idx < count) ? get(idx).rate: 0.0
            }
        }

        ActivityIndicator {
            id: indicator
            objectName: "activityIndicator"
            anchors.right: parent.right
            running: true
        }

        Component {
            id: currencySelector
            Popover {
                Column {
                    anchors {
                        top: parent.top
                        left: parent.left
                        right: parent.right
                    }
                    height: pageLayout.height
                    Header {
                        id: header
                        text: i18n.tr("Select currency")
                    }
                    ListView {
                        clip: true
                        width: parent.width
                        height: parent.height - header.height
                        model: currencies
                        delegate: Standard {
                            objectName: "popoverCurrencySelector"
                            text: model.currency
                            onClicked: {
                                caller.currencyIndex = index
                                caller.input.update()
                                hide()
                            }
                        }
                    }
                }
            }
        }

        Column {
            id: pageLayout

            anchors {
                fill: parent
                margins: root.margins
            }

            spacing: units.gu(1)

            Row {
                spacing: units.gu(1)

                Button {
                    id: selectorFrom
                    objectName: "selectorFrom"
                    property int currencyIndex: 0
                    property TextField input: inputFrom
                    text: currencies.getCurrency(currencyIndex)
                    onClicked: PopupUtils.open(currencySelector, selectorFrom)
                }

                TextField {
                    id: inputFrom
                    objectName: "inputFrom"
                    errorHighlight: false
                    validator: DoubleValidator {notation: DoubleValidator.StandardNotation}
                    width: pageLayout.width - 2 * root.margins - root.buttonWidth
                    height: units.gu(5)
                    font.pixelSize: FontUtils.sizeToPixels("medium")
                    text: '0.0'
                    onTextChanged: {
                        if (activeFocus) {
                            inputTo.text = convert(inputFrom.text, selectorFrom.currencyIndex, selectorTo.currencyIndex)
                        }
                    }

                    // This is more like a callback function
                    function update() {
                        text = convert(inputTo.text, selectorTo.currencyIndex, selectorFrom.currencyIndex)
                    }
                }
            }

            Row {
                spacing: units.gu(1)
                Button {
                    id: selectorTo
                    objectName: "selectorTo"
                    property int currencyIndex: 1
                    property TextField input: inputTo
                    text: currencies.getCurrency(currencyIndex)
                    onClicked: PopupUtils.open(currencySelector, selectorTo)
                }

                TextField {
                    id: inputTo
                    objectName: "inputTo"
                    errorHighlight: false
                    validator: DoubleValidator {notation: DoubleValidator.StandardNotation}
                    width: pageLayout.width - 2 * root.margins - root.buttonWidth
                    height: units.gu(5)
                    font.pixelSize: FontUtils.sizeToPixels("medium")
                    text: '0.0'
                    onTextChanged: {
                        if (activeFocus) {
                            inputFrom.text = convert(inputTo.text, selectorTo.currencyIndex, selectorFrom.currencyIndex)
                        }
                    }

                    function update() {
                        text = convert(inputFrom.text, selectorFrom.currencyIndex, selectorTo.currencyIndex)
                    }
                }
            }

            Button {
                id: clearBtn
                objectName: "clearBtn"
                text: i18n.tr("Clear")
                width: units.gu(12)
                onClicked: {
                    inputTo.text = '0.0';
                    inputFrom.text = '0.0';
                }
            }
        }

        Component.onCompleted: {
            API.startParse(root);
        }
    }
}

  

整个项目的源码在:git clone https://gitcafe.com/ubuntu/CurrencyConverterXml.git

				
时间: 2024-10-16 19:14:48

如何在QML应用中使用Javascript来解析XML的相关文章

如何在QML应用中使用Javascript解析JSON

很多QML应需要访问web services.我们可以通过Javascript的方法来解析得到我们所需要的JSON数据,并把它们展示出来.在今天的例子中,我们将展示如何实现它? 我们可以创建一个最基本的"QML App with Simple UI (qmlproject)",并取名我们的应用为"baidutranslator".我们将使用的API为: http://openapi.baidu.com/public/2.0/bmt/translate?client_

如何在QML应用中启动Scope

在这篇文章中,我们将介绍如何在QML应用中调用Scope,并把搜索的关键词传进去.这对有些QML应用需要用到Scope的情况非常有用.更多关于url-dispatcher的知识,请在文章"使用URL dispatcher的范例"看到. Scope ID 首先我们来讲一下什么是Scope ID.我们打开我们创建的任何一个Scope的manifest.json文件: { "architecture": "@[email protected]", &q

如何在QML应用中实现一个Splash画面

在QML应用中,我们经常要用到一个SplashScreen的画面来渲染我们的应用.那么我们怎么在自己的应用中做一个Splash Screen呢? 首先我们来设计一个自己的SplashScreen的QML模块: SplashScreen.qml import QtQuick 2.0 Item { id: splash anchors.fill: parent property int timeoutInterval: 2000 signal timeout Image { id: splashIm

如何在QML应用中读写文件

我们知道,在QML应用中,有时我们需要来读写一些文件,但是在我们的QML语言中并没有相应的API接口来供我们做(虽然有API接口来存储设置文件等).那么我们怎么来做这个事情呢?我们可以通过Qt C++的方法来实现这个功能. 1)创建一个简单的模版应用 我们使用Ubuntu SDK的模版来创建一个最简单的应用:      我们选择"QML App with C++ plugin"模版来做我们的应用. 2)添加文件读写的文件到项目中 我们添加如下的C++ "FileIO类到我们的

如何在QML应用中得到一个Item的所有属性,信号及方法

Item是QML语言中最基本的元素.有时为了方便,我们可以列出它里面的所有的属性,信号及方法.我们可以通过这个方法来修改我们的属性等.在QML语言中,所有的可视的控件都是继承于Item的. 下面我们来通过一个例子来展示如何这么做.我们可以设计一个简单的QML应用如下: import QtQuick 2.0 import Ubuntu.Components 1.1 /*! \brief MainView with a Label and Button elements. */ MainView {

如何在QML应用中调用系统设置中的页面来设置我们的系统

我们在QML应用中有时需要调用系统设置(system settings)来完成我们的一些设置.比如,我们在使用GPS来定位时,可能GPS并没有打开,如果在我们的应用中直接打开系统中的GPS设置页面,这样我们就可以直接打开系统的GPS而不用单独设计一个页面.我们可以通过使用URL dispatcher的方法来打开另外一个应用.在先前的我们的文章中,我们已经讲述了很多关于URL dispatcher方面的东西: 怎么在Ubuntu手机上发送短信及拨打电话 使用URL dispatcher的范例 关于

Android中通过SAX方式解析XML

每个访问网络的应用程序都有一个自己的服务器,我们可以向服务器提交数据,也可以从服务器上获取数据.那么,这些数据是用什么格式在网络上传输的呢?一般,我们会在网络上传输一些格式化的数据,这些数据有一定的结构和语义.另一方收到数据消息后就可以按照相同的结构规格来进行解析,从而获取到想要的那部分内容. 网络上传输数据最常用的格式有两种,XML和JSON.下面,我们介绍通过SAX方式来解析XML. 首先,进行准备一段XML格式的数据. get_data.xml 1 <apps> 2 <app>

Spring中管理Bean以及解析XML

Spring是分层的轻量级框架 以IoC(Inverse of Control 反转控制)和AOP(Aspect Oriented Programming 面向切面编程)为核心 应用Spring的好处: 方便解耦,简化开发 Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理 AOP编程的支持 Spring提供面向切面编程,可以方便的实现对程序进行权限拦截.运行监控等功能 声明式事务的支持 只需要通过配置就可以完成对事务的管理,而无需手动编程 方便集成各种优秀框架

在java项目中怎样利用Dom4j解析XML文件获取数据

在曾经的学习.net时常常会遇到利用配置文件来解决项目中一些须要常常变换的数据.比方数据库的连接字符串儿等.这个时候在读取配置文件的时候.我们一般会用到一个雷configuration,通过这个类来进行直接读取,能够说这是程序中直接封装好的,包含配置文件里书写的格式等等.那么,假设.想要在配置文件里写一些其它的数据,直接以XML文件的格式进行书写.这个时候在后台怎样读取XML文件里的数据呢?这里利用Dom4j来解析XML文件里连接oracle数据库的xml数据. 在使用之前,首先要在自己的项目中