完成部分xml格式解析方法
This commit is contained in:
parent
249e749e6c
commit
fe2cdb4f21
30
parser.go
30
parser.go
@ -9,6 +9,7 @@ package simpleRequest
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
@ -17,9 +18,11 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 通用类型解析器
|
||||
var bodyEntryParsers = map[string]IBodyEntryParser{
|
||||
jsonContentType: new(JsonParser),
|
||||
formDataType: new(FormDataParser),
|
||||
xmlDataType: new(XmlParser),
|
||||
}
|
||||
|
||||
type IBodyEntryParser interface {
|
||||
@ -138,3 +141,30 @@ func multipartCommonParse(BodyEntry map[string]any) (reader io.Reader, contentTy
|
||||
}
|
||||
return body, formWriter.FormDataContentType()
|
||||
}
|
||||
|
||||
type XmlParser struct{}
|
||||
|
||||
func (f XmlParser) Unmarshal(bodyType EntryMark, BodyEntry map[string]any) (body io.Reader) {
|
||||
switch bodyType {
|
||||
case MapEntryType:
|
||||
xmlData, err := xml.Marshal(BodyEntry[bodyType.string()])
|
||||
if err == nil {
|
||||
return bytes.NewReader(xmlData)
|
||||
} else {
|
||||
return strings.NewReader("")
|
||||
}
|
||||
case ModelEntryType:
|
||||
xmlData, err := xml.Marshal(BodyEntry[bodyType.string()])
|
||||
if err == nil {
|
||||
return bytes.NewReader(xmlData)
|
||||
} else {
|
||||
return strings.NewReader("")
|
||||
}
|
||||
case StringEntryType:
|
||||
return strings.NewReader(BodyEntry[StringEntryType.string()].(string))
|
||||
case BytesEntryType:
|
||||
return bytes.NewReader(BodyEntry[BytesEntryType.string()].([]byte))
|
||||
default:
|
||||
return strings.NewReader("")
|
||||
}
|
||||
}
|
||||
|
@ -251,6 +251,7 @@ func (s *SimpleRequest) TRACE(url string) (body []byte, err error) {
|
||||
// 这里数据
|
||||
func (s *SimpleRequest) initBody() {
|
||||
contentTypeData := s.headers.Get(hdrContentTypeKey)
|
||||
if contentTypeData != "" {
|
||||
switch {
|
||||
case IsJSONType(contentTypeData):
|
||||
var parser, ok = s.bodyEntryParsers[jsonContentType]
|
||||
@ -287,10 +288,7 @@ func (s *SimpleRequest) initBody() {
|
||||
}
|
||||
s.body = parser.Unmarshal(s.BodyEntryMark, s.BodyEntries)
|
||||
|
||||
case contentTypeData == "" && s.BodyEntryMark == BytesEntryType:
|
||||
s.body = bytes.NewReader(s.BodyEntries[BytesEntryType.string()].([]byte))
|
||||
|
||||
case contentTypeData == "" || strings.Contains(contentTypeData, "form-urlencoded"):
|
||||
case strings.Contains(contentTypeData, "form-urlencoded"):
|
||||
//default header type is "x-www-form-urlencoded"
|
||||
var parser, ok = s.bodyEntryParsers["form-urlencoded"]
|
||||
if !ok {
|
||||
@ -307,8 +305,36 @@ func (s *SimpleRequest) initBody() {
|
||||
//todo Automatically determine the data type
|
||||
tmpData := url.Values{}
|
||||
for k, v := range tmpData {
|
||||
if strings.HasPrefix(k, FormFilePathKey.string()) {
|
||||
k = k[len(FormFilePathKey):]
|
||||
}
|
||||
tmpData.Set(k, fmt.Sprintf("%v", v))
|
||||
}
|
||||
s.body = strings.NewReader(tmpData.Encode())
|
||||
}
|
||||
} else {
|
||||
switch s.BodyEntryMark {
|
||||
case BytesEntryType:
|
||||
s.body = bytes.NewReader(s.BodyEntries[BytesEntryType.string()].([]byte))
|
||||
case StringEntryType:
|
||||
s.body = strings.NewReader(s.BodyEntries[BytesEntryType.string()].(string))
|
||||
default:
|
||||
var parser, ok = s.bodyEntryParsers["form-urlencoded"]
|
||||
if !ok {
|
||||
tmpData := url.Values{}
|
||||
for k, v := range s.BodyEntries {
|
||||
if strings.HasPrefix(k, FormFilePathKey.string()) {
|
||||
k = k[len(FormFilePathKey):]
|
||||
}
|
||||
tmpData.Set(k, fmt.Sprintf("%v", v))
|
||||
}
|
||||
s.body = strings.NewReader(tmpData.Encode())
|
||||
s.Headers().ConentType_formUrlencoded()
|
||||
return
|
||||
}
|
||||
s.body = parser.Unmarshal(s.BodyEntryMark, s.BodyEntries)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
86
utils.go
86
utils.go
@ -7,6 +7,11 @@
|
||||
|
||||
package simpleRequest
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func IsJSONType(ct string) bool {
|
||||
return jsonCheck.MatchString(ct)
|
||||
}
|
||||
@ -24,3 +29,84 @@ func IsInArray(arr []string, str string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type xmlMapEntry struct {
|
||||
XMLName xml.Name
|
||||
Value interface{} `xml:",chardata"`
|
||||
}
|
||||
|
||||
// func MapToXml(data map[string]any) ([]byte, error) {
|
||||
// xmlData, err := mapToXML(data)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return xml.MarshalIndent(xmlData, "", " ")
|
||||
// }
|
||||
//
|
||||
// func mapToXML(m map[string]interface{}) (xmlMap map[string]xmlMapEntry, err error) {
|
||||
// if len(m) > 1 {
|
||||
// return nil, errors.New("xml format must have a root name,the map value must like this: map[string]interface{}{\"rootName\":map[string]interface{}{}}")
|
||||
// }
|
||||
// xmlMap = make(map[string]xmlMapEntry)
|
||||
// var rootName string
|
||||
// for root, data := range m {
|
||||
// rootName = root
|
||||
// for k, v := range data.(map[string]interface{}) {
|
||||
// switch typeV := v.(type) {
|
||||
// case map[string]interface{}:
|
||||
// subXmlMap, err := mapToXML(typeV)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// default:
|
||||
// entry := xmlMapEntry{XMLName: xml.Name{Local: k}, Value: v}
|
||||
// xmlMap[k] = entry
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// xmlData := struct {
|
||||
// XMLName xml.Name
|
||||
// Data []xmlMapEntry `xml:",any"`
|
||||
// }{
|
||||
// XMLName: xml.Name{Local: rootName},
|
||||
// Data: make([]xmlMapEntry, 0, len(xmlMap)),
|
||||
// }
|
||||
//
|
||||
// for _, v := range xmlMap {
|
||||
// xmlData.Data = append(xmlData.Data, v)
|
||||
// }
|
||||
//
|
||||
// return xml.MarshalIndent(xmlData, "", " ")
|
||||
// }
|
||||
|
||||
func mapToXML(m map[string]interface{}) ([]byte, error) {
|
||||
xmlData := make([]xmlNode, 0)
|
||||
|
||||
for k, v := range m {
|
||||
node := xmlNode{
|
||||
XMLName: xml.Name{Local: k},
|
||||
}
|
||||
|
||||
switch value := v.(type) {
|
||||
case map[string]interface{}:
|
||||
childXML, err := mapToXML(value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node.Data = childXML
|
||||
default:
|
||||
node.Data = []byte(fmt.Sprintf("%v", v))
|
||||
}
|
||||
|
||||
xmlData = append(xmlData, node)
|
||||
}
|
||||
|
||||
return xml.MarshalIndent(xmlData, "", " ")
|
||||
}
|
||||
|
||||
type xmlNode struct {
|
||||
XMLName xml.Name
|
||||
Data []byte `xml:",innerxml"`
|
||||
}
|
||||
|
82
utils_test.go
Normal file
82
utils_test.go
Normal file
@ -0,0 +1,82 @@
|
||||
// Package simpleRequest -----------------------------
|
||||
// @file : utils_test.go
|
||||
// @author : JJXu
|
||||
// @contact : wavingbear@163.com
|
||||
// @time : 2023/11/17 16:37
|
||||
// -------------------------------------------
|
||||
package simpleRequest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_mapToXML(t *testing.T) {
|
||||
type args struct {
|
||||
m map[string]interface{}
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "多级xml测试",
|
||||
args: args{
|
||||
m: map[string]interface{}{
|
||||
"UserInfo": map[string]any{
|
||||
"Name": "JJXu",
|
||||
"Age": 18,
|
||||
"isTrueMan": true,
|
||||
"assets": map[string]any{
|
||||
"car": "BMW",
|
||||
"house": "shanghai",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: "<UserInfo>\n<Age>18</Age>\n<isTrueMan>true</isTrueMan>\n<assets></assets>\n<Name>JJXu</Name>\n</UserInfo>",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "错误格式测试",
|
||||
args: args{},
|
||||
want: "",
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := mapToXML(tt.args.m)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("mapToXML() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if string(got) != tt.want {
|
||||
t.Errorf("mapToXML() got = %v, want %v", string(got), tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
func Test_mapToXML2(t *testing.T) {
|
||||
person := map[string]interface{}{
|
||||
"userInfo": map[string]interface{}{
|
||||
"name": "John",
|
||||
"age": 30,
|
||||
"address": map[string]interface{}{
|
||||
"street": "123 Main St",
|
||||
"city": "New York",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
xmlBytes, err := mapToXML(person)
|
||||
if err != nil {
|
||||
fmt.Println("Error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
xmlString := string(xmlBytes)
|
||||
fmt.Println(xmlString)
|
||||
}
|
Loading…
Reference in New Issue
Block a user