2019-02-02 16:18:25 +08:00
|
|
|
// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
2018-01-19 15:26:28 +08:00
|
|
|
//
|
|
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
|
|
// If a copy of the MIT was not distributed with this file,
|
2019-02-02 16:18:25 +08:00
|
|
|
// You can obtain one at https://github.com/gogf/gf.
|
2018-01-19 15:26:28 +08:00
|
|
|
|
2019-01-15 23:27:47 +08:00
|
|
|
// Package gxml provides accessing and converting for XML content.
|
2018-01-19 15:26:28 +08:00
|
|
|
package gxml
|
|
|
|
|
|
|
|
import (
|
2019-02-02 16:18:25 +08:00
|
|
|
"github.com/gogf/gf/third/github.com/clbanning/mxj"
|
2018-05-29 23:23:49 +08:00
|
|
|
"encoding/xml"
|
|
|
|
"io"
|
2019-02-02 16:18:25 +08:00
|
|
|
"github.com/gogf/gf/g/text/gregex"
|
|
|
|
"github.com/gogf/gf/third/github.com/axgle/mahonia"
|
2018-06-06 14:58:50 +08:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
2018-06-07 08:37:24 +08:00
|
|
|
"strings"
|
2018-01-19 15:26:28 +08:00
|
|
|
)
|
|
|
|
|
2018-06-01 20:52:17 +08:00
|
|
|
// 将XML内容解析为map变量
|
2018-01-19 15:26:28 +08:00
|
|
|
func Decode(xmlbyte []byte) (map[string]interface{}, error) {
|
2018-06-07 08:37:24 +08:00
|
|
|
prepare(xmlbyte)
|
2018-01-19 15:26:28 +08:00
|
|
|
return mxj.NewMapXml(xmlbyte)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 将map变量解析为XML格式内容
|
2018-01-19 16:19:48 +08:00
|
|
|
func Encode(v map[string]interface{}, rootTag...string) ([]byte, error) {
|
|
|
|
return mxj.Map(v).Xml(rootTag...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func EncodeWithIndent(v map[string]interface{}, rootTag...string) ([]byte, error) {
|
|
|
|
return mxj.Map(v).XmlIndent("", "\t", rootTag...)
|
2018-01-19 15:26:28 +08:00
|
|
|
}
|
|
|
|
|
2018-06-01 20:52:17 +08:00
|
|
|
// XML格式内容直接转换为JSON格式内容
|
2018-01-19 15:26:28 +08:00
|
|
|
func ToJson(xmlbyte []byte) ([]byte, error) {
|
2018-06-07 08:37:24 +08:00
|
|
|
prepare(xmlbyte)
|
2018-06-01 20:52:17 +08:00
|
|
|
mv, err := mxj.NewMapXml(xmlbyte)
|
|
|
|
if err == nil {
|
2018-01-19 15:26:28 +08:00
|
|
|
return mv.Json()
|
|
|
|
} else {
|
|
|
|
return nil, err
|
|
|
|
}
|
2018-06-04 12:32:32 +08:00
|
|
|
}
|
|
|
|
|
2018-06-07 08:37:24 +08:00
|
|
|
// XML字符集预处理
|
|
|
|
// @author wenzi1
|
|
|
|
// @date 20180604
|
|
|
|
func prepare(xmlbyte []byte) error {
|
|
|
|
patten := `<\?xml.*encoding\s*=\s*['|"](.*?)['|"].*\?>`
|
2018-06-04 12:32:32 +08:00
|
|
|
charsetReader := func(charset string, input io.Reader) (io.Reader, error) {
|
2018-06-06 14:58:50 +08:00
|
|
|
reader := mahonia.GetCharset(charset)
|
|
|
|
if reader == nil {
|
|
|
|
return nil, errors.New(fmt.Sprintf("not support charset:%s", charset))
|
2018-06-04 12:32:32 +08:00
|
|
|
}
|
|
|
|
return reader.NewDecoder().NewReader(input), nil
|
|
|
|
}
|
|
|
|
|
2018-07-11 17:06:47 +08:00
|
|
|
matchStr, err := gregex.MatchString(patten, string(xmlbyte))
|
2018-06-04 12:32:32 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-07-04 11:17:15 +08:00
|
|
|
|
|
|
|
xmlEncode := "UTF-8"
|
|
|
|
if len(matchStr) == 2 {
|
|
|
|
xmlEncode = matchStr[1]
|
|
|
|
}
|
2018-06-04 12:32:32 +08:00
|
|
|
|
2018-07-04 11:17:15 +08:00
|
|
|
charset := mahonia.GetCharset(xmlEncode)
|
2018-06-06 14:58:50 +08:00
|
|
|
if charset == nil {
|
2018-07-04 11:17:15 +08:00
|
|
|
return errors.New(fmt.Sprintf("not support charset:%s", xmlEncode))
|
2018-06-04 12:32:32 +08:00
|
|
|
}
|
|
|
|
|
2018-06-07 08:37:24 +08:00
|
|
|
if !strings.EqualFold(charset.Name, "UTF-8") {
|
|
|
|
mxj.CustomDecoder = &xml.Decoder{Strict : false, CharsetReader : charsetReader}
|
2018-06-04 12:32:32 +08:00
|
|
|
}
|
|
|
|
return nil
|
2018-01-19 15:26:28 +08:00
|
|
|
}
|