1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| package util
import ( "bytes" "encoding/xml" "fmt" "io" "reflect" "strings" )
func ToXML(x any) (string, error) { ret, err := ToXMLBytes(x, true) if err != nil { return "", err } return string(ret), nil }
func ToXMLCompact(x any) (string, error) { ret, err := ToXMLBytes(x, false) if err != nil { return "", err } return string(ret), nil }
func ToXMLBytes(x any, indent bool) ([]byte, error) { bts := &bytes.Buffer{} enc := xml.NewEncoder(bts) if indent { enc.Indent("", " ") } if m, err := Cast[map[string]any](x); err == nil { x = ValueMap(m) } err := enc.Encode(x) //nolint:errchkxml // no chance of error if err != nil { return nil, err } b := bts.Bytes() if rf := reflect.ValueOf(x); rf.Kind() == reflect.Slice { n := fmt.Sprintf("%T", x) n = strings.NewReplacer("[", "", "]", "", "{", "", "}", "", " ", "").Replace(n) if idx := strings.LastIndex(n, "."); idx > -1 { n = n[idx+1:] } if n == "interface" || n == "any" { n = "array" } if indent { b = append([]byte(fmt.Sprintf("<%s>\n", n)), b...) b = append(b, []byte(fmt.Sprintf("\n</%s>", n))...) } else { b = append([]byte(fmt.Sprintf("<%s>", n)), b...) b = append(b, []byte(fmt.Sprintf("</%s>", n))...) } } return b, nil }
func FromXML(msg []byte, tgt any) error { return xml.Unmarshal(msg, tgt) }
func FromXMLString(msg []byte) (string, error) { var tgt string err := xml.Unmarshal(msg, &tgt) return tgt, err }
func FromXMLMap(msg []byte) (ValueMap, error) { var tgt ValueMap err := xml.Unmarshal(msg, &tgt) return tgt, err }
func FromXMLAny(msg []byte) (any, error) { var tgt any err := FromXML(msg, &tgt) return tgt, err }
func FromXMLReader(r io.Reader, tgt any) error { return xml.NewDecoder(r).Decode(tgt) }
func FromXMLStrict(msg []byte, tgt any) error { dec := xml.NewDecoder(bytes.NewReader(msg)) dec.Strict = true return dec.Decode(tgt) }
func CycleXML(src any, tgt any) error { b, _ := xml.Marshal(src) return FromXML(b, tgt) }
|