zoukankan      html  css  js  c++  java
  • 【Golang 接口自动化03】 解析接口返回XML

    上一篇我们学习了怎么发送各种数据类型的http请求,这一篇我们来介绍怎么来解析接口返回的XML的数据。

    解析接口返回数据

    定义结构体

    假设我们现在有一个接口返回的数据resp如下:

    <?xml version="1.0" encoding="utf-8"?>
    <ResponseWithResponseInfo>
      <code>00</code>
      <message>SUCCESS</message>
      <describe>成功</describe>
      <resultInfo>
        <uniqueNumber>201808161133401673324075025000035</uniqueNumber>
      </resultInfo>
    </ResponseWithResponseInfo>
    

    要解析这个数据,首先我们要定义一个与之树状结构一致的结构体:

    type XMLresp struct {
    	ResponseWithResponseInfo xml.Name `xml:"ResponseWithResponseInfo"`
    	Code                        int      `xml:"code"`
    	Message                     string   `xml:"message"`
    	Describe                    string   `xml:"describe"`
    	ResultInfo                  struct {
    		XMLName      xml.Name `xml:"resultInfo"`
    		UniqueNumber string   `xml:"uniqueNumber"`
    	}
    }
    

    这里要注意xml.Name 这个tag,它表示后面的数据的父元素是什么,如果没有填写这个信息,在数据解析的时候可能会获取不到数据。

    解析函数:

    接下来我们就可以使用xml.Unmarshal方法将字符串中的数据解析出来了:

    // XMLUnpack xml数据解析
    func XMLUnpack(respbody string) (Prase []interface{}, errs error) {
    	temp := []byte(respbody)
    	v := XMLresp{}
    	errs = xml.Unmarshal(temp, &v)
    	Prase = []interface{}{v.Code, v.Message, v.Describe, v.ResultInfo.UniqueNumber}
    	if errs != nil {
    		return
    	}
    	return
    }
    

    测试

    func main() {
    	data, _ := XMLUnpack(resp)
    	fmt.Println(data)
    }
    

    输出:

    bingo@Mac unpackData$ go run paraseXML.go
    [0 SUCCESS 成功 201808161133401673324075025000035]
    

    优化

    大家可能注意到了,我们在定义XMLUnpack这个函数的时候用于解析这个数据的结构体是固定的,也就是说这个函数只能解析同一个树桩结构的数据,每一个不同的接口我们都需要写一个与之对应的函数。这样我们可能会在后续面临一个问题,如果我们的接口多了,取怎样的函数名可能都会是困扰我们的一个大问题,而且会变得越来越不容易维护。

    那么有没有办法能解决这个问题呢,答案当然是有的,下面我们一起来解决这个问题。
    
    不知道大家还记不记得我么之前一起学习过的method语法,它的优点是可以让不同作用的函数使用同一个函数名称(属性),可以完成面向对象语言特有的继承和重写操作,如果忘记了可以看看之前的学习笔记【Golang】基础09 通过method完成面向对象

    我们这次的优化其实就是method语法的一次实际应用,下面让我们来看一下具体的实现。

    // XMLUnpack 短信网关xml返回结果解析
    func (smsresp *XMLresp) XMLUnpack(respbody string) (Prase []interface{}, errs error) {
    	temp := []byte(respbody)
    	v := SmsXMLresp{}
    	errs = xml.Unmarshal(temp, &v)
    	Prase = []interface{}{v.Code, v.Message, v.Describe, v.ResultInfo.UniqueNumber}
    	if errs != nil {
    		return
    	}
    	return
    }
    

    现在的这个函数和之前的区别就在于我们指定了可以调用这个函数的数据类型为*XMLresp,只有这个类型的数据能够调用这个方法,同样的我们的调用方法也发生了一些小改变:我们需要先定义一个存储这个结构体的变量,然后再调用这个变量的方法,当然,这个变量在后续解析其他相同类型的数据时是可以无限次复用的。参考代码:

    func main() {
    	var p XMLresp
    	data, _ := p.XMLUnpack(resp)
    	fmt.Println(data)
    }
    
  • 相关阅读:
    使用自定义注解动态绑定多实现类实例
    使用策略模式和工厂模式动态绑定多实现类实例
    使用责任链模式动态绑定多实现类实例
    使用模板方法模式动态绑定多实现类实例
    IDEA 调试Java代码的两个技巧
    Maven中dependencyManagement标签的正确使用方法
    Spring注解之获取自定义注解信息
    Spring注解之自定义注解入门
    Spring 动态绑定多实现类实例综述
    数据迁移测试
  • 原文地址:https://www.cnblogs.com/Detector/p/9638053.html
Copyright © 2011-2022 走看看