xml - 在 go 中解码特定的 SOAP 响应

标签 xml go soap unmarshalling

我正在尝试使用以下结构解码以下 SOAP 响应。

var data = `<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3rg/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <doSendResponse>
            <doSendResult>Send OK.&lt;ReturnIDs&gt;c71cf425f5;e5e4dbb5ca&lt;/ReturnIDs&gt;</doSendResult>
        </doSendResponse>
    </soap:Body>
</soap:Envelope>`

type ResponseBody struct {
    ResponseBody SendResponse `xml:"Body"`
}
type SendResponse struct {
    Result Result `xml:"doSendResponse"`
}
type Result struct {
    RawMessage string `xml:"doSendResult"`
}

一切顺利,直到 <doSendResult> 之后元素。
这个特定的标签包含一条消息,即“发送成功”。和一个 HTML 编码的 <ReturnIDs>元素,问题不在于 HTML 编码部分,我已经看到了 this question and the accepted answer. 我的问题是我无法同时提取消息和返回 ID。

我尝试使用前面提到的问题中建议的方法,但我失败了,Here是我到目前为止尝试过的。

package main

import (
    "encoding/xml"
    "fmt"
)

var data = `<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3rg/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <doSendResponse>
            <doSendResult>Send OK.&lt;ReturnIDs&gt;c71cf425f5;e5e4dbb5ca&lt;/ReturnIDs&gt;</doSendResult>
        </doSendResponse>
    </soap:Body>
</soap:Envelope>`

type ResponseBody struct {
    ResponseBody SendResponse `xml:"Body"`
}
type SendResponse struct {
    Result Result `xml:"doSendResponse"`
}
type Result struct {
    RawMessage string `xml:"doSendResult"`
}
type RawMessage struct {
    IDs     string `xml:"ReturnIDs"`
}

func main() {
    var response ResponseBody
    err := xml.Unmarshal([]byte(data), &response)
    if err != nil {
        panic(err.Error())
    }
    fmt.Printf("%+v\n", response)

    var rawMessage RawMessage
    err = xml.Unmarshal([]byte(response.ResponseBody.Result.RawMessage), &rawMessage)
    if err != nil {
        panic(err.Error())
    }
    fmt.Printf("%+v\n", rawMessage)

}

输出:
{ResponseBody:{Result:{RawMessage:Send OK.<ReturnIDs>c71cf425f5;e5e4dbb5ca</ReturnIDs>}}} {IDs:} 我还尝试取消响应,然后尝试解码它,它部分有效,但这种方法存在 3 个主要问题:

  1. 太慢了
  2. 我只能get the ReturnIDsthe message ,而不是两者。
  3. 我相信这只是一个丑陋的 hack,必须有更好的方法来做到这一点(我还不知道。)

那么,我如何提取消息的值(发送成功。)和 <ReturnIDs>

最佳答案

doSendResult标签内容可以通过多种方式解码,我举了一个例子:

play.golang.org/p/NC9YrWqK0k

我定义了两种类型对应于 SOAP 信封主体内的标签:

type (
    SendResponse struct {
        SendResult SendResult `xml:"Body>doSendResponse>doSendResult"`
    }

    SendResult struct {
        RawMessage string   `xml:"-"`
        Text       string   `xml:"-"`
        IDS        []string `xml:"-"`
    }
)

SendResult 类型有一个自定义解码函数来读取原始消息并填充结构

func (sr *SendResult) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    var raw string
    d.DecodeElement(&raw, &start)

    var st struct {
        Contents  string `xml:",chardata"`
        ReturnIDs string `xml:"ReturnIDs"`
    }

    err := xml.Unmarshal([]byte("<xml>"+raw+"</xml>"), &st)
    if err != nil {
        panic(err.Error())
    }

    sr.RawMessage = raw
    sr.Text = st.Contents
    sr.IDS = strings.Split(st.ReturnIDs, ";")

    return nil
}

这是使用方法:

const data = `<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3rg/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <doSendResponse>
            <doSendResult>Send OK.&lt;ReturnIDs&gt;c71cf425f5;e5e4dbb5ca&lt;/ReturnIDs&gt;</doSendResult>
        </doSendResponse>
    </soap:Body>
</soap:Envelope>`

func main() {
    var sendResponse SendResponse

    err := xml.Unmarshal([]byte(data), &sendResponse)
    if err != nil {
        panic(err.Error())
    }

    fmt.Printf("%+v\n", sendResponse)
}

关于xml - 在 go 中解码特定的 SOAP 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47791873/

相关文章:

php - 带命名空间的 xpath

java - XML解析错误: junk after document element - REST

go - Swagger参数问题

go - 使用 Go-Stomp 为 ActiveMQ 缓存连接

Python suds - 服务中未定义方法

java - 带有字符 ^ 的 SOAP MalformedURLException

Java SoapMessage 添加空命名空间

xml - android View 中经常出现的问题,解析XML时出错: unbound prefix

json - Golang - 无法将数字解码为字符串类型的 Go 值

python - 如何使用 Python 通过 Microsoft Exchange Web 服务 API 发送电子邮件