dty3416 2014-08-22 14:59
浏览 20
已采纳

接口和encoding / xml解组

I have a soap service I'm writing against. One portion of the soap API is for returning a query result, and I'm hoping to provide the base structs for decoding the envelope, while allow a developer to fill in the interface in which encoding/xml will decode to.

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
}

Is it possible to inject an interface like this for unmarhsalling or do I have to accept the interface at the QueryEnvelope{} level?

Ideally client side would act as such:

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{})

This would mean that they don't have to reproduce the QueryEnvelope struct (as a developer using the package I'm creating)

  • 写回答

2条回答 默认 最新

  • duanna2026 2014-08-25 14:16
    关注

    So you can indeed inject an interface partway through, I was failing it allocate memory for the decoder to work:

    Package:

    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
    }
    

    Client / main:

    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)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大