解析XML问题(单个对象与多个对象)

时间:2012-05-24 19:50:56

标签: xml flex parsing actionscript

我正在构建一个flex(移动)项目。当我想解析我遇到的Web服务的结果(一些令人沮丧的,可能是愚蠢的)时。 当我得到一个对象时,我需要使用一种解析方法,而当我从webservice收到多个对象(ArrayCollection)时,我需要使用另一种解析方法,这非常烦人。我已经包含了一个代码示例,它解决了这个问题。此外,我已经包含了一个可能的解决方案,这在我看来非常糟糕。您还可以找到XML大纲和一些输出数据。感谢您的任何反馈。

代码:

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>

对象testdata的打印输出:(使问题更加清晰。)

//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

一个糟糕的解决方案:

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
                        }
                    }
                }
            }

1 个答案:

答案 0 :(得分:1)

一种方法是在开始解析例程之前检查对象的类型,如果它不是ArrayCollection类型,则创建一个新的ArrayCollection并将对象添加到它:

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]);
}