我正在写一篇肥皂服务。 soap API的一部分用于返回查询结果,我希望提供用于解码信封的基本结构,同时允许开发人员填写encoding / xml将解码到的接口。
type QueryEnvelope struct {
XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"`
Body *QueryBody `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"`
}
type QueryBody struct {
QueryResult *QueryResult `xml:"queryResponse>result"`
}
type QueryResult struct {
Done bool `xml:"done"`
Size int `xml:"size"`
Records Record `xml:"records"`
}
type Record interface {
UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
}
是否可以为unmarhsalling注入这样的接口,或者我必须接受QueryEnvelope {}级别的接口吗?
理想情况下,客户方将这样做:
type Record struct {
Id int `xml:"id"`,
Name stirng `xml:"name"`
}
func (r *Record) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
// unmasrshal here, or best case I dont even need to implment UnmarsahlXML()!
}
res, err := Query("select id from table", Record{})
这意味着他们不必重现QueryEnvelope结构(作为使用我正在创建的包的开发人员)
答案 0 :(得分:1)
常见的解决方案是要求客户端传递指向其结构实例的指针,如下所示:
// The custom struct of your client
type ClientStruct struct {
Id int `xml:"id"`
Name string `xml:"name"`
}
// This would be your API
func Query(foo string, v interface{}) {
fakeXmlResult := "<test><id>012345</id><name>MyName</name></test>"
xml.Unmarshal([]byte(fakeXmlResult), v)
}
func main() {
r := ClientStruct{}
Query("SQL QUERY", &r) // Note the &
fmt.Println(r)
}
我是否正确理解了您的问题?
答案 1 :(得分:0)
所以你确实可以在中途注入一个接口,我失败了它为解码器分配内存工作:
包装:
type QueryEnvelope struct {
XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"`
Body *QueryBody `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"`
}
type QueryBody struct {
QueryResult *QueryResult `xml:"queryResponse>result"`
}
type QueryResult struct {
Done bool `xml:"done"`
Size int `xml:"size"`
Records interface{} `xml:"records"`
}
func (r *Resource) Query(sql string, r interface{}) error {
t := &QueryEnvelope{Body: &QueryBody{QueryResult: &QueryResult{Records: r}}}
//do query and unmarshal into t
return err
}
客户/主要:
type Record struct {
Id string `xml:"id"`
Name string `xml:"name"`
}
r := new([]*Record) // must allocate memory using new
err = ent.Query("select id, name from account limit 3", r)