首頁 >後端開發 >Golang >使用 Go 解組 SOAP 訊息

使用 Go 解組 SOAP 訊息

WBOY
WBOY轉載
2024-02-06 09:21:141227瀏覽

使用 Go 解组 SOAP 消息

問題內容

我對 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中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除