I've got and XML String in javascript (qml). My goal is to filter informations regarding different lines. I want an object containing the line name ( attribute) and especially the countdowns. For one line name there are departures_count * countdown fields. I want all these (in the current case its 2) countdown values in an array. And the ultimate goal is to load the whole line in a ListModel of the form: line(name, countdown(1,2,..x))
.
The big problem is to access the attributes. In qml somehow the standard functions for the DOM tree are not supported: "Object has no such function as getAttribute()" and others aswell, like getElementByTagName(). With XmlListModel I can access attributes, but just if there is just one. In each other case it returns unknown (there is a bug in qt as far as I found out).
I allready tried pure XmlListModel, but had no luck (see: Parse XmlHttpRequest to XmlListModel) - there multiple entries are not supported. So I try to find a workarround:
To be processed 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 climbing the Object xml tree
With
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;
}
I can dig in to get the element line out of the whole xml tree.
attributeInterface.xml = depatures[0];
attributeInterface.query = "/"
attributeInterface.roles.name = "countdown";
attributeInterface.roles.query = "@countdown/string()";
and with this:
XmlListModel {
id: attributeInterface
onStatusChanged: {
for (var i = 0; i < count; i++) {
console.debug({"countdown": parseFloat(get(i).countdown) });
}}}
I tried to get the attributes out. But the problem there is, that the assignment is invalid, because the xml-elements are objects (DOM? but the methods for such are not there..) and not text.
2 Regex
So my last bet, is to use regular expressions. Is there a way to get ALL countdown values? This is my best try, but it somehow just gets one value (i tried the + at the end to find all countdowns, but it wouldnt work. /delay\=\"\d*\".countdown\=\"(\d*)\"+/
And this
for(var i = 0; i<5; i++) console.debug(found[i]);
is how I retrieve the matches. The second iteration, so found[1] gives me 1 correct countdown. But how do I expand this concept to get all the countdowns?
Hi I do not know if that solves your problem. But I had similar problem and sovled it (related to your problem) like this. `
After searching and playing 2 days through, I got it. I hope this won't bother anyone anymore. There are 2 possible ways I found:
1 loopy loop
Or up the DomTree (number 1 in the org. question):
http://doc.qt.digia.com/qt-maemo/qdeclarativeglobalobject.html
This side was what I was looking for the whole time. It is bad documented (like everything I found about qml/qt), but has the one property one needs to read the attribute fields: attributes (note the typo in the link). It is an array of the attributes, so attributes[1].name is the name of the second att.
Thereafter I just need an easy way to climb the tree, which is described in the org. question.
2 XmlListModels
Since there is a depature count, one can fetch all these counts and then somehow fiddle together the countdowns (all in a list) and the respective lines (with the info how many counts for a line).
This is now just number 2, since if you don't got a hint how many attributes per node, this won't work. The order would go lost.