generalStore
generalStore

Reputation: 31

KSOAP namespaces and XML output formatting of request

I'm building an Android app that needs to get some data via a SOAP interface. I'm trying to use the KSOAP2 module (using ksoap2-android-2.6.0-jar-with-dependencies.jar). I'm having trouble with getting KSOAP to give me correct namespace prefixes in child elements.

I want this:

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

but ksoap2 gives me this:

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

The only difference being that the Port element in the 2nd XML request doesn't have the n0 prefix on the tag label.

I've been brushing up on proper namespace xml theory and it seems to me that well formed XML should either have the namespace prefix on all the relevant elements or the parent element should have a default namespace definition. Playing with SoapUI I can manually submit requests to my server and get either of those options to work, but I can't work out how to make ksoap produce either request format. i.e. I can't work out how to produce an element with a default namespace or how to produce an element that has the namespace prefix on every child element. I've tried every variation of settings I can think of but the only (inelegant) solution I can come up with is to manually add the prefix to the Port label. Has anyone worked out how to do achieve what I want? My SOAP server doesn't like the request without the strict XML formatting syntax.

Here's the relevant code snippet:

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();

    }

Upvotes: 1

Views: 5269

Answers (3)

EdoB
EdoB

Reputation: 91

If you want to remove the namespace only from the Property you can set an empty string when create the PropertyInfo. Like This:

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

Upvotes: 2

Saad Farooq
Saad Farooq

Reputation: 13402

You can get the default namespace effect using the following scheme.

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

This should give you something like:

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

You can also do envelope.setAddAdornments(false) on the Envelope to get an even nicer:

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

Upvotes: 0

generalStore
generalStore

Reputation: 31

I worked this out in the meantime. Quite simple really but I didn't see other examples of this when searching about. Just need to use the setNamespace method on the PropertyInfo used to construct the request. Like this:

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

Upvotes: 2

Related Questions