我对 go 语言还比较陌生。
我在尝试解组 soap 消息时遇到问题。我的尝试是抽象 body 元素的内容并避免静态定义 xml 结构,因为它会根据请求的操作而变化。 不幸的是我找不到正确的方法。在示例中,getcontent 函数应接收指向包含内容的结构的指针,并将其动态添加到 body 中,以便进行填充。但结果并不是预期的。
package main import ( "encoding/xml" "fmt" ) type Message interface{} type EnvelopeResponse struct { XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` Body Message `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` } type Body struct { XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` Fault *Fault `xml:",omitempty"` Content Message `xml:",omitempty"` SOAPBodyContentType string `xml:"-"` } type Fault struct { XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault"` Code string `xml:"faultcode,omitempty"` String string `xml:"faultstring,omitempty"` Actor string `xml:"faultactor,omitempty"` Detail string `xml:"detail,omitempty"` } type GetHostNumberOfEntriesResponse struct { XMLName xml.Name `xml:"urn:dslforum-org:service:Hosts:1 GetHostNumberOfEntriesResponse"` NewHostNumberOfEntries int64 `xml:"NewHostNumberOfEntries"` } func GetContent(rawXml []byte, content interface{}) { envelope := EnvelopeResponse{Body: Body{Content: content}} xml.Unmarshal(rawXml, &envelope) } func main() { b := []byte(` <?xml version="1.0"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <s:Body> <u:GetHostNumberOfEntriesResponse xmlns:u="urn:dslforum-org:service:Hosts:1"> <NewHostNumberOfEntries>47</NewHostNumberOfEntries> </u:GetHostNumberOfEntriesResponse> </s:Body> </s:Envelope> `) content := &GetHostNumberOfEntriesResponse{} GetContent(b, content) fmt.Println(*content) }
这是操场上的示例:
https://go.dev/play/p/bbr4vexipbc
我找到的解决方案是使用泛型来表示主体的变量和参数化内容。
此代码按我的预期工作:
package main import ( "encoding/xml" "fmt" ) type EnvelopeResponse[T any] struct { XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` Body Body[T] `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` } type Body[T any] struct { XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` Fault *Fault `xml:",omitempty"` Content T `xml:",omitempty"` SOAPBodyContentType string `xml:"-"` } type Fault struct { XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault"` Code string `xml:"faultcode,omitempty"` String string `xml:"faultstring,omitempty"` Actor string `xml:"faultactor,omitempty"` Detail string `xml:"detail,omitempty"` } type GetHostNumberOfEntriesResponse struct { XMLName xml.Name `xml:"urn:dslforum-org:service:Hosts:1 GetHostNumberOfEntriesResponse"` NewHostNumberOfEntries int64 `xml:"NewHostNumberOfEntries"` } func GetContent[T any](rawXml []byte, content T) { envelope := EnvelopeResponse[T]{Body: Body[T]{Content: content}} xml.Unmarshal(rawXml, &envelope) } func main() { b := []byte(` <?xml version="1.0"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <s:Body> <u:GetHostNumberOfEntriesResponse xmlns:u="urn:dslforum-org:service:Hosts:1"> <NewHostNumberOfEntries>47</NewHostNumberOfEntries> </u:GetHostNumberOfEntriesResponse> </s:Body> </s:Envelope> `) content := &GetHostNumberOfEntriesResponse{} GetContent(b, content) fmt.Println(*content) }
以上是使用 Go 解组 SOAP 消息的详细内容。更多信息请关注PHP中文网其他相关文章!