Android Question Help with parsing xml data

apty

Active Member
Licensed User
I need help parsing the below xml data:

B4X:
<?xml version="1.0" encoding="utf-8"?>
<aerocrs>
    <flights>
        <flight>
            <airline>Safarilink</airline>
            <airlineid>4</airlineid>
            <airlinelogo>https://storage.aerocrs.com/4/system/SafarilinkLogo.png</airlinelogo>
            <childagefrom>2</childagefrom>
            <childageto>11</childageto>
            <chargetaxoninfant>False</chargetaxoninfant>
            <from>Nairobi-Wilson</from>
            <to>Samburu</to>
            <fromcode>WIL</fromcode>
            <tocode>UAS</tocode>
            <direction>Outbound</direction>
            <flightdate>2017/06/22</flightdate>
            <depart>13:00</depart>
            <arrive>14:35</arrive>
            <number>025</number>
            <bookable>true</bookable>
            <via></via>
            <totalminutes>95</totalminutes>
            <linktowebsite>
                <url>http://www.flysafarilink.com/booking/search-results-flights.asp</url>
                <DepartureDateVal>2017/06/22</DepartureDateVal>
                <TripType>RT</TripType>
                <FromDSTid>41</FromDSTid>
                <ToDSTid>51</ToDSTid>
                <ReturnDateVal>2017/06/29</ReturnDateVal>
                <invAdlt>2</invAdlt>
                <invKids>1</invKids>
                <DepartureShow>0</DepartureShow>
                <ReturnShow>0</ReturnShow>
            </linktowebsite>
            <CompanyWebDiscount>0</CompanyWebDiscount>
            <Rules>
                <rule>this new</rule>
                <rule>This service</rule>
            </Rules>
            <flightcode>1329228</flightcode>
            <classes>
                <class flightcode="1329228">
                    <classcode>Y</classcode>
                    <classname>Economy</classname>
                    <cabinclass>Economy</cabinclass>
                    <flightid>4775281</flightid>
                    <rackfare_adult>192.50</rackfare_adult>
                    <rackfare_child>144.38</rackfare_child>
                    <rackfare_infant>0.00</rackfare_infant>
                    <agtfare_adult>192.50</agtfare_adult>
                    <agtfare_child>144.38</agtfare_child>
                    <agtfare_infant>0.00</agtfare_infant>
                    <tax>11.00</tax>
                    <rackfare_adult_no_vat>192.5000</rackfare_adult_no_vat>
                    <rackfare_child_no_vat>144.3800</rackfare_child_no_vat>
                    <rackfare_infant_no_vat>0.0000</rackfare_infant_no_vat>
                    <agtfare_adult_no_vat>192.5000</agtfare_adult_no_vat>
                    <agtfare_child_no_vat>144.3800</agtfare_child_no_vat>
                    <agtfare_infant_no_vat>0.0000</agtfare_infant_no_vat>
                    <tax_no_vat>11.0000</tax_no_vat>
                    <vat_on_fare>0.0000</vat_on_fare>
                    <vat_on_tax>0.0000</vat_on_tax>
                    <currency>USD</currency>
                    <converttousd>0</converttousd>
                    <ttl>2017/06/08 13:00</ttl>
                    <baggage>15Kg</baggage>
                    <classshowonweb>True</classshowonweb>
                </class>
            </classes>
        </flight>
         </flights>
</aerocrs>
from the xml, i want the following:

flightdate
depart
arrive
ReturnDateVal
flightid

Kindly assist
 

apty

Active Member
Licensed User
i have tried it and i can do upto the below stage where i get the flightdate,depart and arrive:
B4X:
Dim rss As Map = ParsedData.Get("aerocrs")
    Dim channel As Map = rss.Get("flights")
    Dim items As List = channel.Get("flight")
But how do i get the ReturnDateVal and flightid?
 

apty

Active Member
Licensed User
See below:

