381 Star 2.5K Fork 616

GVPJohn / gf

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
anyxml.go 3.58 KB
一键复制 编辑 原始数据 按行查看 历史
package mxj
import (
"encoding/xml"
"reflect"
)
const (
DefaultElementTag = "element"
)
// Encode arbitrary value as XML.
//
// Note: unmarshaling the resultant
// XML may not return the original value, since tag labels may have been injected
// to create the XML representation of the value.
/*
Encode an arbitrary JSON object.
package main
import (
"encoding/json"
"fmt"
"gitee.com/johng/gf/third/github.com/clbanning/mxj"
)
func main() {
jsondata := []byte(`[
{ "somekey":"somevalue" },
"string",
3.14159265,
true
]`)
var i interface{}
err := json.Unmarshal(jsondata, &i)
if err != nil {
// do something
}
x, err := mxj.AnyXmlIndent(i, "", " ", "mydoc")
if err != nil {
// do something else
}
fmt.Println(string(x))
}
output:
<mydoc>
<somekey>somevalue</somekey>
<element>string</element>
<element>3.14159265</element>
<element>true</element>
</mydoc>
*/
// Alternative values for DefaultRootTag and DefaultElementTag can be set as:
// AnyXml( v, myRootTag, myElementTag).
func AnyXml(v interface{}, tags ...string) ([]byte, error) {
if reflect.TypeOf(v).Kind() == reflect.Struct {
return xml.Marshal(v)
}
var err error
s := new(string)
p := new(pretty)
var rt, et string
if len(tags) == 1 || len(tags) == 2 {
rt = tags[0]
} else {
rt = DefaultRootTag
}
if len(tags) == 2 {
et = tags[1]
} else {
et = DefaultElementTag
}
var ss string
var b []byte
switch v.(type) {
case []interface{}:
ss = "<" + rt + ">"
for _, vv := range v.([]interface{}) {
switch vv.(type) {
case map[string]interface{}:
m := vv.(map[string]interface{})
if len(m) == 1 {
for tag, val := range m {
err = mapToXmlIndent(false, s, tag, val, p)
}
} else {
err = mapToXmlIndent(false, s, et, vv, p)
}
default:
err = mapToXmlIndent(false, s, et, vv, p)
}
if err != nil {
break
}
}
ss += *s + "</" + rt + ">"
b = []byte(ss)
case map[string]interface{}:
m := Map(v.(map[string]interface{}))
b, err = m.Xml(rt)
default:
err = mapToXmlIndent(false, s, rt, v, p)
b = []byte(*s)
}
return b, err
}
// Encode an arbitrary value as a pretty XML string.
// Alternative values for DefaultRootTag and DefaultElementTag can be set as:
// AnyXmlIndent( v, "", " ", myRootTag, myElementTag).
func AnyXmlIndent(v interface{}, prefix, indent string, tags ...string) ([]byte, error) {
if reflect.TypeOf(v).Kind() == reflect.Struct {
return xml.MarshalIndent(v, prefix, indent)
}
var err error
s := new(string)
p := new(pretty)
p.indent = indent
p.padding = prefix
var rt, et string
if len(tags) == 1 || len(tags) == 2 {
rt = tags[0]
} else {
rt = DefaultRootTag
}
if len(tags) == 2 {
et = tags[1]
} else {
et = DefaultElementTag
}
var ss string
var b []byte
switch v.(type) {
case []interface{}:
ss = "<" + rt + ">\n"
p.Indent()
for _, vv := range v.([]interface{}) {
switch vv.(type) {
case map[string]interface{}:
m := vv.(map[string]interface{})
if len(m) == 1 {
for tag, val := range m {
err = mapToXmlIndent(true, s, tag, val, p)
}
} else {
p.start = 1 // we 1 tag in
err = mapToXmlIndent(true, s, et, vv, p)
*s += "\n"
}
default:
p.start = 0 // in case trailing p.start = 1
err = mapToXmlIndent(true, s, et, vv, p)
}
if err != nil {
break
}
}
ss += *s + "</" + rt + ">"
b = []byte(ss)
case map[string]interface{}:
m := Map(v.(map[string]interface{}))
b, err = m.XmlIndent(prefix, indent, rt)
default:
err = mapToXmlIndent(true, s, rt, v, p)
b = []byte(*s)
}
return b, err
}
Go
1
https://gitee.com/johng/gf.git
git@gitee.com:johng/gf.git
johng
gf
gf
v1.4.7

搜索帮助

53164aa7 5694891 3bd8fe86 5694891