使用qml读取多个Xml属性

时间:2013-10-09 20:17:40

标签: javascript xml regex qt qml

我在javascript(qml)中得到了XML String。我的目标是过滤有关不同线路的信息。我想要一个包含行名(属性)的对象,尤其是倒计时。对于一个行名称,有departures_count *倒计时字段。我想要一个数组中的所有这些(在当前情况下为2)倒计时值。最终目标是将整行加载到表单的ListModel中:line(name, countdown(1,2,..x))

最大的问题是访问属性。在qml中,不支持DOM树的标准函数:“Object没有像getAttribute()这样的函数”,还有其他函数,比如getElementByTagName()。使用XmlListModel,我可以访问属性,但只是只有一个。在其他情况下,它返回unknown(据我发现,qt中有一个bug)。

我已经尝试过纯XmlListModel,但没有运气(参见:Parse XmlHttpRequest to XmlListModel) - 不支持多个条目。所以我试着找到一个工作场所:

要处理XML:

<?xml version="1.0" encoding="UTF-8"?> 
<ft> 
  <response> 
    <client device="" appName="" clientId="123" appVersion=""/> 
    <responseType>api_get_monitor</responseType> 
    <responseTime>2011-05-31 14:41:13</responseTime> 
    <monitor id="36469" clientexpiration=""> 
      <lines count="24"> 
        <line name="U1" type="ptMetro" towards="Leopoldau" direction="H" platform="U1_H" barrierFree="1" realtimeSupported="1"> 
          <departures count="2"> 
            <departure> 
              <departureTime delay="" countdown="3"/> 
            </departure> 
            <departure> 
              <departureTime  delay="" countdown="6"/> 
            </departure> 
            <firstDeparture> 
              <departureTime  delay="" countdown=""/> 
            </firstDeparture> 
            <lastDeparture> 
              <departureTime  delay="" countdown=""/> 
            </lastDeparture> 
          </departures> 
        </line>
      </lines> 
    </monitor> 
    <trafficInfos/> 
    <message messageCode="1">ok</message> 
  </response> 
</ft> 

1攀爬Object xml树

 function getElementsByTagName(rootElement, tagName) {
        var childNodes = rootElement.childNodes;
        var elements = [];
        for(var i = 0; i < childNodes.length; i++) {
            if(childNodes[i].tagName === tagName) {
                elements.push(childNodes[i]);
            }
        }
        return elements;
    }

我可以深入挖掘整个xml树中的元素行。

attributeInterface.xml = depatures[0];
attributeInterface.query = "/"
attributeInterface.roles.name = "countdown";
attributeInterface.roles.query = "@countdown/string()";

并且用这个:

XmlListModel {
    id: attributeInterface

    onStatusChanged: {
        for (var i = 0; i < count; i++) {
            console.debug({"countdown": parseFloat(get(i).countdown) });
        }}}

我试图将属性排除在外。但问题是,赋值是无效的,因为xml元素是对象(DOM?但是这些方法不存在......)而不是文本。

2 Regex

