Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unmarshaling a SOAP response in Go

I am making a SOAP call to an API, Here is a sample response:

<?xml version="1.0" encoding="utf-8" ?>
 <soapenv:envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:body>
      <soapenv:fault>
        <faultcode>
          ERR109
        </faultcode>
        <faultstring>
          Account Expired. Result code is 2163
        </faultstring>
        <detail>
          <ns1:serviceexception xmlns:ns1="http://www.csapi.org/schema/parlayx/common/v2_1">
            <messageid>
              ERR109
            </messageid>
            <text>
              Account Expired. Result code is 2163
            </text>
            <variables>
              2163
            </variables>
          </ns1:serviceexception>
        </detail>
      </soapenv:fault>
    </soapenv:body>
  </soapenv:envelope>

To unmarshal this response, I have built some structs:

type SoapResponse struct {
    Body    ResponseBody `soapenv:"body"`
}
type ResponseBody struct {
    Fault   Fault    `soapenv:"fault"`
}
type Fault struct {
    FaultCode   string `xml:"faultcode"`
    FaultString string `xml:"faultstring"`
    Detail      Detail `xml:"detail"`
}
type Detail struct {
    ServiceException ServiceException `ns1:"serviceexception"`
}
type ServiceException struct {
    ID          string `xml:"messageid"` 
    MessageText string `xml:"text"`
    ErrorCode   string `xml:"variables"`
}

And here is the code that does the unmarshaling part:

responseBody, _:= ioutil.ReadAll(resp.Body)
var soapResponse = new(SoapResponse)
err := xml.Unmarshal(responseBody, soapResponse)
    if err != nil {
        panic("Error!")
    }

The problem is that all soapResponse properties are populated just right, except for soapResponse.Body.Fault.Detail.ServiceException.ID which prints nothing.
I couldn't figure out why. Any help would be appreciated.

like image 912
Sam Avatar asked Oct 05 '17 18:10

Sam


People also ask

What do you think about unmarshalling JSON?

Unmarshalling JSon is a more common tasking as XML seems to have lost some of its luster of late if it ever really had any. I was never a fan of XML so when most of the new work seemed to shift toward Json I was pretty much all for it.

What is JSON marshalling and unmarshalling in Golang?

But, Unmarshalling is a reverse process of marshalling, which means the given json string or file will be converted to the desired object (type). In order to perform the json marshalling and unmarshalling in golang, first of all, you need a model (i.e. type) in golang.

What is an example of a SOAP message?

A typical example of a simple SOAP message is the following: Hello, World! This message content weights 285 bytes, which might not seem a lot, but a similar payload in JSON would be 25 bytes and in Protocol Buffers 14 bytes.

What is marshalling and unmarshalling?

This tutorial has step by step approach and the example program, which has been tested and shared in the same post. What is Marshalling and Unmarshalling? The marshalling is a process of converting an object (type) into a JSON string or file.


1 Answers

You may parse got XML with such structures:

type SoapResponse struct {
    Body ResponseBody `xml:"soapenv body"`
}
type ResponseBody struct {
    Fault Fault `xml:"fault"`
}
type Fault struct {
    FaultCode   string `xml:"faultcode"`
    FaultString string `xml:"faultstring"`
    Detail      Detail `xml:"detail"`
}
type Detail struct {
    ServiceException ServiceException `xml:"serviceexception"`
}
type ServiceException struct {
    ID          string `xml:"messageid"`
    MessageText string `xml:"text"`
    ErrorCode   string `xml:"variables"`
}

I've added namespace for the first element and fixed some definitions. Working example - https://play.golang.org/p/vZQhaxYikX

like image 138
Eugene Lisitsky Avatar answered Oct 08 '22 10:10

Eugene Lisitsky