【问题标题】:How to parse this Web service response in Android?如何在 Android 中解析这个 Web 服务响应?
【发布时间】:2009-08-13 05:35:12
【问题描述】:

我正在使用 KSOAP2 从 android 应用程序调用 .NET webservice,并且 web 服务的响应格式如下

anyType{
UserName=anyType{}; 
Password=anyType{}; 
ApplicationCode=JOB; 
ActionType=Query; 
MessageParameters=anyType{Parameters=anyType{}; }; 
TableData=anyType{TableNo=167; 
          TableName=Job; 
      DataRows=
      anyType{
        DataRow=
          anyType{
             DataRowValues=
            anyType{
                DataRowValue=
                anyType{
                    FieldNo=1; 
                    FieldName=No.; 
                    PrimaryKey=true; 
                    FieldType=Code20; DataValue=DEERFIELD, 8 WP; 
                       };
               DataRowValue=
                anyType
                       {
                    FieldNo=3; 
                    FieldName=Description; 
                    PrimaryKey=false; 
                    FieldType=Text50; 
                    DataValue=Setting up Eight Work Areas; 
                       };
             DataRowValue=
                anyType
                       {
                    FieldNo=4; 
                    FieldName=Description 2; 
                    PrimaryKey=false; 
                    FieldType=Text50; 
                    DataValue=anyType{}; 
                       }; 
                }; 
              }; 
           }; 
       }; 
    }; 
 ResponseForRequest=GETTABLEDATA; 
 CustomIdentifier=TestBB; 
Applications=anyType{}; 
Forms=anyType{}; 
Menu=anyType{}; 
}

我不知道这个响应的格式,我不知道如何解析这个响应以获得特定的结果。任何知道它的人请帮助我。

注意:我手动格式化了此响应以供您理解。

