我正在尝试使用以下结构解组以下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.<ReturnIDs>c71cf425f5;e5e4dbb5ca</ReturnIDs></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>
元素之后
该特定标签包含一条消息,即“发送OK”。和一个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.<ReturnIDs>c71cf425f5;e5e4dbb5ca</ReturnIDs></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:}
我也尝试过Unesacpe的回复,然后尝试解组,部分工作,但这种方法有3个主要问题:
那么,如何提取消息的值(发送确定。)和<ReturnIDs>
?
答案 0 :(得分:0)
由于doSendResult
元素的内容似乎是“自定义”格式(与HTML,XML等格式良好的文档相对),正则表达式可能是解析结果在这里。
例如:
type SendResult struct {
Status string
ReturnIds []string
}
var doSendResultRegex = regexp.MustCompile("^Send (.*?)\\.<ReturnIDs>(.*?)</ReturnIDs>$")
func ParseSendResult(s string) *SendResult {
ss := doSendResultRegex.FindStringSubmatch(s)
if ss == nil {
return nil
}
return &SendResult{
Status: ss[1],
ReturnIds: strings.Split(ss[2], ";"),
}
}
// ...
fmt.Println("%#v\n", ParseSendResult(response.Result.RawMessage))
// &main.SendResult{
// Status: "OK",
// ReturnIds: []string{"c71cf425f5", "e5e4dbb5ca"}
// }
当然,您可能希望根据该数据的其他示例修改doSendResultRegex
表达式,但上面的代码应该说明这个想法。
答案 1 :(得分:0)
您可以通过多种方式解码doSendResult标记内容,但我做了一个示例:
我定义了两个与soap信封体内标签对应的类型:
type (
SendResponse struct {
SendResult SendResult `xml:"Body>doSendResponse>doSendResult"`
}
SendResult struct {
RawMessage string `xml:"-"`
Text string `xml:"-"`
IDS []string `xml:"-"`
}
)
类型SendResult
有一个自定义的unmarshal函数来读取原始消息并填充结构
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.<ReturnIDs>c71cf425f5;e5e4dbb5ca</ReturnIDs></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)
}