在 Go 中解组 SOAP 响应

Sam*_*Sam 6 soap go unmarshalling

我正在对 API 进行 SOAP 调用,这是一个示例响应:

<?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>
Run Code Online (Sandbox Code Playgroud)

为了解组这个响应,我构建了一些结构:

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"`
}
Run Code Online (Sandbox Code Playgroud)

这是执行解组部分的代码:

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

问题是所有soapResponse属性都填充得恰到好处,除了soapResponse.Body.Fault.Detail.ServiceException.ID不打印任何内容。
我想不通为什么。任何帮助,将不胜感激。

Eug*_*sky 3

你可以用这样的结构解析得到的 XML:

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"`
}
Run Code Online (Sandbox Code Playgroud)

我为第一个元素添加了命名空间并修复了一些定义。工作示例 - https://play.golang.org/p/vZQhaxYikX