【问题讨论】:

    标签: android


    【解决方案1】:

    如果您知道 Java Script,实际上这是一种已知格式。这种格式的这些数据实际上是 JSON ObjectJSON Array 的。我希望你使用的是KSOAP2 library。所以这里是你如何解析这个结果。

    例如:

    private Bundle bundleResult=new Bundle();
    private JSONObject JSONObj;
    private JSONArray JSONArr;
    Private SoapObject resultSOAP = (SoapObject) envelope.getResponse();
    /* gets our result in JSON String */
    private String ResultObject = resultSOAP.getProperty(0).toString();
    
    if (ResultObject.startsWith("{")) { // if JSON string is an object
        JSONObj = new JSONObject(ResultObject);
        Iterator<String> itr = JSONObj.keys();
        while (itr.hasNext()) {
            String Key = (String) itr.next();
            String Value = JSONObj.getString(Key);
            bundleResult.putString(Key, Value);
            // System.out.println(bundleResult.getString(Key));
        }
    } else if (ResultObject.startsWith("[")) { // if JSON string is an array
        JSONArr = new JSONArray(ResultObject);
        System.out.println("length" + JSONArr.length());
        for (int i = 0; i < JSONArr.length(); i++) {
            JSONObj = (JSONObject) JSONArr.get(i);
            bundleResult.putString(String.valueOf(i), JSONObj.toString());
            // System.out.println(bundleResult.getString(i));
        } 
    }
    

    最初我在处理这类数据时遇到了很多麻烦,但最后我得到了一切工作。从那时起我一直在使用它。我希望这可以帮助你解决你的问题。

    【讨论】:

    • 如何将该解析方法的结果放入我的返回语句中?
    • 现在你会得到格式为 {key1:val1, key2:val2,......} 的结果,它们存储在一个包中,所以返回'bundleResult'跨度>
    【解决方案2】:

    前提是 SOAP 响应采用有效的 JSON 格式;接受的答案可能并不总是成功,因为响应字符串不是以“{”开头,而是以“anyType”开头。

    在这种情况下,我总是收到关于“anyType”不是有效 JSON 对象的错误。然后我继续使用 IndexOf("{"); 对响应字符串进行子串化。然后开始解析,但如果响应字符串不是有效的 JSON 格式,它将再次中断。

    这里的问题是我的响应字符串包含未转义的字符,与 JSON 格式不兼容。

    参考这个答案:Android KSoap2: how to get property name

    这是我设法实现的:

        public Bundle getElementsFromSOAP(SoapObject so){
        Bundle resultBundle = new Bundle();
        String Key = null;
        String Value = null;
        int elementCount = so.getPropertyCount();                  
    
        for(int i = 0;i<elementCount;i++){
            PropertyInfo pi = new PropertyInfo();
            SoapObject nestedSO = (SoapObject)so.getProperty(i);
    
            int nestedElementCount = nestedSO.getPropertyCount();
            Log.i(tag, Integer.toString(nestedElementCount));
    
            for(int ii = 0;ii<nestedElementCount;ii++){
                nestedSO.getPropertyInfo(ii, pi);
                resultBundle.putString(pi.name, pi.getValue().toString());
                //Log.i(tag,pi.getName() + " " + pii.getProperty(ii).toString());
                //Log.i(tag,pi.getName() + ": " + pi.getValue());
    
            }
        }
    
        return resultBundle;
    
    }
    

    【讨论】:

    • @Zarah 我不确定您发布的问题在问什么。您能否提供这方面的更多详细信息。
    • 感谢您的回复。我使用了您的方法,但整个数据字符串作为一个属性从 Web 服务返回(propertyCount 为 1)。其次,我的响应字符串无法在在线 JSON 解析器中验证,所以我认为我的数据不是有效的 JSON 格式。我发布了question here。那么你能建议我用什么方法来解析来自网络服务的这种响应吗?
    • @Zarah:正如您在链接的问题中提到的,此处发布的解决方案在一定程度上起作用,应作为理解 KSOAP 如何映射 Web 服务响应的基础。考虑到这一点,您应该使用此代码示例来识别每个 anyType 元素并将其映射\转换为对象。然后对于您映射\转换为对象的每个 anyType 元素;检查它是否属于 Soap 类并进行属性计数,并在这方面对 anyType 元素遵循相同的过程。对于不是 Soap 类类型的对象 (key1:value1),从主 soap 对象中将其检索为 getPropertyAsString
    • @Zarah: propertyCount=1 因为 Web 服务字符串(响应)是一个肥皂对象。将您的字符串转换为肥皂对象,然后执行 propertyCount,它将返回 3。其中一个属性 (key3=anyType) 是另一个肥皂对象,应该这样进行转换。
    【解决方案3】:

    例如您的回复:

    anyType
    {
      FOO_DEALS=anyType
      {
           CATEGORY_LIST=anyType
           {
             CATEGORY=Books; 
             CATEGORY_URL=books_chennai; 
             CATEGORY_ICON=http://deals.foo.com/common/images/books.png; 
             CATEGORY_COUNT=1045; 
             TYPE=1; 
             SUPERTAG=Books; 
           };
           CATEGORY_LIST=anyType
           {
               CATEGORY=Cameras;
               CATEGORY_URL=cameras_chennai;
               CATEGORY_ICON=http://deals.foo.com/common/images/cameras.png; 
               CATEGORY_COUNT=152; 
               SUPERTAG=Cameras; 
               TYPE=1; 
           }; 
       }; 
     }
    

    对于请求和解析,请这样做:

    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
               // Add the input required by web service
               request.addProperty("city","chennai");
               request.addProperty("key","10000");
    
               SoapSerializationEnvelope envelope =new SoapSerializationEnvelope(SoapEnvelope.VER11);
               envelope.setOutputSoapObject(request);
    
               // Make the soap call.
               androidHttpTransport.call(SOAP_ACTION, envelope);
    
               // Get the SoapResult from the envelope body.
               resultRequestSOAP = (SoapObject) envelope.bodyIn;
    
    
               System.out.println("********Response : "+resultRequestSOAP.toString());
    
               SoapObject root = (SoapObject) resultRequestSOAP.getProperty(0);
               SoapObject s_deals = (SoapObject) root.getProperty("FOO_DEALS");
    
               StringBuilder stringBuilder = new StringBuilder();
    
               System.out.println("********Count : "+ s_deals.getPropertyCount());
    
               for (int i = 0; i < s_deals.getPropertyCount(); i++) 
               {
                   Object property = s_deals.getProperty(i);
                   if (property instanceof SoapObject)
                   {
                       SoapObject category_list = (SoapObject) property;
                       String CATEGORY = category_list.getProperty("CATEGORY").toString();
                       String CATEGORY_URL = category_list.getProperty("CATEGORY_URL").toString();
                       String CATEGORY_ICON = category_list.getProperty("CATEGORY_ICON").toString();
                       String CATEGORY_COUNT = category_list.getProperty("CATEGORY_COUNT").toString();
                       String SUPERTAG = category_list.getProperty("SUPERTAG").toString();
                       String TYPE = category_list.getProperty("TYPE").toString();
                       stringBuilder.append
                       (
                            "Row value of: " +(i+1)+"\n"+
                            "Category: "+CATEGORY+"\n"+
                            "Category URL: "+CATEGORY_URL+"\n"+
                            "Category_Icon: "+CATEGORY_ICON+"\n"+
                            "Category_Count: "+CATEGORY_COUNT+"\n"+
                            "SuperTag: "+SUPERTAG+"\n"+
                            "Type: "+TYPE+"\n"+
                            "******************************"
                       );                   
                       stringBuilder.append("\n");
                   }
               }
    

    【讨论】:

      【解决方案4】:

      我不认识格式。我认为您将不得不自己解析响应,

      一系列正则表达式似乎是最快的开始。

      例如:

      String intput = ""; //your big response string
      List<Map<String,String>> rows = new ArrayList<Map<String,String>>();
      String[] rowdata = input.matches("DataRowValue\=\r\s*anyType{[^}]*};");
      
      
      for (String r : rowdata){
         Map<String, String> row = new HashMap<String, String>();
         String[] nvpairs = r.split(";");
      
         for (string pair : nvpairs) {
            String[] s = pair.split("=");
            row.push(s[0], s[1]);
         }
      
      }
      

      应该让你开始。 由于很多原因,您可能需要调整第一个正则表达式。 像 "(?)[^}]" 这样的东西可能更合适。 我很想访问任何只出现一次的东西,直接用类似

      的东西捞出来

      字符串用户名 = input.match("(?

      【讨论】:

        【解决方案5】:

        SoapObject 响应 = (SoapObject) 信封.getResponse();

                  int cols = response.getPropertyCount();
        
                    for (int i = 0; i < cols; i++) {
                        Object objectResponse = (Object) response.getProperty(i);
        
        
        
        
                        SoapObject r =(SoapObject) objectResponse;
        
                        FieldName=(String) r.getProperty("FieldName").toString();
        
                        // Get the rest of your Properties by 
                        // (String) r.getProperty("PropertyName").toString();
        
                    }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-01-28
          • 2011-02-05
          • 1970-01-01
          • 1970-01-01
          • 2017-07-04
          • 1970-01-01
          • 2011-10-13
          相关资源
          最近更新 更多