| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- 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
- }
|