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条)

报告相同问题?

悬赏问题

  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)
  • ¥15 AIC3204的示例代码有吗,想用AIC3204测量血氧,找不到相关的代码。