Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Highlighted
New Contributor
Posts: 3
Registered: ‎06-21-2011
My Device: Z10 STL 100-3
My Carrier: TELUS

Load XML into JS Array

Hey everyone, first post here. I've been searching around for a bit, and chatting with some other Devs I know, but I can't seem to solve my problem.

 

I need to load an XML file into an array of some sort. This does not nessicarily need to be JavaScript, however I understand you can easily load JS into a QML signal.

 

XML:

 <Content>

         <Item>

               <service_id>3_merged_837286</service_id>

               <start_date>20121230</start_date>

               <end_date>20130323</end_date>

               <monday>0</monday>

               <tuesday>0</tuesday>

               <wednesday>0</wednesday>

               <thursday>0</thursday>

               <friday>0</friday>

               <saturday>0</saturday>

               <sunday>1</sunday>

         </Item>

</Content>

 

This repeats several times.

 

QML:

 

 DataSource {

            id: calendarDataSource

            source: "asset:///calendar.xml"

            query: "/Content"

            type: DataSourceType.Xml

            onDataLoaded: {

                console.log("DEBUGGING:-----Before-----")

                var Content = data

                console.log("DEBUGGING:-----DATA-----:" + Content)

                var marray = [], tarray = [], warray = []

                for(var i = 0; i < Content.length; i++) {

                    var Content = Content[i];

                    var monday = Content.getElementsByTagName("monday");

                    for(var j = 0; j < monday.length; j++) {

                        marray.push(monday[j].childNodes[0].nodeValue);

                    }

                    var tuesday = Content.getElementsByTagName("tuesday");

                    for(var j = 0; j < tuesday.length; j++) {

                        tarray.push(tuesday[j].childNodes[0].nodeValue);

                    }

                }

                console.log(JSON.stringify(marray))

                console.log(JSON.stringify(tarray))

 

            }

}

 

This should load the data into the javascript array, or at least thats what I want it to do. However, it isn't. The console log ends up saying something along the lines of "[object Object]" and I don't know why.

 

This is my first time working with Qt and and JavaScript, as well as my first time building an app, so I don't really know where to start in terms of debugging this.

 

-Robert

Developer
Posts: 6,473
Registered: ‎12-08-2010
My Device: PlayBook, Z10
My Carrier: none

Re: Load XML into JS Array

When I run that with the second log output changed to print('DEBUGGING:-----DATA-----:', content, JSON.stringify(content));  I get the following:

 

15:47:46.254 default 9000  DEBUGGING:-----Before-----
15:47:46.254 default 9000  DEBUGGING:-----DATA-----: [object Object] {".root":"Content","Item":{"end_date":"20130323","friday":"0","monday":"0","saturday":"0","service_id":"3_merged_837286",
"start_date":"20121230","sunday":"1","thursday":"0","tuesday":"0","wednesday":"0"}}

The only difference is you said "this repeats several times" about the XML you show. If that's really true, then it's not a valid XML file since it contains more than one item as the root document.  If you were to wrap all the <Content> elements with a single outer one, say <Calendar>, and change your query property to match, does it change anything?


Peter Hansen -- (BB10 and dev-related blog posts at http://peterhansen.ca.)
Author of White Noise and Battery Guru for BB10 and for PlayBook | Get more from your battery!
New Contributor
Posts: 3
Registered: ‎06-21-2011
My Device: Z10 STL 100-3
My Carrier: TELUS

Re: Load XML into JS Array

No, I meant the <item> tag repeats. Not content. The content tag is the root tag.
Developer
Posts: 6,473
Registered: ‎12-08-2010
My Device: PlayBook, Z10
My Carrier: none

Re: Load XML into JS Array

So it should be loading... I guess you're getting the first output so it must be a valid file.

Try the JSON.stringify() approach on the raw content the way I did above, and you ought to see more than just [object Object]. The default JavaScript toString() routine which produces that output is pretty useless generally... stringify() is nearly always more helpful at least when you're not certain what form the data may take.

Peter Hansen -- (BB10 and dev-related blog posts at http://peterhansen.ca.)
Author of White Noise and Battery Guru for BB10 and for PlayBook | Get more from your battery!
Developer
Posts: 6,473
Registered: ‎12-08-2010
My Device: PlayBook, Z10
My Carrier: none

Re: Load XML into JS Array

So adding a second Item element I get output like this:

{".root":"Content","Item":
[
{"end_date":"20130323","friday":"0","id":"1","monday":
{".data":"0","urgent":"true"},"saturday":"0","service_id":"3_merged_837286",
"start_date":"20121230","sunday":"1","thursday":"0","tuesday":"0","wednesday":"0"},

{"end_date":"20140323","friday":"0","id":"2","monday":"0",
"saturday":"0","service_id":"testing","start_date":"20131230",
"sunday":"1","thursday":"1","tuesday":"1","wednesday":"1"}
]
}

Extra whitespace added to improve readability. I also made my first monday element look like this just to see what it would do with attributes: <monday urgent="true">0</monday>

 


Peter Hansen -- (BB10 and dev-related blog posts at http://peterhansen.ca.)
Author of White Noise and Battery Guru for BB10 and for PlayBook | Get more from your battery!
Developer
Posts: 6,473
Registered: ‎12-08-2010
My Device: PlayBook, Z10
My Carrier: none

Re: Load XML into JS Array

And assuming you get the same with stringify(), then it looks like the rest of the problem is just that the DataSource doesn't provide the conventional "DOM" API to access the data, so there's no getElementsByTagName() etc. It's actually a C++ class, which is parsing the XML and turning it into a nested structure of QObjects of various kinds (e.g. QVariantMap, QVariantList, etc), and when you retrieve that data in JavaScript the QML engine is automatically mapping all of those to JavaScript objects and arrays.

Peter Hansen -- (BB10 and dev-related blog posts at http://peterhansen.ca.)
Author of White Noise and Battery Guru for BB10 and for PlayBook | Get more from your battery!
New Contributor
Posts: 3
Registered: ‎06-21-2011
My Device: Z10 STL 100-3
My Carrier: TELUS

Re: Load XML into JS Array

I agree it doesn't look like the dataSource has the ability for DOM. Does this mean that I need to pass the data using

 

dataModelID.insertList(data)

 

then have the data sorted from there?

 

If not, how would I go about sorting the data into arrays from the dataSource? From Peter's reply, it seems like I need to call a C++ class to do this for me?

Developer
Posts: 6,473
Registered: ‎12-08-2010
My Device: PlayBook, Z10
My Carrier: none

Re: Load XML into JS Array

JavaScript is a reasonably powerful language, and it can certainly be used to do sorting.

First you need to read the data into an array, which as shown above is basically how it arrives with the dataLoaded() signal.

Then you need to create a sorting function, which returns a value comparing two inputs a and b. For numeric data, you would extract the fields involved (which are strings in the original XML) and compare those but in your case if it's the start_date string (for example) then it can be compared non-numerically.  Then you call .sort() on the array and pass it the sorting function.

 

Rough example (untested):

function start_date_sorter(a, b) {
    if (a.start_date < b.start_date) return -1;
    else if (a.start_date > b.start_date) return 1;
    return 0;
}

onDataLoaded: {
    var items = data.Item;
    item.sort(start_date_sorter);
// items should now be sorted }

 


Peter Hansen -- (BB10 and dev-related blog posts at http://peterhansen.ca.)
Author of White Noise and Battery Guru for BB10 and for PlayBook | Get more from your battery!