59413fcc8277b490d848ea7d80a3d075a8d4cd03
[profile/ivi/qtxmlpatterns.git] / doc / src / examples / trafficinfo.qdoc
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the documentation of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:FDL$
9 ** GNU Free Documentation License
10 ** Alternatively, this file may be used under the terms of the GNU Free
11 ** Documentation License version 1.3 as published by the Free Software
12 ** Foundation and appearing in the file included in the packaging of
13 ** this file.
14 **
15 ** Other Usage
16 ** Alternatively, this file may be used in accordance with the terms
17 ** and conditions contained in a signed written agreement between you
18 ** and Nokia.
19 **
20 **
21 **
22 **
23 **
24 ** $QT_END_LICENSE$
25 **
26 ****************************************************************************/
27
28 /*!
29     \example xmlpatterns/trafficinfo
30     \title TrafficInfo Example
31
32     Shows how XQuery can be used extract information from WML documents provided by a WAP service.
33
34     \section1 Overview
35
36     The WAP service used in this example is \l{Trafikanten}{wap.trafikanten.no}
37     that is run by the Norwegian governmental agency for public transport in
38     Oslo. The service provides real time information about the departure of
39     busses, trams and undergrounds for every station in the city area.
40
41     This example application displays the departure information for a specific
42     station and provides the feature to filter for a special bus or tram line.
43
44     \image trafficinfo-example.png
45
46     \section1 Retrieving the Data
47
48     Without the knowledge of XQuery, one would use QNetworkAccessManager to
49     query the WML document from the WAP service and then using the QDom
50     classes or QXmlStreamReader classes to iterate over the document and
51     extract the needed information.
52     However this approach results in a lot of glue code and consumes valuable
53     developer time, so we are looking for something that can access XML
54     documents locally or over the network and extract data according to given
55     filter rules. That's the point where XQuery enters the stage!
56
57     If we want to know when the underground number 6 in direction
58     \Aring\c{}sjordet is passing the underground station in Nydalen on November
59     14th 2008 after 1pm, we use the following URL:
60
61     \c{http://wap.trafikanten.no/F.asp?f=03012130&t=13&m=00&d=14.11.2008&start=1}
62
63     The parameters have the following meanings:
64     \list
65         \li \e{f} The unique station ID of Nydalen.
66         \li \e{t} The hour in 0-23 format.
67         \li \e{m} The minute in 0-59 format.
68         \li \e{d} The date in dd.mm.yyyy format.
69         \li \e{start} Not interesting for our use but should be passed.
70     \endlist
71
72     As a result we get the following document:
73
74     \quotefile xmlpatterns/trafficinfo/time_example.wml
75
76     So for every departure we have a \c <a> tag that contains the time as a
77     text element, and the following text element contains the line number
78     and direction.
79
80     To encapsulate the XQuery code in the example application, we create a
81     custom \c TimeQuery class. This provides the \c queryInternal() function
82     that takes a station ID and date/time as input and returns the list of
83     times and directions:
84
85     \snippet xmlpatterns/trafficinfo/timequery.cpp 1
86
87     The first lines of this function synthesize the XQuery strings that fetch
88     the document and extract the data.
89     For better readability, two separated queries are used here: the first one
90     fetches the times and the second fetches the line numbers and directions.
91
92     The \c doc() XQuery method opens a local or remote XML document and returns
93     it, so the \c{/wml/card/p/small/} statement behind it selects all XML nodes
94     that can be reached by the path, \c wml \rarrow \c card \rarrow \c p \rarrow
95     \c small.
96     Now we are on the node that contains all the XML nodes we are interested in.
97
98     In the first query we select all \c a nodes that have a \c href attribute
99     starting with the string "Rute" and return the text of these nodes.
100
101     In the second query we select all text nodes that are children of the
102     \c small node which start with a number.
103     These two queries are passed to the QXmlQuery instance and are evaluated
104     to string lists. After some sanity checking, we have collected all the
105     information we need.
106
107     In the section above we have seen that an unique station ID must be passed
108     as an argument to the URL for retrieving the time, so how to find out which
109     is the right station ID to use? The WAP service provides a page for that
110     as well, so the URL
111
112     \c{http://wap.trafikanten.no/FromLink1.asp?fra=Nydalen}
113
114     will return the following document:
115
116     \snippet xmlpatterns/trafficinfo/station_example.wml 0
117
118     The names of the available stations are listed as separate text elements
119     and the station ID is part of the \c href attribute of the parent \c a
120     (anchor) element. In our example, the \c StationQuery class encapsulates
121     the action of querying the stations that match the given name pattern with
122     the following code:
123
124     \snippet xmlpatterns/trafficinfo/stationquery.cpp 0
125
126     Just as in the \c TimeQuery implementation, the first step is to
127     synthesize the XQuery strings for selecting the station names and the
128     station IDs. As the station name that we pass in the URL will be input
129     from the user, we should protect the XQuery from code injection by using
130     the QXmlQuery::bindVariable() method to do proper quoting of the variable
131     content for us instead of concatenating the two strings manually.
132
133     So, we define a XQuery \c $station variable that is bound to the user
134     input. This variable is concatenated inside the XQuery code with the
135     \c concat method. To extract the station IDs, we select all \c a elements
136     that have an \c title attribute with the content "Velg", and from these
137     elements we take the substring of the \c href attribute that starts at the
138     18th character.
139
140     The station name can be extracted a bit more easily by just taking the
141     text elements of the selected \a elements.
142
143     After some sanity checks we have all the station IDs and the corresponding
144     names available.
145
146     The rest of the code in this example is just for representing the time and
147     station information to the user, and uses techniques described in the
148     \l{Widget Examples}.
149 */