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