English 中文(简体)
分析 XML 问题( 单对象对多个对象)
原标题:Parse XML issue (single object vs multiple objects)

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
                        }
                    }
                }
            }
最佳回答

一种办法是在开始解析常规之前检查对象的类型,如果不是类型 Array Collection 创建一个新的 Array Collection 并添加对象到它:

var collection:ArrayCollection;

var result_1:Object = {};
var result_2:ArrayCollection = new ArrayCollection([{}, {}]);

trace("result 1", convertToArrayCollection(result_1));
trace("result 2", convertToArrayCollection(result_2));

// result 1 [object Object]
// result 2 [object Object],[object Object]

function convertToArrayCollection(obj:*):ArrayCollection
{   
    // If obj is an ArrayCollection return it. If obj is  
    // not an ArrayCollection, create a new ArrayCollection
    // and add obj as the only element.
    return (obj is ArrayCollection)
        ? ArrayCollection(obj)
        : new ArrayCollection([obj]);
}
问题回答

暂无回答




相关问题
Disable button tooltip in AS3

I want to disable the tooltip on certain buttons. The tooltip manager seems to be an all or nothing solution. Is it possible to disable the tooltip for just one or two buttons?

Multiple Remote call made simultenously

I was making multiple remote calls and they are done sequentially and when I am getting a result event back it s triggering calls to all the methods with ResultEvent as an argument . I am supposed to ...

Attaching a property to an event in Flex/AS3

I have a parameter that needs to be passed along with an event. After unsuccessful attempts to place it on the type by extending the class, I ve been advised in another SO question to write a custom ...

Clearing RSL in Cache

I have built a flex application which has a "main" project and it is assosciated with a few RSL s which are loaded and cached once i run my "main" application. The problem i am facing is that the ...

What s a good way of deserializing data into mock objects?

I m writing a mock backend service for my flex application. Because I will likely need to add/edit/modify the mock data over time, I d prefer not to generate the data in code like this: var mockData =...

AS3 try/catch out of memory

I m loading a few huge images on my flex/as3 app, but I can t manage to catch the error when the flash player runs out of memory. Here is the what I was thinking might work (I use ???? because i dont ...

热门标签