I m building a flex (mobile) project. When I want to parse the result of a webservice I m having (some frustrating & probably stupid) issues. When I get one object back I need to use one method of parsing, while when I receive multiple objects (ArrayCollection) from the webservice I need to use another method of parsing which is quite annoying. I ve included a code example which accents the problem. Further on I ve included a possible solution which is in my eyes quite bad. You can also find an XML outline and some output data. Thanks for any feedback.
Code:
public function saveData(event):void{
locationDAO = new LocationDAO();
parameterDAO = new ParameterDAO();
for each (var datObj:Object in event.result.Envelope.Body.pollResponse.locs)
{
var data:Data = new Data();
if (obj.locParams.length > 1){
data.loc_id = locationDAO.getID(datObj.loc);
for each (var p:Object in event.result.Envelope.Body.pollResponse.locs.locParams.params){
data.par_id = parameterDAO.getID(p.abbr);
if (p.measures.measure != null){
data.date = StringFormat.StringToDate(p.measures.measure.ctDate);
data.trend = p.measures.measure.trend;
data.value = p.measures.measure.val;
}else{
//prediction
data.date = StringFormat.StringToDate(p.measures.prediction.ctDate);
data.trend = "/";
data.value = p.measures.prediction.val;
}
if (!dataDAO.exist(data)){
dataDAO.insert(data);
}else
dataDAO.update(data);
}
}
locationDAO = null;
parameterDAO = null;
}
XML:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<pollResponse xmlns="an-url">
<locs>
<locParams>
<loc>dummyLoc1</loc>
<params>
<param>
<abbr>abbr1</abbr>
<measures>
<measure>
<ctDate>date1</ctDate>
<calc>false</calc>
<val>-178.901692</val>
</measure>
</measures>
</param>
</params>
</locParams>
<locParams>
<loc>dummyLoc2</loc>
<params>
<param>
<abbr>abbr2</abbr>
<measures>
<prediction>
<ctDate>date2</ctDate>
<val>115.0</val>
</prediction>
</measures>
</param>
<param>
<abbr>abbr3</abbr>
<measures>
<prediction>
<ctDate>date3</ctDate>
<val>11.0</val>
</prediction>
</measures>
</param>
</params>
</locParams>
</locs>
<msgs/>
</pollResponse>
</soapenv:Body>
</soapenv:Envelope>
Printout of object testdata: (to make the problem more clear.)
//With one item -> I get one object, with multiple items I get an ArrayCollection.
This brings up an difference in parsing because the level is different.
---------------------------------------------------------
event.result.Envelope.Body.pollResponse.locs
---------------------------------------------------------
//////// 1 Row
(Object)#0
locParams = (Object)#1
loc = "VSHI"
params = (Object)#2
param = (Object)#3
abbr = "XQU"
measures = (Object)#4
prediction = (Object)#5
ctDate = "date1"
pdtDate = "date2"
val = 115
//////// Multiple rows
(Object)#0
locParams = (mx.collections::ArrayCollection)#1
filterFunction = (null)
length = 2
list = (mx.collections::ArrayList)#2
length = 2
source = (Array)#3
[0] (Object)#4
loc = "MIL"
params = (Object)#5
param = (Object)#6
abbr = "XX1"
measures = (Object)#7
measure = (Object)#8
calc = false
ctDate = "date1"
trend = "S"
val = 19
[1] (Object)#9
loc = "VSI1"
params = (Object)#10
param = (Object)#11
abbr = "KSI"
measures = (Object)#12
prediction = (Object)#13
ctDate = "date1"
pdtDate = "date3"
val = 115
uid = "SELKFDS03302309303930209"
sort = (null)
source = (Array)#3
---------------------------------------------------------
event.result.Envelope.Body.pollResponse.locs.locParams
---------------------------------------------------------
//////// 1 Row
(Object)#0
locParams = (Object)#1
loc = "VSI1"
params = (Object)#2
param = (Object)#3
abbr = "HO3"
measures = (Object)#4
prediction = (Object)#5
ctDate = "date1"
pdtDate = "date2"
val = 115
//////// Multiple Rows
(mx.collections::ArrayCollection)#0
filterFunction = (null)
length = 2
list = (mx.collections::ArrayList)#1
length = 2
source = (Array)#2
[0] (Object)#3
loc = "DPS2"
params = (Object)#4
param = (Object)#5
abbr = "WI2"
measures = (Object)#6
measure = (Object)#7
calc = false
ctDate = "date1"
trend = "S"
val = 14.356693
[1] (Object)#8
loc = "VSH1"
params = (Object)#9
param = (Object)#10
abbr = "SO2"
measures = (Object)#11
prediction = (Object)#12
ctDate = "date1"
pdtDate = "date2"
val = 115
uid = "XXLSKS0OID0I0I30J3LJ"
sort = (null)
source = (Array)#2
A bad solution:
for each (var obj:Object in ArrayUtil.toArray(event.result.Envelope.Body.pollResponse.locs))
{
var data:Data = new Data();
if (obj.locParams.length > 1){
trace("array of objects")
for each (var arrObj:Object in obj.locParams){
data = new Data();
data.loc_id = locationDAO.getID(arrObj.loc);
if (arrObj.params.param.length > 1){
//multiple params
for each (var arrParam:Object in obj.locParams.params.param ){
if (arrParam.measures.measure != null){
//measure
data.date = StringFormat.StringToDate(arrParam.measures.measure.ctDate);
data.trend = arrParam.measures.measure.trend;
data.value = arrParam.measures.measure.val;
//NOTE: this can go further: there can be multiple measures
}else{
//prediction
data.date = StringFormat.StringToDate(arrParam.measures.prediction.ctDate);
data.trend = "/";
data.value = arrParam.measures.prediction.val;
//NOTE: this can go further: there can be multiple predictions
}
}
}else{
//1 param
var par:Object = arrObj.params.param;
if (par.measures.measure != null){
//measure
data.date = StringFormat.StringToDate(par.measures.measure.ctDate);
data.trend = par.measures.measure.trend;
data.value = par.measures.measure.val;
//NOTE: this can go further: there can be multiple measures
}else{
//prediction
data.date = StringFormat.StringToDate(par.measures.prediction.ctDate);
data.trend = "/";
data.value = par.measures.prediction.val;
//NOTE: this can go further: there can be multiple predictions
}
}
}
}else{
trace("1 object, no array");
data.loc_id = locationDAO.getID(obj.locParams.loc);
if (obj.locParams.params.param.length > 1){
//multiple params
for each (var arrParam:Object in obj.locParams.params.param ){
if (arrParam.measures.measure != null){
//measure
data.datum = StringFormat.StringToDate(arrParam.measures.measure.ctDate);
data.trend = arrParam.measures.measure.trend;
data.waarde = arrParam.measures.measure.val;
//NOTE: this can go further: there can be multiple measures
}else{
//prediction
data.datum = StringFormat.StringToDate(arrParam.measures.prediction.ctDate);
data.trend = "/";
data.waarde = arrParam.measures.prediction.val;
//NOTE: this can go further: there can be multiple predictions
}
}
}else{
//1 param
var par:Object = obj.locParams.params.param;
if (par.measures.measure != null){
//measure
data.date = StringFormat.StringToDate(par.measures.measure.ctDate);
data.trend = par.measures.measure.trend;
data.value = par.measures.measure.val;
//NOTE: this can go further: there can be multiple measures
}else{
//prediction
data.date = StringFormat.StringToDate(par.measures.prediction.ctDate);
data.trend = "/";
data.value = par.measures.prediction.val;
//NOTE: this can go further: there can be multiple predictions
}
}
}
}