【问题标题】:Weird SOAP response, is it JSON? How to parse it?奇怪的 SOAP 响应,是 JSON 吗?如何解析它?
【发布时间】:2014-06-17 16:26:58
【问题描述】:

我正在使用ksoap2 来使用基于SOAPweb-service,而我得到的响应格式类似于:

anyType{
    key1=value1;
    key2=value2;

    key3=anyType{

        key4=value4;
        key5=value5;
        key6= anyType{
                key7= anyType{
                    key8= value8;
                };
            };

    };

    key9=value9;
}

JSON objects(如果我们假设这是JSON)以anyType{开头并以}结尾,键和值之间用=分隔,;是字段分隔符/语句终止符/其他。

我尝试使用online validators 验证响应字符串,但失败了。这指出这不是一个有效的JSON object

类似的例子可以在in this question找到。但是 accepted answer 对我不起作用,因为首先响应字符串不是以{ 开头,而是以anyType{ 开头,如果我将anyType{ 放在if 条件中,下次遇到anyType{ (a nested JSON object) 时仍然会引发异常

第二个答案似乎在某种程度上有效,但问题是我的整个响应字符串似乎是作为一个属性出现的(因为 propertyCount 是 1),所以当我打印出属性的名称或值,则打印整个响应字符串。

我用谷歌搜索了很多,并尝试了我能找到的一切。所以我想我必须自己解析它。

我的问题是解析这种响应的最佳方式是什么。

我是否应该尝试使用regex 解析它我应该通过将所有出现的anyType{ 替换为{、@987654344 来将响应字符串转换为JSON format @ by :, ; by , etc. etc. ,然后通过以下方式将此字符串转换为 JSONObject:

jsonObject= new JSONObject(responseString);

然后通过以下方式提取键和值:

Iterator itr= jsonObject.keys();

        while(itr.hasNext()) {
            String value = null; 

            String key= (String) itr.next();
            try {
                value= jsonObject.getString(key);
            } catch (JSONException e) {
                e.printStackTrace();
            }

            Log.i(TAG, key + " : " + value); 

            // ......
        }

   import java.util.Iterator;

import org.json.JSONException;
import org.json.JSONObject;

public class JSONPracticeOne {

    private static JSONObject jsonObject;

    private static String key;
    private static String value;

    public static void main(String[] args) {

        String responseString= " anyType{key1=value1;key2=value2;key3=anyType{key4=value4;key5=value5;key6=anyType{key7=anyType{key8=value8};};};key9=value9;}";

        responseString = responseString.replaceAll("anyType\\Q{\\E", "{");

        responseString = responseString.replaceAll("\\Q=\\E", ":");

        responseString = responseString.replaceAll(";", ",");

        responseString = responseString.replaceAll(",\\Q}\\E","}");

        //System.out.println(responseString); 

        //System.out.println();

        responseString= responseString.replaceAll("(:\\{)", "-"); //Replace :{ by -
        responseString= responseString.replaceAll("[:]", "\":\""); //Replace : by ":"
        responseString= responseString.replaceAll("-", "\":{\""); //Replace - back to :{

        //System.out.println(responseString);

        //System.out.println();

        responseString = responseString.replaceAll("[,]",",\"");

        //System.out.println(responseString); 

        //System.out.println();

        //String string= responseString.charAt(1) + "";  System.out.println("CHECHE " + string); 

        responseString = responseString.replaceFirst("[\\{]","{\"");

        //System.out.println(responseString);

        //System.out.println(); 

        //responseString= responseString.replaceAll("([^\\}],)","\","); // truncation

        responseString= responseString.replaceAll("(\\},)", "-"); // replace }, by -

        responseString= responseString.replaceAll(",","\","); //replace , by ",

        responseString = responseString.replaceAll("-","},"); // replace - back to },

        //System.out.println(responseString);

        //System.out.println();

        responseString = responseString.replaceAll("(?<![\\}])\\}","\"}");

        System.out.println(responseString);

        System.out.println("**********************************************************************************************\n\n");}}

输出:-

{
    "key1":"value1",
    "key2":"value2",
    "key3":{
        "key5":"value5",
        "key6":{
            "key7":{
                "key8":"value8"
            }
        },
        "key4":"value4"
    },
    "key9":"value9"
}

【问题讨论】:

  • 我不知道有人说什么,但你得到的不是 json
  • @IllegalArgument 谢谢,经过一番辛劳,我得出了同样的结论,但是问题(在问题中显示为粗体)仍然是解析它的最佳方法吗?
  • 发布您的整个响应解析代码都依赖于它我假设最终代码将导致类似字符串操作的结果
  • 实际上我确实尝试过类似的事情并发布在问题中。我仍然需要将键和值包含在" 中;但是像这样操作响应字符串似乎不是一种有效的方法。必须有更好的方法来处理 ti。
  • 你能说出你想解析出什么吗?忽略7和6,key8够不够?

标签: android regex json soap ksoap2


【解决方案1】:

响应不是 JSON,它是类似 JSON 的对象,您可以使用 ksoap2 的功能对其进行解析。

SoapObject.java中,有一些方法如下:

 public Object getProperty(int index) {
        Object prop = properties.elementAt(index);
        if(prop instanceof PropertyInfo) {
            return ((PropertyInfo)prop).getValue();
        } else {
            return ((SoapObject)prop);
        }
    }

 /**
* Get the toString value of the property.
*
* @param index
* @return
*/
    public String getPropertyAsString(int index) {
        PropertyInfo propertyInfo = (PropertyInfo) properties.elementAt(index);
        return propertyInfo.getValue().toString();
    }

/**
* Get the property with the given name
*
* @throws java.lang.RuntimeException
* if the property does not exist
*/
    public Object getProperty(String name) {
        Integer index = propertyIndex(name);
        if (index != null) {
            return getProperty(index.intValue());
        } else {
            throw new RuntimeException("illegal property: " + name);
        }
    }

/**
* Get the toString value of the property.
*
* @param name
* @return
*/

    public String getPropertyAsString(String name) {
        Integer index = propertyIndex(name);
        if (index != null) {
            return getProperty(index.intValue()).toString();
        } else {
            throw new RuntimeException("illegal property: " + name);
        }
    }

等等。

您可以尝试像这样解析您的对象:

try {
            androidHttpTransport.call(SOAP_ACTION, envelope);
            SoapObject response = (SoapObject) envelope.getResponse();

            if (response.toString().equals("anyType{}") || response == null) {
                return;
            } else {
                String value1 = response.getPropertyAsString("key1");
                String value2 = response.getPropertyAsString("key2");

                SoapObject soapKey3 = (SoapObject) response.getProperty("key3");
                String value4 = soapKey3.getPropertyAsString("key4");
                String value5 = soapKey3.getPropertyAsString("key5");

                SoapObject soapKey6 = (SoapObject) soapKey3.getProperty("key6");
                SoapObject soapKey7 = (SoapObject) soapKey6.getProperty("key7");

                String value8 = soapKey7.getPropertyAsString("key8");

                String value9 = response.getPropertyAsString("key9");

                System.out.println(value1 + ", " + value2 + ", " + value4 + ", " + value5 + ", " + value8 + ", " + value9);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

【讨论】:

  • 很好,你打败了我。
  • 您的解决方案非常简单易用,老实说,我更倾向于使用它,但尝试使用它会带来Runtime Exception: illegal Property'; and looking at the SoapObject class, I found that the index of the property appears to be null`跨度>
【解决方案2】:

试试这个,我认为它会工作

          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;

             String   key1=(String) r.getProperty("key1").toString();

                // Get the rest of your Properties by 
                // (String) r.getProperty("PropertyName").toString();

            }

【讨论】:

    【解决方案3】:
    1. 将您的响应字符串转换为肥皂对象。
    2. 对soap 对象进行属性计数并迭代计数。
    3. 对于每个属性,转换为 Object 并检查 Object 是否属于 Soap 类。如果 Object 是 soap 类类型,则转换为 Soap Object 并从第 2 步重做,否则将属性检索为字符串值。

      SoapObject result=(SoapObject)responseString;
      if (result.getPropertyCount() > 0){
          Object obj = result.getProperty(0);
          if (obj!=null && obj.getClass().equals(SoapObject.class)){
              SoapObject j = (SoapObject)obj;
          }
      }   
      
      for (int i = 0; i < j.getPropertyCount(); i++) {
          Object obj0 = j.getProperty(i);                     
          if (obj0!=null && obj0.getClass().equals(SoapObject.class)){
              SoapObject j0 =(SoapObject) j.getProperty(i);
              for (int i0 = 0; i0 < j0.getPropertyCount(); i0++) {
                  Object obj1 = j0.getProperty(i0);
                  if (obj1!=null && obj1.getClass().equals(SoapObject.class)){
                      SoapObject j1 =(SoapObject) j0.getProperty(i0);
                      //TODO retrieve the properties for this soap object
                  }else{
                      // retrieve soap property as string
                      String keyValue = obj1.toString()
                  }   
              }
          }else{
              // retrieve soap property as string
              String keyValue0 = obj0.toString();
          }
      }
      

    【讨论】:

    • 非常感谢。虽然由于我是新手,所以花了一些时间才完全理解它,但这很棒;除了有一个问题。在我想要制作的应用程序中,来自 Web 服务的响应(取决于用户要求的内容)会有不同的嵌套级别。例如,在您的代码中,您在另一个中嵌套了一个 for 循环,在我的代码中,我调整了您的代码以测试真实的 Web 服务响应,我使用了一个嵌套在另一个中的属性,嵌套在另一个中,在另一个中,在另一个中,在另一个中(那是5次嵌套)......那
    • ...这是基于一个soap请求的一种响应。现在,用户将有不同的选项来选择他们想要请求 Web 服务的内容。在请求的基础上,响应将具有不同的属性,因此我们无法预测属性将嵌套在其他属性中的程度。如果你能给我一些建议,我将不胜感激。再次感谢您的回答。
    • @Zarah:不幸的是,由于 KSOAP 不消耗 wsdl 本身;您必须非常了解 Web 服务及其响应。你已经经历过的事情;因此提供的代码是为了帮助理解。您可以查看代码生成器 www.wsdl2code.com;尽管根据我的经验,为映射 Web 服务响应而生成的类在我的情况下被错误地映射。
    • 用于验证属性是否为soap类类型的代码,有助于确定迭代时的嵌套级别。
    猜你喜欢
    • 2019-09-15
    • 1970-01-01
    • 2015-09-10
    • 2012-01-09
    • 1970-01-01
    • 2012-07-14
    • 1970-01-01
    • 2020-04-22
    相关资源
    最近更新 更多