Documentation
¶
Index ¶
- Variables
- type BadgerFish
- type EncodeDecoder
- type JSONConverter
- func (c *JSONConverter) JSONtoXML(b []byte) ([]byte, error)
- func (c *JSONConverter) WithJSONDecoderOpts(opts ...func(*json.Decoder))
- func (c *JSONConverter) WithJSONEncoderOpts(opts ...func(*json.Encoder))
- func (c *JSONConverter) WithXMLDecoderOpts(opts ...func(*xml.Decoder))
- func (c *JSONConverter) WithXMLEncoderOpts(opts ...func(*xml.Encoder))
- func (c *JSONConverter) XMLtoJSON(b []byte) ([]byte, error)
- type RayFish
- type Simple
- type XMLError
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( CauseDataType = "xmlconv: invalid data type." CauseJSONStruct = "xmlconv: invalid json structure." CauseJSONKey = "xmlconv: invalid json key." CauseEmptyVal = "xmlconv: invalid empty value." CauseJSONEncoder = "xmlconv: json encoder return with an error." CauseJSONDecoder = "xmlconv: json decoder return with an error." CauseXMLEncoder = "xmlconv: xml encoder return with an error." CauseXMLDecoder = "xmlconv: xml decoder return with an error." )
Functions ¶
This section is empty.
Types ¶
type BadgerFish ¶
type BadgerFish struct { // TextKey is the json key name to store text content of elements. // Typically "$" is used. // TextKey should not be empty. TextKey string // AttrPrefix is the json key name prefix for XML attributes. // Attribute names are stored in json with this prefix. // For example, XML attribute foo="bar" is converted into {"@foo": "bar"}. // Typically "@" is used. // AttrPrefix should not be empty. AttrPrefix string // NamespaceSep is the name space separator. // Namespace separator ":" in XML element names are converted // into the specified string. // Use ":" if there is no reason to change. // NamespaceSep should not be empty. NamespaceSep string // TrimSpace if true, trims unicode space from xml text. // See the [unicode.IsSpace] for space definition. // This option is used in XML to JSON conversion. TrimSpace bool // XMLValue convert JSON value into XML value. // Input value is the any type value decoded by [json.Decoder]. // Returned value is recognized by [xml.Encoder]. // The given [xml.StartElement] can be modified in the function. // This option is used in JSON to XML conversion. XMLValue func(any, *xml.StartElement) (xml.Token, error) // JSONValue convert XML value into JSON value. // Input value is the text part of a XML element. // Returned value is recognized by [json.Encoder]. // This function is used in XML to JSON conversion. JSONValue func(string, xml.StartElement) (any, error) // contains filtered or unexported fields }
BadgerFish is the XML JSON converter following BadgerFish encode-decoder. Basic conversion rules are shown in the table below.
References:
- http://www.sklar.com/badgerfish/
- https://wiki.open311.org/JSON_and_XML_Conversion/
- http://dropbox.ashlock.us/open311/json-xml/
- https://github.com/bramstein/xsltjson/
- https://pypi.org/project/xmljson/
- https://cloud.google.com/apigee/docs/api-platform/reference/policies/xml-json-policy
- https://cloud.google.com/apigee/docs/api-platform/reference/policies/json-xml-policy
Conversion Rules:
┌=====================================┐┌=====================================┐ │ XML Input ││ JSON Output | └=====================================┘└=====================================┘ | A simple element without attributes or children. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice>bob</alice> ││ { │ │ ││ "alice": { "$": "bob" } │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An element with attribute. Prefix "@" is added to the name. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice charlie="david">bob</alice> ││ { │ │ ││ "alice": { │ │ ││ "$": "bob", │ │ ││ "@charlie": "david" │ │ ││ } │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An element with children. Children have different name. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice> ││ { │ │ <bob>charlie</bob> ││ "alice": { │ │ <david>edgar</david> ││ "bob": { "$": "charlie" }, │ │ </alice> ││ "david": { "$": "edgar" } │ │ ││ } │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An element with children. Children have the same name. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice> ││ { │ │ <bob>charlie</bob> ││ "alice": { │ │ <bob>edgar</bob> ││ "bob": [ │ │ </alice> ││ { "$": "charlie" }, │ │ ││ { "$": "edgar" } │ │ ││ ] │ │ ││ } │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An element with mixed content. Text contents are joined. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice> ││ { │ │ bob ││ "alice": { │ │ <charlie>david</charlie> ││ "$": "bobedgar", │ │ edgar ││ "charlie": { "$": "david" } │ │ </alice> ││ } │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An element with namespaces. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice xmlns:ns="http://abc.com/"> ││ { │ │ <ns:bob>charlie</ns:bob> ││ "alice": { │ │ </alice> ││ "@xmlns": { │ │ ││ "ns": "http://abc.com/" │ │ ││ }, │ │ ││ "ns:bob": { "$": "charlie" } │ │ ││ } │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An empty element with empty attribute. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice charlie=""></alice> ││ { │ │ ││ "alice": { │ │ ││ "@charlie": "" │ │ ││ } │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | [BadgerFish.WithEmptyValue] replaces the JSON value for empty elements. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <!-- m := map[string]any{} --> ││ { │ │ <!-- WithEmptyValue(m) --> ││ "alice": {} │ │ <alice></alice> ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <!-- WithEmptyValue("") --> ││ { │ │ <alice></alice> ││ "alice": "" │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <!-- WithEmptyValue(nil) --> ││ { │ │ <alice></alice> ││ "alice": null │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘
Example (Jsonxml) ¶
package main import ( "fmt" "github.com/aileron-projects/go/zencoding/zxml" ) func main() { c := zxml.JSONConverter{ EncodeDecoder: zxml.NewBadgerFish(), } b, err := c.JSONtoXML([]byte(`{"alice":{"$":"bob","@charlie":"david"}}`)) if err != nil { panic(err) } fmt.Println(string(b)) }
Output: <alice charlie="david">bob</alice>
Example (Xmljson) ¶
package main import ( "fmt" "github.com/aileron-projects/go/zencoding/zxml" ) func main() { c := zxml.JSONConverter{ EncodeDecoder: zxml.NewBadgerFish(), } b, err := c.XMLtoJSON([]byte(`<alice charlie="david">bob</alice>`)) if err != nil { panic(err) } fmt.Println(string(b)) }
Output: {"alice":{"$":"bob","@charlie":"david"}}
func NewBadgerFish ¶
func NewBadgerFish() *BadgerFish
NewBadgerFish returns a new instance of BadgerFish with default configuration.
func (*BadgerFish) Decode ¶
func (b *BadgerFish) Decode(decoder *xml.Decoder) (any, error)
Decode decodes XML document read by the decoder into Go values.
Returned value can be:
- map[string]any
- []map[string]any
Decode:
- Ignores encoding/xml.Comment
- Ignores encoding/xml.ProcInst
- Ignores encoding/xml.Directive
- Does not identify CDATA (Limitation of encoding/xml)
func (*BadgerFish) Encode ¶
Encode encodes the given obj into XML document. Resulting XML is written into the encoder. See the comment on BadgerFish for conversion rules.
func (*BadgerFish) WithEmptyValue ¶
func (b *BadgerFish) WithEmptyValue(v any)
WithEmptyValue replaces the value corresponding to empty element that do not have any attributes, text content and child elements. The given value is used in XML to JSON conversion. Allowed values are listed below and other will result in panic.
Allowed values are:
- nil
- string("")
- make(map[string]any,0)
type EncodeDecoder ¶
type EncodeDecoder interface { // Encode encodes the obj into XML document. // Structure of the obj must follow the implementer's instruction. Encode(encoder *xml.Encoder, obj map[string]any) error // Decode decodes XML document read from the decoder // into map[string]any or []map[string]any. Decode(decoder *xml.Decoder) (any, error) }
EncodeDecoder provides interface for encoding and decoding XML document from/to JSON object.
type JSONConverter ¶
type JSONConverter struct { EncodeDecoder // Header is the XML header line string. // If not empty, the value is written into the // header part of XML document. // Typically [encoding/xml.Header] should be used. Header string // contains filtered or unexported fields }
JSONConverter converts XML to JSON document and JSON to XML document.
func (*JSONConverter) JSONtoXML ¶
func (c *JSONConverter) JSONtoXML(b []byte) ([]byte, error)
JSONtoXML converts JSON document into XML document. Given json structure must follow the instruction of the [JSONConverter.EncodeDecoder].
func (*JSONConverter) WithJSONDecoderOpts ¶
func (c *JSONConverter) WithJSONDecoderOpts(opts ...func(*json.Decoder))
WithJSONDecoderOpts registers JSON decoder options. Following example applies decoder to parse numbers as encoding/json.Number.
Example:
func(d *json.Decoder){ d.UseNumber() }
Example ¶
package main import ( "encoding/json" "fmt" "github.com/aileron-projects/go/zencoding/zxml" ) func main() { c := zxml.JSONConverter{ EncodeDecoder: zxml.NewSimple(), } c.WithJSONDecoderOpts(func(d *json.Decoder) { d.UseNumber() }) b, err := c.JSONtoXML([]byte(`{"alice":{"$":1.2345678901234567890}}`)) if err != nil { panic(err) } fmt.Println(string(b)) }
Output: <alice>1.2345678901234567890</alice>
func (*JSONConverter) WithJSONEncoderOpts ¶
func (c *JSONConverter) WithJSONEncoderOpts(opts ...func(*json.Encoder))
WithJSONEncoderOpts registers JSON encoder options. Following example make the encoder not to apply HTML escape and to use indent.
Example:
func(e *json.Encoder) { e.SetEscapeHTML(false) e.SetIndent("", " ") }
Example ¶
package main import ( "encoding/json" "fmt" "github.com/aileron-projects/go/zencoding/zxml" ) func main() { c := zxml.JSONConverter{ EncodeDecoder: zxml.NewSimple(), } c.WithJSONEncoderOpts(func(e *json.Encoder) { e.SetIndent("", " ") }) b, err := c.XMLtoJSON([]byte(`<alice>bob</alice>`)) if err != nil { panic(err) } fmt.Println(string(b)) }
Output: { "alice": "bob" }
func (*JSONConverter) WithXMLDecoderOpts ¶
func (c *JSONConverter) WithXMLDecoderOpts(opts ...func(*xml.Decoder))
WithXMLDecoderOpts registers XML decoder options. Following example adds ability to read non UTF-8 XML document.
Example:
func(d *xml.Decoder) { d.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) { switch { case strings.EqualFold(charset, "Shift_JIS"): return transform.NewReader(input, japanese.ShiftJIS.NewDecoder()), nil } return input, nil } }
Example ¶
package main import ( "encoding/xml" "fmt" "io" "strings" "github.com/aileron-projects/go/zencoding/zxml" "golang.org/x/text/encoding/japanese" "golang.org/x/text/transform" ) func main() { c := zxml.JSONConverter{ EncodeDecoder: zxml.NewSimple(), } c.WithXMLDecoderOpts(func(d *xml.Decoder) { d.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) { switch { case strings.EqualFold(charset, "Shift_JIS"): return transform.NewReader(input, japanese.ShiftJIS.NewDecoder()), nil } return input, nil } }) header := `<?xml version="1.0" encoding="SHIFT_JIS"?>` b, err := c.XMLtoJSON([]byte(header + "<alice>\xea\x9f</alice>")) if err != nil { panic(err) } fmt.Println(string(b)) }
Output: {"alice":"堯"}
func (*JSONConverter) WithXMLEncoderOpts ¶
func (c *JSONConverter) WithXMLEncoderOpts(opts ...func(*xml.Encoder))
WithXMLEncoderOpts registers XML encoder options. Following example apply indent to the output.
Example:
func(e *xml.Encoder){ e.Indent("", " ") }
Example ¶
package main import ( "encoding/xml" "fmt" "github.com/aileron-projects/go/zencoding/zxml" ) func main() { c := zxml.JSONConverter{ EncodeDecoder: zxml.NewSimple(), } c.WithXMLEncoderOpts(func(e *xml.Encoder) { e.Indent("", " ") }) b, err := c.JSONtoXML([]byte(`{"alice":{"bob":{"$":"david"}}}`)) if err != nil { panic(err) } fmt.Println(string(b)) }
Output: <alice> <bob>david</bob> </alice>
type RayFish ¶
type RayFish struct { // NameKeys is the json key name to store // XML element names. // Typically "#name" is used. // NameKey should not be empty. NameKey string // TextKey is the json key name to store text content of elements. // Typically "#text" is used. // TextKey should not be empty. TextKey string // ChildrenKey is the json key name to store // attributes of a element and its child elements. // Typically "#children" is used. // ChildrenKey should not be empty. ChildrenKey string // AttrPrefix is the json key name prefix for XML attributes. // Attribute names are stored in json with this prefix. // For example, XML attribute foo="bar" is converted into {"@foo": "bar"}. // Typically "@" is used. // AttrPrefix should not be empty. AttrPrefix string // NamespaceSep is the name space separator. // Namespace separator ":" in XML element names are converted // into the specified string. // Note that general RayFish convention discards namespace information // but this encode-decoder keeps them. // Use ":" if there is no reason to change. // NamespaceSep should not be empty. NamespaceSep string // TrimSpace if true, trims unicode space from xml text. // See the [unicode.IsSpace] for space definition. // This option is used in XML to JSON conversion. TrimSpace bool // XMLValue convert JSON value into XML value. // Input value is the any type value decoded by [json.Decoder]. // Returned value is recognized by [xml.Encoder]. // The given [xml.StartElement] can be modified in the function. // This option is used in JSON to XML conversion. XMLValue func(any, *xml.StartElement) (xml.Token, error) // JSONValue convert XML value into JSON value. // Input value is the text part of a XML element. // Returned value is recognized by [json.Encoder]. // This function is used in XML to JSON conversion. JSONValue func(string, xml.StartElement) (any, error) // contains filtered or unexported fields }
RayFish is the XML JSON converter following RayFish encode-decoder. Basic conversion rules are shown in the table below.
References:
- https://www.onperl.org/blog/onperl/page/rayfish
- https://github.com/bramstein/xsltjson/
- https://wiki.open311.org/JSON_and_XML_Conversion/
- https://pypi.org/project/xmljson/
Conversion Rules:
┌=====================================┐┌=====================================┐ │ XML Input ││ JSON Output | └=====================================┘└=====================================┘ | A simple element without attributes or children. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice>bob</alice> ││ { │ │ ││ "#name": "alice", │ │ ││ "#text": "bob", │ │ ││ "#children": [] │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An element with attribute. Prefix "@" is added to the name. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice charlie="david">bob</alice> ││ { │ │ ││ "#name": "alice", │ │ ││ "#text": "bob", │ │ ││ "#children": [ │ │ ││ { │ │ ││ "#name": "@charlie", │ │ ││ "#text": "david", │ │ ││ "#children": [] │ │ ││ } │ │ ││ ] │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An element with children. Children have different name. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice> ││ { │ │ <bob>charlie</bob> ││ "#name": "alice", │ │ <david>edgar</david> ││ "#text": "", │ │ </alice> ││ "#children": [ │ │ ││ { │ │ ││ "#name": "bob", │ │ ││ "#text": "charlie", │ │ ││ "#children": [] │ │ ││ }, │ │ ││ { │ │ ││ "#name": "david", │ │ ││ "#text": "edgar", │ │ ││ "#children": [] │ │ ││ } │ │ ││ ] │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An element with children. Children have the same name. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice> ││ { │ │ <bob>charlie</bob> ││ "#name": "alice", │ │ <bob>edgar</bob> ││ "#text": "", │ │ </alice> ││ "#children": [ │ │ ││ { │ │ ││ "#name": "bob", │ │ ││ "#text": "charlie", │ │ ││ "#children": [] │ │ ││ }, │ │ ││ { │ │ ││ "#name": "bob", │ │ ││ "#text": "edgar", │ │ ││ "#children": [] │ │ ││ } │ │ ││ ] │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An element with mixed content. Text contents are joined. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice> ││ { │ │ bob ││ "#name": "alice", │ │ <charlie>david</charlie> ││ "#text": "bobedgar", │ │ edgar ││ "#children": [ │ │ </alice> ││ { │ │ ││ "#name": "charlie", │ │ ││ "#text": "david", │ │ ││ "#children": [] │ │ ││ } │ │ ││ ] │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An element with namespaces. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice xmlns:ns="http://abc.com/"> ││ { │ │ <ns:bob>charlie</ns:bob> ││ "#name": "alice", │ │ </alice> ││ "#text": "", │ │ ││ "#children": [ │ │ ││ { │ │ ││ "#name": "@xmlns:ns", │ │ ││ "#text": "http://abc.com/", │ │ ││ "#children": [] │ │ ││ }, │ │ ││ { │ │ ││ "#name": "ns:bob", │ │ ││ "#text": "charlie", │ │ ││ "#children": [] │ │ ││ } │ │ ││ ] │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An empty element with empty attribute. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice charlie=""></alice> ││ { │ │ ││ "#name": "alice", │ │ ││ "#text": "", │ │ ││ "#children": [ │ │ ││ { │ │ ││ "#name": "@charlie", │ │ ││ "#text": "", │ │ ││ "#children": [] │ │ ││ } │ │ ││ ] │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | [RayFish.WithEmptyValue] replaces the JSON value for empty elements. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <!-- WithEmptyValue("") --> ││ { │ │ <alice></alice> ││ "#name": "alice", │ │ ││ "#text": "", │ │ ││ "#children": [] │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <!-- WithEmptyValue(nil) --> ││ { │ │ <alice></alice> ││ "#name": "alice", │ │ ││ "#text": null, │ │ ││ "#children": [] │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘
Example (Jsonxml) ¶
package main import ( "fmt" "github.com/aileron-projects/go/zencoding/zxml" ) func main() { c := zxml.JSONConverter{ EncodeDecoder: zxml.NewRayFish(), } b, err := c.JSONtoXML([]byte(` { "#name": "alice", "#text": "bob", "#children": [ { "#name": "@charlie", "#text": "david", "#children": [] } ] } `)) if err != nil { panic(err) } fmt.Println(string(b)) }
Output: <alice charlie="david">bob</alice>
Example (Xmljson) ¶
package main import ( "fmt" "github.com/aileron-projects/go/zencoding/zxml" ) func main() { c := zxml.JSONConverter{ EncodeDecoder: zxml.NewRayFish(), } b, err := c.XMLtoJSON([]byte(`<alice charlie="david">bob</alice>`)) if err != nil { panic(err) } fmt.Println(string(b)) }
Output: {"#children":[{"#children":[],"#name":"@charlie","#text":"david"}],"#name":"alice","#text":"bob"}
func NewRayFish ¶
func NewRayFish() *RayFish
NewRayFish returns a new instance of RayFish with default configuration.
func (*RayFish) Decode ¶
Decode decodes XML document read by the decoder into Go values.
Returned value can be:
- map[string]any
- []map[string]any
Decode:
- Ignores encoding/xml.Comment
- Ignores encoding/xml.ProcInst
- Ignores encoding/xml.Directive
- Does not identify CDATA (Limitation of encoding/xml)
func (*RayFish) Encode ¶
Encode encodes the given obj into XML document. Resulting XML is written into the encoder. See the comment on RayFish for conversion rules.
func (*RayFish) WithEmptyValue ¶
WithEmptyValue replaces the value corresponding to empty element that do not have any attributes, text content and child elements. The given value is used in XML to JSON conversion. Allowed values are listed below and other will result in panic.
Allowed values are:
- nil
- string("")
type Simple ¶
type Simple struct { // TextKey is the json key name to store text content of elements. // Typically "$" is used. // TextKey should not be empty. TextKey string // AttrPrefix is the json key name prefix for XML attributes. // Attribute names are stored in json with this prefix. // For example, XML attribute foo="bar" is converted into {"@foo": "bar"}. // Typically "@" is used. // AttrPrefix should not be empty. AttrPrefix string // NamespaceSep is the name space separator. // Namespace separator ":" in XML element names are converted // into the specified string. // Note that general RayFish convention discards namespace information // but this encode-decoder keeps them. // Use ":" if there is no reason to change. // NamespaceSep should not be empty. NamespaceSep string // TrimSpace if true, trims unicode space from xml text. // See the [unicode.IsSpace] for space definition. // This option is used in XML to JSON conversion. TrimSpace bool // PreferShort if true, use short format. // For XML to JSON conversion, if content has no attribute and no child elements, // JSON will be {"key": "value"} rather than {"key": {"$": "value"}}. // For JSON to XML conversion, JSON can always use {"key": "value"} // and {"key": {"$": "value"}} expression without this configuration. // This option is used in XML to JSON conversion. PreferShort bool // XMLValue convert JSON value into XML value. // Input value is the any type value decoded by [json.Decoder]. // Returned value is recognized by [xml.Encoder]. // The given [xml.StartElement] can be modified in the function. // This option is used in JSON to XML conversion. XMLValue func(any, *xml.StartElement) (xml.Token, error) // JSONValue convert XML value into JSON value. // Input value is the text part of a XML element. // Returned value is recognized by [json.Encoder]. // This function is used in XML to JSON conversion. JSONValue func(string, xml.StartElement) (any, error) // contains filtered or unexported fields }
Simple is the simple XML JSON encode-decoder. It is not an implementation of convention such as RayFish or BadgerFish. Basic conversion rules are shown in the table below.
References:
- https://www.onperl.org/blog/onperl/page/rayfish
- https://github.com/bramstein/xsltjson/
- https://wiki.open311.org/JSON_and_XML_Conversion/
- https://pypi.org/project/xmljson/
Conversion Rules:
┌=====================================┐┌=====================================┐ │ XML Input ││ JSON Output | └=====================================┘└=====================================┘ | A simple element without attributes or children. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice>bob</alice> ││ { │ │ ││ "alice": { "$": "bob" } │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An element with attribute. Prefix "@" is added to the name. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice charlie="david">bob</alice> ││ { │ │ ││ "alice": { │ │ ││ "$": "bob", │ │ ││ "@charlie": "david" │ │ ││ } │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An element with children. Children have different name. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice> ││ { │ │ <bob>charlie</bob> ││ "alice": { │ │ <david>edgar</david> ││ "bob": { "$": "charlie" }, │ │ </alice> ││ "david": { "$": "edgar" } │ │ ││ } │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An element with children. Children have the same name. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice> ││ { │ │ <bob>charlie</bob> ││ "alice": { │ │ <bob>edgar</bob> ││ "bob": [ │ │ </alice> ││ { "$": "charlie" }, │ │ ││ { "$": "edgar" } │ │ ││ ] │ │ ││ } │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An element with mixed content. Text contents are joined. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice> ││ { │ │ bob ││ "alice": { │ │ <charlie>david</charlie> ││ "$": "bobedgar", │ │ edgar ││ "charlie": { "$": "david" } │ │ </alice> ││ } │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An element with namespaces. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice xmlns:ns="http://abc.com/"> ││ { │ │ <ns:bob>charlie</ns:bob> ││ "alice": { │ │ </alice> ││ "@xmlns:ns": "http://abc.com/", │ │ ││ "ns:bob": { "$": "charlie" } │ │ ││ } │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | An empty element with empty attribute. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice charlie=""></alice> ││ { │ │ ││ "alice": { "@charlie": "" } │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | Option [Simple.PreferShort] directory associates text value to the key. | This option works for the element without any child elements and attributes. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <alice>bob</alice> ││ { │ │ ││ "alice": "bob" │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ | [Simple.WithEmptyValue] replaces the JSON value for empty elements. | Note that the output will be different when [Simple.PreferShort] is true. ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <!-- WithEmptyValue("") --> ││ { │ │ <alice></alice> ││ "alice": { "$": "" } │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <!-- WithEmptyValue(nil) --> ││ { │ │ <alice></alice> ││ "alice": {} │ │ ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘ ┌─────────────────────────────────────┐┌─────────────────────────────────────┐ │ <!-- m := map[string]any{} --> ││ { │ │ <!-- WithEmptyValue(m) --> ││ "alice": { "$": {} } │ │ <alice></alice> ││ } │ └─────────────────────────────────────┘└─────────────────────────────────────┘
Example (Jsonxml) ¶
package main import ( "fmt" "github.com/aileron-projects/go/zencoding/zxml" ) func main() { c := zxml.JSONConverter{ EncodeDecoder: zxml.NewSimple(), } b, err := c.JSONtoXML([]byte(`{"alice":{"$":"bob","@charlie":"david"}}`)) if err != nil { panic(err) } fmt.Println(string(b)) }
Output: <alice charlie="david">bob</alice>
Example (Xmljson) ¶
package main import ( "fmt" "github.com/aileron-projects/go/zencoding/zxml" ) func main() { c := zxml.JSONConverter{ EncodeDecoder: zxml.NewSimple(), } b, err := c.XMLtoJSON([]byte(`<alice charlie="david">bob</alice>`)) if err != nil { panic(err) } fmt.Println(string(b)) }
Output: {"alice":{"$":"bob","@charlie":"david"}}
func NewSimple ¶
func NewSimple() *Simple
NewSimple returns a new instance of Simple encode-decoder with default configuration.
func (*Simple) Decode ¶
Decode decodes XML document read by the decoder into Go values.
Returned value can be:
- map[string]any
- []map[string]any
Decode:
- Ignores encoding/xml.Comment
- Ignores encoding/xml.ProcInst
- Ignores encoding/xml.Directive
- Does not identify CDATA (Limitation of encoding/xml)
func (*Simple) Encode ¶
Encode encodes the given obj into XML document. Resulting XML is written into the encoder. See the comment on Simple for conversion rules.
func (*Simple) WithEmptyValue ¶
WithEmptyValue replaces the value corresponding to empty element that do not have any attributes, text content and child elements. The given value is used in XML to JSON conversion. Allowed values are listed below and others will result in panic.
Allowed values are:
- nil
- string("")
- make(map[string]any,0)