Чтение нескольких атрибутов Xml с помощью qml

У меня есть строка XML в javascript (qml). Моя цель - отфильтровать информацию о разных строках. Мне нужен объект, содержащий имя строки (атрибут) и особенно обратный отсчет. Для одного имени строки есть поля offsets_count * countdown. Мне нужны все эти (в данном случае 2) значения обратного отсчета в массиве. И конечной целью является загрузка всей строки в ListModel вида: line(name, countdown(1,2,..x)).

Большая проблема заключается в доступе к атрибутам. В qml почему-то не поддерживаются стандартные функции для DOM-дерева: "У объекта нет такой функции, как getAttribute()" и другие, вроде getElementByTagName(). С XmlListModel я могу получить доступ к атрибутам, но только если есть только один. В каждом другом случае он возвращает unknown (насколько мне известно, в qt есть ошибка).

Я уже пробовал чистый 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 регулярное выражение

Итак, моя последняя ставка — использовать регулярные выражения. Есть ли способ получить ВСЕ значения обратного отсчета? Это моя лучшая попытка, но она каким-то образом получает только одно значение (я попробовал + в конце, чтобы найти все обратные отсчеты, но это не сработало. /delay\=\"\d*\".countdown\=\"(\d*)\"+/

И вот так for(var i = 0; i<5; i++) console.debug(found[i]); я извлекаю спички. Вторая итерация, найденная таким образом[1], дает мне 1 правильный обратный отсчет. Но как мне расширить эту концепцию, чтобы получить все обратные отсчеты?


person mike    schedule 09.10.2013    source источник


Ответы (2)


После поиска и игры через 2 дня я получил это. Надеюсь, это больше никого не побеспокоит. Есть 2 возможных способа, которые я нашел:

1 петельная петля

Или вверх по DomTree (номер 1 в организационном вопросе):

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

Эта сторона была тем, что я искал все время. Он плохо документирован (как и все, что я нашел о qml/qt), но имеет одно свойство, необходимое для чтения полей атрибутов: атрибуты (обратите внимание на опечатку в ссылке). Это массив атрибутов, поэтому attribute[1].name — это имя второго атрибута.

После этого мне просто нужен простой способ взобраться на дерево, который описан в орг. вопрос.

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()" }
}
person mike    schedule 11.10.2013

Привет, я не знаю, решит ли это твою проблему. Но у меня была похожая проблема, и я решил ее (связанную с вашей проблемой) следующим образом. `

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 `
person 3electrons    schedule 15.06.2014