1

要处理一个 xml API 响应结果,需要捕获多个案例。对于成功案例和失败案例,我可以定义 2 个结构来处理它们。来源为:去操场

如果响应数据有很多结果,并且它们没有相同的xml结构,我们可以在go中定义所有的struct类型。但是有没有一种简单的方法来捕获它的数据?

我发现 go 的 xmlUnmarshalXML方法可以重写 xml 数据。打包 xml 但使用它需要先设置为特殊且唯一的结构:

func (r *PostSuccessResponse) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {

    return nil
}

是否可以使用startElement.Name.Local遍历所有响应 xml 数据来检查它有什么元素,然后使用哪个 go struct 来处理?比如如果找到Fault则使用PostFailureResponsestruct,如果找到return则使用PostSuccessResponsestruct。

4

1 回答 1

1

根据评论的建议,我重新创建了您的代码,如下所示:

package main

import (
    "encoding/xml"
    "fmt"
)

type PostSuccessResponse struct {
    PostID     string `xml:"return>postResult>postId"`
    PostNumber string `xml:"return>postNumber"`
}

type PostFailureResponse struct {
    Code    string `xml:"detail>faultDetails>code"`
    Details string `xml:"detail>faultDetails>details"`
}

type Response struct {
    PostSuccessResponse *PostSuccessResponse `xml:"Body>postResponse"`
    PostFailureResponse *PostFailureResponse `xml:"Body>Fault"`
}

func main() {
    var response1 = &Response{}
    if err := xml.Unmarshal([]byte(successPayload), response1); err != nil {
        panic(err)
    }
    fmt.Printf("success=%+v failure=%+v\n", response1.PostSuccessResponse, response1.PostFailureResponse)

    var response2 = &Response{}
    if err := xml.Unmarshal([]byte(failurePayload), response2); err != nil {
        panic(err)
    }
    fmt.Printf("success=%+v failure=%+v\n", response2.PostSuccessResponse, response2.PostFailureResponse)
}

var successPayload = []byte(`
    <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
       <env:Header/>
       <env:Body>
          <ns2:postResponse xmlns:ns2="http://example.com/">
             <return>
                <postDetails>
                    <title>P</title>
                    <body>A</body>
                </postDetails>
                <postResult>
                   <postId>1234</postId>
                </postResult>
                <postNumber>1000000</postNumber>
             </return>
          </ns2:postResponse>
       </env:Body>
    </env:Envelope>
`)

var failurePayload = []byte(`
    <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
       <env:Header/>
       <env:Body>
          <env:Fault>
             <faultcode>env:Server</faultcode>
             <faultstring>An unexpected problem occurred</faultstring>
             <detail>
                <ns2:faultDetails xmlns:ns2="http://example.com/">
                   <code>Unexpected error</code>
                   <details>The post content is not right.</details>
                </ns2:faultDetails>
             </detail>
          </env:Fault>
       </env:Body>
    </env:Envelope>
`)

输出:

success=&{PostID:1234 PostNumber:1000000} failure=<nil>
success=<nil> failure=&{Code:Unexpected error Details:The post content is not right.}
于 2021-06-11T15:10:07.037 回答