所以我的最后一个赌注是使用正则表达式。有没有办法获得所有倒计时值?这是我最好的尝试,但它不知何故只获得一个值(我在最后尝试了+来查找所有倒计时,但它不起作用。/delay\=\"\d*\".countdown\=\"(\d*)\"+/

而且这个 for(var i = 0; i<5; i++) console.debug(found[i]);是我检索匹配的方式。第二次迭代,所以发现[1]给了我一个正确的倒计时。但是,我如何扩展这个概念以获得所有倒计时?

2 个答案:

答案 0 :(得分:1)

经过2天的搜索和播放,我明白了。我希望这不会再困扰任何人了。 我找到了两种可能的方法:

1个循环循环

或者提升DomTree(组织问题中的第1位):

http://doc.qt.digia.com/qt-maemo/qdeclarativeglobalobject.html

这一方是我一直在寻找的。记录不好(就像我发现的关于qml / qt的所有内容),但是有一个属性需要读取属性字段:属性(注意链接中的拼写错误)。它是属性的数组,因此attributes [1] .name是第二个att的名称。

此后我只需要一种简单的方法来爬树,这在组织中有所描述。问题

2 XmlListModels

由于存在一个描述计数,因此可以获取所有这些计数,然后以某种方式将倒计时(列表中的所有计数)和相应的行(以及信息的行数计算在一起)放在一起。

现在只是数字2,因为如果你没有得到每个节点有多少属性的提示,这将无效。订单会丢失。

XmlListModel {
    id: lineXmlModel
    query: "/ft/response/monitor/lines/line"

    onStatusChanged: {
        if (status === 1) {
            console.debug("lineModel has: "+count+" items");
            for (var i = 0; i < count; i++) {
                lineListModel.append({"line": get(i).line});// , "depaturesCount": parseFloat(get(i).depaturesCount) });
            }
        }
    }

    // name = variable name, query fetches the data with XPATH
    XmlRole { name: "line"; query: "@name/string()" }

} // xmlModel



XmlListModel {
    id: depatureCountXmlModel
    query: "/ft/response/monitor/lines/line/departures"

    onStatusChanged: {
        if (status === 1) {
            console.debug("departureCountModel has: "+count+" items");
            for (var i = 0; i < count; i++) {
                lineListModel.append({"line": get(i).line, "depatureCount": parseFloat(get(i).depaturesCount) });
            }
        }
    }

    XmlRole { name: "depatureCount"; query: "@count/number()" }

} // xmlModel



XmlListModel {
    id: countdownXmlModel
    query: "/ft/response/monitor/lines/line/departures/departure/departureTime"

    onStatusChanged: {
        if (status === 1 && lineXmlModel.status === 1 && depatureCountXmlModel.status === 1) {
            console.debug("CountdownModel has: "+count+" items");
            for (var i = 0; i < lineXmlModel.count; i++) {
                console.debug("Line: "+ lineXmlModel.get(i).name + " number of depatures "+ depatureCountXmlModel.get(i).depatureCount );
                // console.debug("countdown "+ parseFloat(get(i).countdown) );
                // lineListModel.append({"countdown": parseFloat(get(i).countdown) });
            }
        }
    }

    XmlRole { name: "countdown"; query: "@countdown/number()" }
}

答案 1 :(得分:0)

嗨,我不知道是否能解决您的问题。但是我遇到了类似的问题并且像这样解决了(与你的问题有关)。 `

import QtQuick 2.0 
import QtQuick.XmlListModel 2.0


ListView 
{
  width: 300;
  height: 400; 

  spacing: 10 

  model: XmlListModel 
  {
    xml: '<?xml version="1.0" encoding="UTF-8"?> 
<ft> 
  <response> 
    <client device="" appName="" clientId="123" appVersion=""/> 
    <responseType>api_get_monitor</responseType> 
    <responseTime>2011-05-31 14:41:13</responseTime> 
    <monitor id="36469" clientexpiration=""> 
      <lines count="24"> 
    <line name="U1" type="ptMetro" towards="Leopoldau" direction="H" platform="U1_H" barrierFree="1" realtimeSupported="1"> 
      <departures count="2"> 
        <departure> 
          <departureTime delay="1" countdown="3"/> 
        </departure> 
        <departure> 
          <departureTime  delay="2" countdown="6"/> 
        </departure> 
        <firstDeparture> 
          <departureTime  delay="3" countdown="99"/> 
        </firstDeparture> 
        <lastDeparture> 
          <departureTime  delay="4" countdown="98"/> 
        </lastDeparture> 
      </departures> 
    </line>
      </lines> 
    </monitor> 
    <trafficInfos/> 
    <message messageCode="1">ok</message> 
  </response> 
</ft>'; 

    query:"/ft/response/monitor/lines/line/departures/departure"

    XmlRole { name:"delay" ; query: "departureTime/@delay/number()" } 
    XmlRole { name:"countdown" ; query: "departureTime/@countdown/number()" } 


  }

  delegate: 
  Rectangle
  {
    color: "pink"; 
    width:parent.width; 
    height: col.height
  Column 
  {
    id: col 
    Text{ text: countdown } 
    Text{ text: delay } 
  }
  }

}// listView `