B4X:
(MyMap){flights={flight=[{airline=Northair ltd., airlineid=20, airlinelogo=https://storage.aerocrs.com/0/system/northair.png, childagefrom=2, childageto=12, chargetaxoninfant=False, from=Barcelona, to=Madrid, fromcode=BCN, tocode=MAD, direction=Outbound, flightdate=2018/05/18, depart=07:00, arrive=09:00, number=123456, bookable=true, via=, totalminutes=120, linktowebsite={url=http://northair.aerocrs.net/booking/search-results-flights.asp, DepartureDateVal=2018/05/18, TripType=RT, FromDSTid=2926, ToDSTid=2927, ReturnDateVal=2018/05/18, invAdlt=1, invKids=1, DepartureShow=0, ReturnShow=0}, CompanyWebDiscount=0, Rules=, flightcode=2238171, classes={class=[{Attributes={flightcode=2238171}, classcode=ECO/Y1, classname=EasyGo, cabinclass=Economy, flightid=9105773, rackfare_adult=90.00, rackfare_child=80.00, rackfare_infant=20.00, agtfare_adult=81.00, agtfare_child=72.00, agtfare_infant=18.00, tax=20.00, rackfare_adult_no_vat=90.0000, rackfare_child_no_vat=80.0000, rackfare_infant_no_vat=20.0000, agtfare_adult_no_vat=81.0000, agtfare_child_no_vat=72.0000, agtfare_infant_no_vat=18.0000, tax_no_vat=20.0000, vat_on_fare=0.0000, vat_on_tax=0.0000, currency=USD, converttousd=0, ttl=2018/05/18 06:00, baggage=23Kg, classshowonweb=False}, {Attributes={flightcode=2238171}, classcode=ECO/M3, classname=EasyGo2, cabinclass=Economy, flightid=9105777, rackfare_adult=110.00, rackfare_child=160.00, rackfare_infant=40.00, agtfare_adult=110.00, agtfare_child=160.00, agtfare_infant=40.00, tax=25.00, rackfare_adult_no_vat=110.0000, rackfare_child_no_vat=160.0000, rackfare_infant_no_vat=40.0000, agtfare_adult_no_vat=110.0000, agtfare_child_no_vat=160.0000, agtfare_infant_no_vat=40.0000, tax_no_vat=25.0000, vat_on_fare=0.0000, vat_on_tax=0.0000, currency=USD, converttousd=0, ttl=2018/05/18 06:00, baggage=23Kg, classshowonweb=False}]}}, {airline=Northair ltd., airlineid=20, airlinelogo=https://storage.aerocrs.com/0/system/northair.png, childagefrom=2, childageto=12, chargetaxoninfant=False, from=Barcelona, to=Madrid, fromcode=BCN, tocode=MAD, direction=Outbound, flightdate=2018/05/18, depart=08:00, arrive=10:00, number=111, bookable=true, via=, totalminutes=120, linktowebsite={url=http://northair.aerocrs.net/booking/search-results-flights.asp, DepartureDateVal=2018/05/18, TripType=RT, FromDSTid=2926, ToDSTid=2927, ReturnDateVal=2018/05/18, invAdlt=1, invKids=1, DepartureShow=0, ReturnShow=0}, CompanyWebDiscount=0, Rules=, flightcode=2111706, classes={class={Attributes={flightcode=2111706}, classcode=ECO/D, classname=TestD, cabinclass=Economy, flightid=8467819, rackfare_adult=170.59, rackfare_child=82.35, rackfare_infant=58.82, agtfare_adult=170.59, agtfare_child=82.35, agtfare_infant=58.82, tax=11.76, rackfare_adult_no_vat=170.5882, rackfare_child_no_vat=82.3529, rackfare_infant_no_vat=58.8235, agtfare_adult_no_vat=170.5882, agtfare_child_no_vat=82.3529, agtfare_infant_no_vat=58.8235, tax_no_vat=11.7647, vat_on_fare=0.0000, vat_on_tax=0.0000, currency=USD, converttousd=0, ttl=2018/05/18 08:00, baggage=80Kg, classshowonweb=True}}}, {airline=Northair ltd., airlineid=20, airlinelogo=https://storage.aerocrs.com/0/system/northair.png, childagefrom=2, childageto=12, chargetaxoninfant=False, from=Barcelona, to=Madrid, fromcode=BCN, tocode=MAD, direction=Outbound, flightdate=2018/05/18, depart=11:00, arrive=13:00, number=12345, bookable=true, via=, totalminutes=120, linktowebsite={url=http://northair.aerocrs.net/booking/search-results-flights.asp, DepartureDateVal=2018/05/18, TripType=RT, FromDSTid=2926, ToDSTid=2927, ReturnDateVal=2018/05/18, invAdlt=1, invKids=1, DepartureShow=0, ReturnShow=0}, CompanyWebDiscount=0, Rules=, flightcode=2237940, classes={class=[{Attributes={flightcode=2237940}, classcode=ECO/Y1, classname=EasyGo, cabinclass=Economy, flightid=9104170, rackfare_adult=90.00, rackfare_child=80.00, rackfare_infant=20.00, agtfare_adult=81.00, agtfare_child=72.00, agtfare_infant=18.00, tax=20.00, rackfare_adult_no_vat=90.0000, rackfare_child_no_vat=80.0000, rackfare_infant_no_vat=20.0000, agtfare_adult_no_vat=81.0
 

DonManfred

Expert
Licensed User
B4X:
    Dim m As Map = xml2map.Parse(File.ReadString(File.DirAssets,"flightdata.xml"))
   
    Dim rss As Map = m.Get("aerocrs")
    Log("RSS="&rss)
    Dim flights As Map = rss.Get("flights")
    Log("FLIGHTS="&flights)
   
    Dim items As Map = flights.Get("flight")
    Log("ITEMS="&items)
    If items.ContainsKey("linktowebsite") Then
        Dim link As Map = items.Get("linktowebsite")
        Log("LINK="&link)
        Dim url As String = link.Get("url")
        Dim ReturnDateVal As String = link.Get("ReturnDateVal")
        ' [and so on]
    End If
 

DonManfred

Expert
Licensed User
Some notes: based on the names in the XML i can imagine that "flights" (you are using as a map) can be a LIST when the Api returns more than one Flight in the Result.
For one Result (the XML you posted) it is a Map...
But it may be a List if the Api returns more flights... You need to check

B4X:
<aerocrs>
    <flights>
        <flight>
 

apty

Active Member
Licensed User
It gives an error
java.lang.ClassCastException: java.util.ArrayList cannot be cast to anywheresoftware.b4a.objects.collections.Map$MyMap
 

apty

Active Member
Licensed User
Some notes: based on the names in the XML i can imagine that "flights" (you are using as a map) can be a LIST when the Api returns more than one Flight in the Result.
For one Result (the XML you posted) it is a Map...
But it may be a List if the Api returns more flights... You need to check

B4X:
<aerocrs>
    <flights>
        <flight>
Yeah. The api returns a list.
 

apty

Active Member
Licensed User
The one just returned by the api looks like below:
B4X:
<?xml version="1.0" encoding="utf-8"?>
<aerocrs>
    <flights>
        <flight>
            <airline>Safarilink</airline>
            <airlineid>4</airlineid>
            <airlinelogo>https://storage.aerocrs.com/4/system/SafarilinkLogo.png</airlinelogo>
            <childagefrom>2</childagefrom>
            <childageto>11</childageto>
            <chargetaxoninfant>False</chargetaxoninfant>
            <from>Nairobi-Wilson</from>
            <to>Samburu</to>
            <fromcode>WIL</fromcode>
            <tocode>UAS</tocode>
            <direction>Outbound</direction>
            <flightdate>2017/06/22</flightdate>
            <depart>13:00</depart>
            <arrive>14:35</arrive>
            <number>025</number>
            <bookable>true</bookable>
            <via></via>
            <totalminutes>95</totalminutes>
            <linktowebsite>
                <url>http://www.flysafarilink.com/booking/search-results-flights.asp</url>
                <DepartureDateVal>2017/06/22</DepartureDateVal>
                <TripType>RT</TripType>
                <FromDSTid>41</FromDSTid>
                <ToDSTid>51</ToDSTid>
                <ReturnDateVal>2017/06/29</ReturnDateVal>
                <invAdlt>2</invAdlt>
                <invKids>1</invKids>
                <DepartureShow>0</DepartureShow>
                <ReturnShow>0</ReturnShow>
            </linktowebsite>
            <CompanyWebDiscount>0</CompanyWebDiscount>
            <Rules>
                <rule>ore%20your%20flight.</rule>
                <rule>r%20the%20additional%20seats.</rule>
            </Rules>
            <flightcode>1329228</flightcode>
            <classes>
                <class flightcode="1329228">
                    <classcode>Y</classcode>
                    <classname>Economy</classname>
                    <cabinclass>Economy</cabinclass>
                    <flightid>4775281</flightid>
                    <rackfare_adult>192.50</rackfare_adult>
                    <rackfare_child>144.38</rackfare_child>
                    <rackfare_infant>0.00</rackfare_infant>
                    <agtfare_adult>192.50</agtfare_adult>
                    <agtfare_child>144.38</agtfare_child>
                    <agtfare_infant>0.00</agtfare_infant>
                    <tax>11.00</tax>
                    <rackfare_adult_no_vat>192.5000</rackfare_adult_no_vat>
                    <rackfare_child_no_vat>144.3800</rackfare_child_no_vat>
                    <rackfare_infant_no_vat>0.0000</rackfare_infant_no_vat>
                    <agtfare_adult_no_vat>192.5000</agtfare_adult_no_vat>
                    <agtfare_child_no_vat>144.3800</agtfare_child_no_vat>
                    <agtfare_infant_no_vat>0.0000</agtfare_infant_no_vat>
                    <tax_no_vat>11.0000</tax_no_vat>
                    <vat_on_fare>0.0000</vat_on_fare>
                    <vat_on_tax>0.0000</vat_on_tax>
                    <currency>USD</currency>
                    <converttousd>0</converttousd>
                    <ttl>2017/06/08 13:00</ttl>
                    <baggage>15Kg</baggage>
                    <classshowonweb>True</classshowonweb>
                </class>
            </classes>
        </flight>
        <flight>
            <airline>Airkenya Express LTD</airline>
            <airlineid>5</airlineid>
            <airlinelogo>https://storage.aerocrs.com/0/system/airkenya.png</airlinelogo>
            <childagefrom>2</childagefrom>
            <childageto>11</childageto>
            <chargetaxoninfant>False</chargetaxoninfant>
            <from>Nairobi-Wilson</from>
            <to>Samburu Buffalo</to>
            <fromcode>WIL</fromcode>
            <tocode>UAS</tocode>
            <direction>Outbound</direction>
            <flightdate>2017/06/22</flightdate>
            <depart>08:30</depart>
            <arrive>09:20</arrive>
            <number>861</number>
            <bookable>true</bookable>
            <via></via>
            <totalminutes>50</totalminutes>
            <linktowebsite>
                <url>http://www.airkenya.com/booking/search-results-flights.asp</url>
                <DepartureDateVal>2017/06/22</DepartureDateVal>
                <TripType>RT</TripType>
                <FromDSTid>212</FromDSTid>
                <ToDSTid>217</ToDSTid>
                <ReturnDateVal>2017/06/29</ReturnDateVal>
                <invAdlt>2</invAdlt>
                <invKids>1</invKids>
                <DepartureShow>0</DepartureShow>
                <ReturnShow>0</ReturnShow>
            </linktowebsite>
            <CompanyWebDiscount>5</CompanyWebDiscount>
            <Rules>
                <rule>A%20minimum%20wi400hrs</rule>
            </Rules>
            <flightcode>1138174</flightcode>
            <classes></classes>
        </flight>
        <flight>
            <airline>Airkenya Express LTD</airline>
            <airlineid>5</airlineid>
            <airlinelogo>https://storage.aerocrs.com/0/system/airkenya.png</airlinelogo>
            <childagefrom>2</childagefrom>
            <childageto>11</childageto>
            <chargetaxoninfant>False</chargetaxoninfant>
            <from>Nairobi-Wilson</from>
            <to>Samburu Buffalo</to>
            <fromcode>WIL</fromcode>
            <tocode>UAS</tocode>
            <direction>Outbound</direction>
            <flightdate>2017/06/22</flightdate>
            <depart>09:15</depart>
            <arrive>10:40</arrive>
            <number>871</number>
            <bookable>true</bookable>
            <via>Via Nanyuki</via>
            <totalminutes>85</totalminutes>
            <linktowebsite>
                <url>http://www.airkenya.com/booking/search-results-flights.asp</url>
                <DepartureDateVal>2017/06/22</DepartureDateVal>
                <TripType>RT</TripType>
                <FromDSTid>212</FromDSTid>
                <ToDSTid>217</ToDSTid>
                <ReturnDateVal>2017/06/29</ReturnDateVal>
                <invAdlt>2</invAdlt>
                <invKids>1</invKids>
                <DepartureShow>0</DepartureShow>
                <ReturnShow>0</ReturnShow>
            </linktowebsite>
            <CompanyWebDiscount>5</CompanyWebDiscount>
            <Rules>
                <rule>A%220minimum%20will%20be%202%20pax.%20Loisas</rule>
            </Rules>
            <flightcode>1137444</flightcode>
            <classes>
                <class flightcode="1137444">
                    <classcode>Y</classcode>
                    <classname>Standard</classname>
                    <cabinclass>Economy</cabinclass>
                    <flightid>3805769</flightid>
                    <rackfare_adult>175.50</rackfare_adult>
                    <rackfare_child>122.85</rackfare_child>
                    <rackfare_infant>0.00</rackfare_infant>
                    <agtfare_adult>175.50</agtfare_adult>
                    <agtfare_child>122.85</agtfare_child>
                    <agtfare_infant>0.00</agtfare_infant>
                    <tax>17.00</tax>
                    <rackfare_adult_no_vat>175.5000</rackfare_adult_no_vat>
                    <rackfare_child_no_vat>122.8500</rackfare_child_no_vat>
                    <rackfare_infant_no_vat>0.0000</rackfare_infant_no_vat>
                    <agtfare_adult_no_vat>175.5000</agtfare_adult_no_vat>
                    <agtfare_child_no_vat>122.8500</agtfare_child_no_vat>
                    <agtfare_infant_no_vat>0.0000</agtfare_infant_no_vat>
                    <tax_no_vat>17.0000</tax_no_vat>
                    <vat_on_fare>0.0000</vat_on_fare>
                    <vat_on_tax>0.0000</vat_on_tax>
                    <currency>USD</currency>
                    <converttousd>0</converttousd>
                    <ttl>2017/06/08 09:15</ttl>
                    <baggage>15Kg</baggage>
                    <classshowonweb>True</classshowonweb>
                </class>
                <class flightcode="1137444">
                    <classcode>P</classcode>
                    <classname>Package</classname>
                    <cabinclass>Economy</cabinclass>
                    <flightid>3805770</flightid>
                    <rackfare_adult>175.50</rackfare_adult>
                    <rackfare_child>122.85</rackfare_child>
                    <rackfare_infant>0.00</rackfare_infant>
                    <agtfare_adult>175.50</agtfare_adult>
                    <agtfare_child>122.85</agtfare_child>
                    <agtfare_infant>0.00</agtfare_infant>
                    <tax>17.00</tax>
                    <rackfare_adult_no_vat>175.5000</rackfare_adult_no_vat>
                    <rackfare_child_no_vat>122.8500</rackfare_child_no_vat>
                    <rackfare_infant_no_vat>0.0000</rackfare_infant_no_vat>
                    <agtfare_adult_no_vat>175.5000</agtfare_adult_no_vat>
                    <agtfare_child_no_vat>122.8500</agtfare_child_no_vat>
                    <agtfare_infant_no_vat>0.0000</agtfare_infant_no_vat>
                    <tax_no_vat>17.0000</tax_no_vat>
                    <vat_on_fare>0.0000</vat_on_fare>
                    <vat_on_tax>0.0000</vat_on_tax>
                    <currency>USD</currency>
                    <converttousd>0</converttousd>
                    <ttl>2017/06/08 09:15</ttl>
                    <baggage>15Kg</baggage>
                    <classshowonweb>False</classshowonweb>
                </class>
            </classes>
        </flight>
         </flights>
</aerocrs>
 

DonManfred

Expert
Licensed User
try it with something like

B4X:
    xml2map.Initialize
    Dim m As Map = xml2map.Parse(File.ReadString(File.DirAssets,"flightdata.xml"))
    
    Dim rss As Map = m.Get("aerocrs")
    Log("RSS="&rss)
    'RSS=(MyMap) {flights={flight={linktowebsite={url=http://www.flysafarilink.com/booking/search-results-flights.asp, DepartureDateVal=2017/06/22, TripType=RT, FromDSTid=41, ToDSTid=51, ReturnDateVal=2017/06/29, invAdlt=2, invKids=1, DepartureShow=0, ReturnShow=0}
    Dim flightmap As Map = rss.Get("flights")
    Log("flightmap="&flightmap)

    If GetType(flightmap.Get("flight")) = "java.util.ArrayList" Then
    
        Dim flightlist As List = flightmap.Get("flight")
        Log(flightlist)
        
        For Each flight As Map In flightlist
            Log("FLIGHT="&flight)
            If flight.ContainsKey("linktowebsite") Then
                Dim link As Map = flight.Get("linktowebsite")
                Log("LINK="&link)
                Dim url As String = link.Get("url")
                Dim ReturnDateVal As String = link.Get("ReturnDateVal")
                ' [and so on]
            End If
            
        Next
    Else
        Dim flightmap As Map = flightmap.Get("flights")
        Dim items As Map = flightmap.Get("flight")
        Log("ITEMS="&items)
        If items.ContainsKey("linktowebsite") Then
            Dim link As Map = items.Get("linktowebsite")
            Log("LINK="&link)
            Dim url As String = link.Get("url")
            Dim ReturnDateVal As String = link.Get("ReturnDateVal")
            ' [and so on]
        End If
    End If
 

apty

Active Member
Licensed User
This works. The only challenge is getting the flight id. I have tried adding the code below but i still get an error (java.lang.ClassCastException: java.util.ArrayList cannot be cast to anywheresoftware.b4a.objects.collections.Map$MyMap)

B4X:
If flight.ContainsKey("classes") Then
                Dim clasx As Map = flight.Get("classes")
                Dim flclass As Map=clasx.Get("class")
               
                Dim fligtid As String = flclass.Get("flightid")
 

apty

Active Member
Licensed User
I converted it to json and used https://b4x.com:51041/json/index.html to generate json code. It works but crashes after getting the first entries for flightid,flightdate
depart,arrive and ReturnDateVal.
It gives me the error below:
java.lang.ClassCastException: anywheresoftware.b4a.objects.collections.Map$MyMap cannot be cast to java.util.List

It fails at the point where i am getting "class" i.e:
B4X:
Dim classes As Map = colflight.Get("classes")
        Dim class As List = classes.Get("class")
 
Last edited:

DonManfred

Expert
Licensed User
i guess you are getting ONE item here again. So Map should be used.

The problem is that the api is not consistent in its results.
If there is only one result it returns a map, if there are more, a list of maps.

You can create a code using the json tool with the results from a call containing one item.
Then you do the same with a query which returns more.

You need to adapt the code the way i did above in my example. 1st check the type; if it is a list, use the list-way; if not, use the Map-way.

If you can define a parameter which tells the api to ALWAYS return a LIST then you should use this setting. If not then it is a bit work for you to manage the different answers.
 

apty

Active Member
Licensed User
i guess you are getting ONE item here again. So Map should be used.

The problem is that the api is not consistent in its results.
If there is only one result it returns a map, if there are more, a list of maps.

You can create a code using the json tool with the results from a call containing one item.
Then you do the same with a query which returns more.

You need to adapt the code the way i did above in my example. 1st check the type; if it is a list, use the list-way; if not, use the Map-way.

If you can define a parameter which tells the api to ALWAYS return a LIST then you should use this setting. If not then it is a bit work for you to manage the different answers.
You are right. Its not consistent. I will adapt the way you did
 
Top