namesilo/vendor/github.com/basgys/goxml2json/plugins.go

162 lines
3.6 KiB
Go
Executable File

package xml2json
import (
"strings"
)
type (
// an plugin is added to an encoder or/and to an decoder to allow custom functionality at runtime
plugin interface {
AddToEncoder(*Encoder) *Encoder
AddToDecoder(*Decoder) *Decoder
}
// a type converter overides the default string sanitization for encoding json
encoderTypeConverter interface {
Convert(string) string
}
// customTypeConverter converts strings to JSON types using a best guess approach, only parses the JSON types given
// when initialized via WithTypeConverter
customTypeConverter struct {
parseTypes []JSType
}
attrPrefixer string
contentPrefixer string
excluder []string
nodesFormatter struct {
list []nodeFormatter
}
nodeFormatter struct {
path string
plugin nodePlugin
}
nodePlugin interface {
AddTo(*Node)
}
arrayFormatter struct{}
)
// WithTypeConverter allows customized js type conversion behavior by passing in the desired JSTypes
func WithTypeConverter(ts ...JSType) *customTypeConverter {
return &customTypeConverter{parseTypes: ts}
}
func (tc *customTypeConverter) parseAsString(t JSType) bool {
if t == String {
return true
}
for i := 0; i < len(tc.parseTypes); i++ {
if tc.parseTypes[i] == t {
return false
}
}
return true
}
// Adds the type converter to the encoder
func (tc *customTypeConverter) AddToEncoder(e *Encoder) *Encoder {
e.tc = tc
return e
}
func (tc *customTypeConverter) AddToDecoder(d *Decoder) *Decoder {
return d
}
func (tc *customTypeConverter) Convert(s string) string {
// remove quotes if they exists
if strings.HasPrefix(s, `"`) && strings.HasSuffix(s, `"`) {
s = s[1 : len(s)-1]
}
jsType := Str2JSType(s)
if tc.parseAsString(jsType) {
// add the quotes removed at the start of this func
s = `"` + s + `"`
}
return s
}
// WithAttrPrefix appends the given prefix to the json output of xml attribute fields to preserve namespaces
func WithAttrPrefix(prefix string) *attrPrefixer {
ap := attrPrefixer(prefix)
return &ap
}
func (a *attrPrefixer) AddToEncoder(e *Encoder) *Encoder {
e.attributePrefix = string((*a))
return e
}
func (a *attrPrefixer) AddToDecoder(d *Decoder) *Decoder {
d.attributePrefix = string((*a))
return d
}
// WithContentPrefix appends the given prefix to the json output of xml content fields to preserve namespaces
func WithContentPrefix(prefix string) *contentPrefixer {
c := contentPrefixer(prefix)
return &c
}
func (c *contentPrefixer) AddToEncoder(e *Encoder) *Encoder {
e.contentPrefix = string((*c))
return e
}
func (c *contentPrefixer) AddToDecoder(d *Decoder) *Decoder {
d.contentPrefix = string((*c))
return d
}
// ExcludeAttributes excludes some xml attributes, for example, xmlns:xsi, xsi:noNamespaceSchemaLocation
func ExcludeAttributes(attrs []string) *excluder {
ex := excluder(attrs)
return &ex
}
func (ex *excluder) AddToEncoder(e *Encoder) *Encoder {
return e
}
func (ex *excluder) AddToDecoder(d *Decoder) *Decoder {
d.ExcludeAttributes([]string((*ex)))
return d
}
// WithNodes formats specific nodes
func WithNodes(n ...nodeFormatter) *nodesFormatter {
return &nodesFormatter{list: n}
}
func (nf *nodesFormatter) AddToEncoder(e *Encoder) *Encoder {
return e
}
func (nf *nodesFormatter) AddToDecoder(d *Decoder) *Decoder {
d.AddFormatters(nf.list)
return d
}
func NodePlugin(path string, plugin nodePlugin) nodeFormatter {
return nodeFormatter{path: path, plugin: plugin}
}
func (nf *nodeFormatter) Format(node *Node) {
child := node.GetChild(nf.path)
if child != nil {
nf.plugin.AddTo(child)
}
}
func ToArray() *arrayFormatter {
return &arrayFormatter{}
}
func (af *arrayFormatter) AddTo(n *Node) {
n.ChildrenAlwaysAsArray = true
}