KSOAP名称空间和XML输出格式化请求

时间:2011-12-19 07:18:21

标签: xml soap android-ksoap2

我正在构建一个需要通过SOAP接口获取一些数据的Android应用程序。我正在尝试使用KSOAP2模块(使用kso​​ap2-android-2.6.0-jar-with-dependencies.jar)。 我无法让KSOAP在子元素中为我提供正确的名称空间前缀。

我想要这个:

<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header />
<v:Body>
<n0:GetRequest id="o0" c:root="1" xmlns:n0="http://dummy.com/nbi">
    <n0:Port i:type="d:string">Data</n0:Port>
</n0:GetRequest>
</v:Body></v:Envelope>

但是ksoap2给了我这个:

<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header />
<v:Body>
<n0:GetRequest id="o0" c:root="1" xmlns:n0="http://dummy.com/nbi">
    <Port i:type="d:string">Data</Port>
</n0:GetRequest>
</v:Body></v:Envelope>

唯一的区别是第二个XML请求中的Port元素在标记标签上没有n0前缀。

我一直在研究正确的命名空间xml理论,在我看来,格式良好的XML应该在所有相关元素上都有命名空间前缀,或者父元素应该有一个默认的命名空间定义。使用SoapUI我可以手动向我的服务器提交请求,并使其中任何一个选项工作,但我无法弄清楚如何使ksoap生成请求格式。即我无法弄清楚如何生成具有默认命名空间的元素或如何生成在每个子元素上具有命名空间前缀的元素。 我已经尝试了我能想到的各种设置变化,但我能想到的唯一(不优雅)解决方案是手动将前缀添加到Port标签。 有没有人制定出如何实现我想要的目标? 如果没有严格的XML格式化语法,我的SOAP服务器就不喜欢这个请求。

以下是相关的代码段:

private static final String namespace = "http://dummy.com/nbi";
private static final String URL = "http://192.168.254.117/soap/nbi";
String SOAP_ACTION = namespace + "/" + methodCall;
SoapObject request = new SoapObject(namespace, methodCall);
    PropertyInfo pi = new PropertyInfo();
pi.setName("myName");
pi.setValue("myString");
pi.setType(String.class);
    request.addProperty(pi);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = false;
envelope.setAddAdornments(false);       
envelope.implicitTypes = false;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.debug = true;

try
   {
    List<HeaderProperty> headerList = new ArrayList<HeaderProperty>();
    headerList.add(new HeaderProperty("Authorization", "Basic " + org.kobjects.base64.Base64.encode("nbsam:nbsam".getBytes())));
        androidHttpTransport.call(SOAP_ACTION, envelope, headerList);
        SoapObject response = (SoapObject)envelope.getResponse();
        String result = response.getProperty(0).toString();

    }

3 个答案:

答案 0 :(得分:2)

我在此期间解决了这个问题。 非常简单但我在搜索时没有看到其他的例子。 只需要在用于构造请求的setNamespace上使用PropertyInfo方法。像这样:

pi.setNamespace("http://example.com/nbi");

答案 1 :(得分:2)

如果只想从Property中删除命名空间,可以在创建PropertyInfo时设置空字符串。像这样:

PropertyInfo pi = new PropertyInfo();
pi.setNamespace("");
pi.setName("myName");
pi.setValue("myString");
pi.setType(String.class);

答案 2 :(得分:0)

您可以使用以下方案获取默认命名空间效果。

SoapObject request = new SoapObject(NAMESPACE, "GetRequest");
SoapObject data = new SoapObject("", "Port");
request.addSoapObject(data);

这应该给你类似的东西:

<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header />
<v:Body>
<GetRequest id="o0" c:root="1" xmlns:n0="http://dummy.com/nbi">
    <Port i:type="d:string">Data</Port>
</GetRequest>
</v:Body></v:Envelope>

你也可以在信封上做envelope.setAddAdornments(false)以获得更好的效果:

<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header />
<v:Body>
<GetRequest xmlns:n0="http://dummy.com/nbi">
    <Port i:type="d:string">Data</Port>
</GetRequest>
</v:Body></v:Envelope>