如何在Android中解析此Web服务响应?

时间:2009-08-13 05:35:12

标签: android

我正在使用KSOAP2从Android应用程序调用.NET Web服务,来自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{}; 
}

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

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

5 个答案:

答案 0 :(得分:7)

如果您了解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));
    } 
}

最初我在使用这种数据方面遇到了很多麻烦,但最后我把它全部搞定了。从那时起我一直在使用它。我希望这可以帮助你解决问题。

答案 1 :(得分:5)

前提是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;

}

答案 2 :(得分: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");
               }
           }

答案 3 :(得分:0)

我不认识这种格式。我想你将不得不自己解析反应,

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

例如:

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

}

应该让你入门。 出于很多原因,您可能需要调整第一个正则表达式。 像“(?&lt; = DataRowValue = [^ {] )[^}] ”这样的东西可能会更加合适。 我很想通过用

之类的东西直接捕获它来访问任何只出现过一次的东西

String username = input.match(“(?&lt; = UserName \ =)[^;] *”)

答案 4 :(得分:0)

SoapObject response =(SoapObject)envelope.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();

            }