const ( Cast = true // for clarity - e.g., mxj.NewMapXml(doc, mxj.Cast) SafeEncoding = true // ditto - e.g., mv.Json(mxj.SafeEncoding) )
const (
DefaultElementTag = "element"
)
const (
DefaultRootTag = "doc"
)
const ( NoAttributes = true // suppress LeafNode values that are attributes )
CustomDecoder can be used to specify xml.Decoder attribute values, e.g., Strict:false, to be used. By default CustomDecoder is nil. If CustomeDecoder != nil, then mxj.XmlCharsetReader variable is ignored and must be set as part of the CustomDecoder value, if needed.
Usage: mxj.CustomDecoder = &xml.Decoder{Strict:false}
var CustomDecoder *xml.Decoder
Decode numericvalues as json.Number type Map values - see encoding/json#Number. NOTE: this is for decoding JSON into a Map with NewMapJson(), NewMapJsonReader(), etc.; it does not affect NewMapXml(), etc. The XML encoders mv.Xml() and mv.XmlIndent() do recognize json.Number types; a JSON object can be decoded to a Map with json.Number value types and the resulting Map can be correctly encoded into a XML object.
var JsonUseNumber bool
var KeyNotExistError = errors.New("Key does not exist")
var NO_ROOT = NoRoot // maintain backwards compatibility
NoRoot is returned by NewXmlSeq, etc., when a comment, directive or procinstr element is parsed in the XML data stream and the element is not contained in an XML object with a root element.
var NoRoot = errors.New("no root key")
var PathNotExistError = errors.New("Path does not exist")
If XmlCharsetReader != nil, it will be used to decode the XML, if required. Note: if CustomDecoder != nil, then XmlCharsetReader is ignored; set the CustomDecoder attribute instead.
import ( charset "code.google.com/p/go-charset/charset" github.com/clbanning/mxj ) ... mxj.XmlCharsetReader = charset.NewReader m, merr := mxj.NewMapXml(xmlValue)
var XmlCharsetReader func(charset string, input io.Reader) (io.Reader, error)
func AnyXml(v interface{}, tags ...string) ([]byte, error)
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" "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>
An extreme example is available in examples/goofy_map.go.
Alternative values for DefaultRootTag and DefaultElementTag can be set as: AnyXml( v, myRootTag, myElementTag).
func AnyXmlIndent(v interface{}, prefix, indent string, tags ...string) ([]byte, error)
Encode an arbitrary value as a pretty XML string. Alternative values for DefaultRootTag and DefaultElementTag can be set as: AnyXmlIndent( v, "", " ", myRootTag, myElementTag).
func BeautifyXml(b []byte, prefix, indent string) ([]byte, error)
BeautifyXml (re)formats an XML doc similar to Map.XmlIndent(). It preserves comments, directives and process instructions,
func CastNanInf(b ...bool)
Cast "Nan", "Inf", "-Inf" XML values to 'float64'. By default, these values will be decoded as 'string'.
func CastValuesToBool(b ...bool)
CastValuesToBool can be used to skip casting to bool when "cast" argument is 'true' in NewMapXml, etc. Default is true.
func CastValuesToFloat(b ...bool)
CastValuesToFloat can be used to skip casting to float64 when "cast" argument is 'true' in NewMapXml, etc. Default is true.
func CastValuesToInt(b ...bool)
CastValuesToInt tries to coerce numeric valus to int64 or uint64 instead of the default float64. Repeated calls with no argument will toggle this on/off, or this handling will be set with the value of 'b'.
func CoerceKeysToLower(b ...bool)
Coerce all tag values to keys in lower case. This is useful if you've got sources with variable tag capitalization, and you want to use m.ValuesForKeys(), etc., with the key or path spec in lower case.
CoerceKeysToLower() will toggle the coercion flag true|false - on|off CoerceKeysToLower(true|false) will set the coercion flag on|off NOTE: only recognized by NewMapXml, NewMapXmlReader, and NewMapXmlReaderRaw functions as well as the associated HandleXmlReader and HandleXmlReaderRaw.
func CoerceKeysToSnakeCase(b ...bool)
CoerceKeysToSnakeCase changes the default, false, to the specified value, b. Note: the attribute prefix will be a hyphen, '-', or what ever string value has been specified using SetAttrPrefix.
func DecodeSimpleValuesAsMap(b ...bool)
DecodeSimpleValuesAsMap forces all values to be decoded as map["#text":<value>]. If called with no argument, the decoding is toggled on/off.
By default the NewMapXml functions decode simple values without attributes as map[<tag>:<value>]. This function causes simple values without attributes to be decoded the same as simple values with attributes - map[<tag>:map["#text":<value>]].
func DisableTrimWhiteSpace(b ...bool)
DisableTrimWhiteSpace set if the white space should be trimmed or not. By default white space is always trimmed. If no argument is provided, trim white space will be disabled.
func HandleJsonReader(jsonReader io.Reader, mapHandler func(Map) bool, errHandler func(error) bool) error
Bulk process JSON using handlers that process a Map value.
'rdr' is an io.Reader for the JSON (stream). 'mapHandler' is the Map processing handler. Return of 'false' stops io.Reader processing. 'errHandler' is the error processor. Return of 'false' stops io.Reader processing and returns the error. Note: mapHandler() and errHandler() calls are blocking, so reading and processing of messages is serialized. This means that you can stop reading the file on error or after processing a particular message. To have reading and handling run concurrently, pass argument to a go routine in handler and return 'true'.
▹ Example
func HandleJsonReaderRaw(jsonReader io.Reader, mapHandler func(Map, []byte) bool, errHandler func(error, []byte) bool) error
Bulk process JSON using handlers that process a Map value and the raw JSON.
'rdr' is an io.Reader for the JSON (stream). 'mapHandler' is the Map and raw JSON - []byte - processor. Return of 'false' stops io.Reader processing. 'errHandler' is the error and raw JSON processor. Return of 'false' stops io.Reader processing and returns the error. Note: mapHandler() and errHandler() calls are blocking, so reading and processing of messages is serialized. This means that you can stop reading the file on error or after processing a particular message. To have reading and handling run concurrently, pass argument(s) to a go routine in handler and return 'true'.
▹ Example
func HandleXMPPStreamTag(b ...bool)
HandleXMPPStreamTag causes decoder to parse XMPP <stream:stream> elements. If called with no argument, XMPP stream element handling is toggled on/off. (See xmppStream_test.go for example.)
If called with NewMapXml, NewMapXmlReader, New MapXmlReaderRaw the "stream" element will be returned as: map["stream"]interface{}{map[-<attrs>]interface{}}. If called with NewMapSeq, NewMapSeqReader, NewMapSeqReaderRaw the "stream" element will be returned as: map["stream:stream"]interface{}{map["#attr"]interface{}{map[string]interface{}}} where the "#attr" values have "#text" and "#seq" keys. (See NewMapXmlSeq.)
func HandleXmlReader(xmlReader io.Reader, mapHandler func(Map) bool, errHandler func(error) bool) error
Bulk process XML using handlers that process a Map value.
'rdr' is an io.Reader for XML (stream) 'mapHandler' is the Map processor. Return of 'false' stops io.Reader processing. 'errHandler' is the error processor. Return of 'false' stops io.Reader processing and returns the error. Note: mapHandler() and errHandler() calls are blocking, so reading and processing of messages is serialized. This means that you can stop reading the file on error or after processing a particular message. To have reading and handling run concurrently, pass argument to a go routine in handler and return 'true'.
▹ Example
func HandleXmlReaderRaw(xmlReader io.Reader, mapHandler func(Map, []byte) bool, errHandler func(error, []byte) bool) error
Bulk process XML using handlers that process a Map value and the raw XML.
'rdr' is an io.Reader for XML (stream) 'mapHandler' is the Map and raw XML - []byte - processor. Return of 'false' stops io.Reader processing. 'errHandler' is the error and raw XML processor. Return of 'false' stops io.Reader processing and returns the error. Note: mapHandler() and errHandler() calls are blocking, so reading and processing of messages is serialized. This means that you can stop reading the file on error or after processing a particular message. To have reading and handling run concurrently, pass argument(s) to a go routine in handler and return 'true'. See NewMapXmlReaderRaw for comment on performance associated with retrieving raw XML from a Reader.
▹ Example
func IncludeTagSeqNum(b ...bool)
IncludeTagSeqNum - include a "_seq":N key:value pair with each inner tag, denoting its position when parsed. This is of limited usefulness, since list values cannot be tagged with "_seq" without changing their depth in the Map. So THIS SHOULD BE USED WITH CAUTION - see the test cases. Here's a sample of what you get.
<Obj c="la" x="dee" h="da"> <IntObj id="3"/> <IntObj1 id="1"/> <IntObj id="2"/> <StrObj>hello</StrObj> </Obj> parses as: { Obj:{ "-c":"la", "-h":"da", "-x":"dee", "intObj":[ { "-id"="3", "_seq":"0" // if mxj.Cast is passed, then: "_seq":0 }, { "-id"="2", "_seq":"2" }], "intObj1":{ "-id":"1", "_seq":"1" }, "StrObj":{ "#text":"hello", // simple element value gets "#text" tag "_seq":"3" } } }
func LeafUseDotNotation(b ...bool)
LeafUseDotNotation sets a flag that list members in LeafNode paths should be identified using ".N" syntax rather than the default "[N]" syntax. Calling LeafUseDotNotation with no arguments toggles the flag on/off; otherwise, the argument sets the flag value 'true'/'false'.
func PrependAttrWithHyphen(v bool)
PrependAttrWithHyphen. Prepend attribute tags with a hyphen. Default is 'true'. (Not applicable to NewMapXmlSeq(), mv.XmlSeq(), etc.)
Note: If 'false', unmarshaling and marshaling is not symmetric. Attributes will be marshal'd as <attr_tag>attr</attr_tag> and may be part of a list.
func SetArraySize(size int) int
SetArraySize adjust the buffers for expected number of values to return from ValuesForKey() and ValuesForPath(). This can have the effect of significantly reducing memory allocation-copy functions for large data sets. Returns the initial buffer size.
func SetAttrPrefix(s string)
SetAttrPrefix changes the default, "-", to the specified value, s. SetAttrPrefix("") is the same as PrependAttrWithHyphen(false). (Not applicable for NewMapXmlSeq(), mv.XmlSeq(), etc.)
func SetCheckTagToSkipFunc(fn func(string) bool)
SetCheckTagToSkipFunc registers function to test whether the value for a tag should be cast to bool or float64 when "cast" argument is 'true'. (Dot tag path notation is not supported.) NOTE: key may be "#text" if it's a simple element with attributes
or "decodeSimpleValuesAsMap == true".
NOTE: does not apply to NewMapXmlSeq... functions.
func SetFieldSeparator(s ...string)
SetFieldSeparator changes the default field separator, ":", for the newVal argument in mv.UpdateValuesForPath and the optional 'subkey' arguments in mv.ValuesForKey and mv.ValuesForPath.
E.g., if the newVal value is "http://blah/blah", setting the field separator to "|" will allow the newVal specification, "<key>|http://blah/blah" to parse properly. If called with no argument or an empty string value, the field separator is set to the default, ":".
func SetGlobalKeyMapPrefix(s string)
func XMLEscapeChars(b ...bool)
XMLEscapeChars(true) forces escaping invalid characters in attribute and element values. NOTE: this is brute force with NO interrogation of '&' being escaped already; if it is then '&' will be re-escaped as '&amp;'.
The values are: " " ' ' < < > > & &
Note: if XMLEscapeCharsDecoder(true) has been called - or the default, 'false,' value has been toggled to 'true' - then XMLEscapeChars(true) is ignored. If XMLEscapeChars(true) has already been called before XMLEscapeCharsDecoder(true), XMLEscapeChars(false) is called to turn escape encoding on mv.Xml, etc., to prevent double escaping ampersands, '&'.
func XMLEscapeCharsDecoder(b ...bool)
XMLEscapeCharsDecoder(b ...bool) escapes XML characters in xml.CharData values returned by Decoder.Token. Thus, the internal Map values will contain escaped values, and you do not need to set XMLEscapeChars for proper encoding.
By default, the Map values have the non-escaped values returned by Decoder.Token. XMLEscapeCharsDecoder(true) - or, XMLEscapeCharsDecoder() - will toggle escape encoding 'on.'
Note: if XMLEscapeCharDecoder(true) is call then XMLEscapeChars(false) is called to prevent re-escaping the values on encoding using mv.Xml, etc.
func XmlCheckIsValid(b ...bool)
XmlCheckIsValid forces the encoded XML to be checked for validity.
func XmlDefaultEmptyElemSyntax()
XmlDefaultEmptyElemSyntax() - <tag .../> rather than <tag ...></tag>. Return XML encoding for empty elements to the default package setting. Reverses effect of XmlGoEmptyElemSyntax().
func XmlGoEmptyElemSyntax()
XmlGoEmptyElemSyntax() - <tag ...></tag> rather than <tag .../>.
Go's encoding/xml package marshals empty XML elements as <tag ...></tag>. By default this package encodes empty elements as <tag .../>. If you're marshaling Map values that include structures (which are passed to xml.Marshal for encoding), this will let you conform to the standard package.
LeafNode - a terminal path value in a Map. For XML Map values it represents an attribute or simple element value - of type string unless Map was created using Cast flag. For JSON Map values it represents a string, numeric, boolean, or null value.
type LeafNode struct { Path string // a dot-notation representation of the path with array subscripting Value interface{} // the value at the path termination }
type Map map[string]interface{}
func New() Map
Allocate a Map.
func NewMapGob(gobj []byte) (Map, error)
NewMapGob returns a Map value for a gob object that has been encoded from a map[string]interface{} (or compatible type) value. It is intended to provide symmetric handling of Maps that have been encoded using mv.Gob.
func NewMapJson(jsonVal []byte) (Map, error)
Just a wrapper on json.Unmarshal
Converting JSON to XML is a simple as: ... mapVal, merr := mxj.NewMapJson(jsonVal) if merr != nil { // handle error } xmlVal, xerr := mapVal.Xml() if xerr != nil { // handle error }
NOTE: as a special case, passing a list, e.g., [{"some-null-value":"", "a-non-null-value":"bar"}], will be interpreted as having the root key 'object' prepended - {"object":[ ... ]} - to unmarshal to a Map. See mxj/j2x/j2x_test.go.
func NewMapJsonReader(jsonReader io.Reader) (Map, error)
Retrieve a Map value from an io.Reader.
NOTE: The raw JSON off the reader is buffered to []byte using a ByteReader. If the io.Reader is an os.File, there may be significant performance impact. If the io.Reader is wrapping a []byte value in-memory, however, such as http.Request.Body you CAN use it to efficiently unmarshal a JSON object.
func NewMapJsonReaderRaw(jsonReader io.Reader) (Map, []byte, error)
Retrieve a Map value and raw JSON - []byte - from an io.Reader.
NOTE: The raw JSON off the reader is buffered to []byte using a ByteReader. If the io.Reader is an os.File, there may be significant performance impact. If the io.Reader is wrapping a []byte value in-memory, however, such as http.Request.Body you CAN use it to efficiently unmarshal a JSON object and retrieve the raw JSON in a single call.
func NewMapStruct(structVal interface{}) (Map, error)
DEPRECATED - import github.com/fatih/structs and cast result of structs.Map to mxj.Map.
import "github.com/fatih/structs" ... sm, err := structs.Map(<some struct>) if err != nil { // handle error } m := mxj.Map(sm)
Alernatively uncomment the old source and import in struct.go.
func NewMapXml(xmlVal []byte, cast ...bool) (Map, error)
NewMapXml - convert a XML doc into a Map (This is analogous to unmarshalling a JSON string to map[string]interface{} using json.Unmarshal().)
If the optional argument 'cast' is 'true', then values will be converted to boolean or float64 if possible. Converting XML to JSON is a simple as: ... mapVal, merr := mxj.NewMapXml(xmlVal) if merr != nil { // handle error } jsonVal, jerr := mapVal.Json() if jerr != nil { // handle error } NOTES: 1. Declarations, directives, process instructions and comments are NOT parsed. 2. The 'xmlVal' will be parsed looking for an xml.StartElement, so BOM and other extraneous xml.CharData will be ignored unless io.EOF is reached first. 3. If CoerceKeysToLower() has been called, then all key values will be lower case. 4. If CoerceKeysToSnakeCase() has been called, then all key values will be converted to snake case. 5. If DisableTrimWhiteSpace(b bool) has been called, then all values will be trimmed or not. 'true' by default.
func NewMapXmlReader(xmlReader io.Reader, cast ...bool) (Map, error)
Get next XML doc from an io.Reader as a Map value. Returns Map value.
NOTES: 1. Declarations, directives, process instructions and comments are NOT parsed. 2. The 'xmlReader' will be parsed looking for an xml.StartElement, so BOM and other extraneous xml.CharData will be ignored unless io.EOF is reached first. 3. If CoerceKeysToLower() has been called, then all key values will be lower case. 4. If CoerceKeysToSnakeCase() has been called, then all key values will be converted to snake case.
func NewMapXmlReaderRaw(xmlReader io.Reader, cast ...bool) (Map, []byte, error)
Get next XML doc from an io.Reader as a Map value. Returns Map value and slice with the raw XML.
NOTES: 1. Declarations, directives, process instructions and comments are NOT parsed. 2. Due to the implementation of xml.Decoder, the raw XML off the reader is buffered to []byte using a ByteReader. If the io.Reader is an os.File, there may be significant performance impact. See the examples - getmetrics1.go through getmetrics4.go - for comparative use cases on a large data set. If the io.Reader is wrapping a []byte value in-memory, however, such as http.Request.Body you CAN use it to efficiently unmarshal a XML doc and retrieve the raw XML in a single call. 3. The 'raw' return value may be larger than the XML text value. 4. The 'xmlReader' will be parsed looking for an xml.StartElement, so BOM and other extraneous xml.CharData will be ignored unless io.EOF is reached first. 5. If CoerceKeysToLower() has been called, then all key values will be lower case. 6. If CoerceKeysToSnakeCase() has been called, then all key values will be converted to snake case.
func (mv Map) Attributes(path string) ([]string, error)
If the path is an element with attributes, return a list of the attribute keys. (The list is alphabeticly sorted.) NOTE: Map keys that are not prefixed with '-', a hyphen, are not treated as attributes; see m.Elements(path). Also, if the attribute prefix is "" - SetAttrPrefix("") or PrependAttrWithHyphen(false) - then there are no identifiable attributes.
func (mv Map) Copy() (Map, error)
Return a copy of mv as a newly allocated Map. If the Map only contains string, numeric, map[string]interface{}, and []interface{} values, then it can be thought of as a "deep copy." Copying a structure (or structure reference) value is subject to the noted restrictions.
NOTE: If 'mv' includes structure values with, possibly, JSON encoding tags then only public fields of the structure are in the new Map - and with keys that conform to any encoding tag instructions. The structure itself will be represented as a map[string]interface{} value.
▹ Example
func (mv Map) Elements(path string) ([]string, error)
If the path is an element with sub-elements, return a list of the sub-element keys. (The list is alphabeticly sorted.) NOTE: Map keys that are prefixed with '-', a hyphen, are considered attributes; see m.Attributes(path).
func (mv Map) Exists(path string, subkeys ...string) (bool, error)
Checks whether the path exists. If err != nil then 'false' is returned along with the error encountered parsing either the "path" or "subkeys" argument.
func (mv Map) Gob() ([]byte, error)
Gob returns a gob-encoded value for the Map 'mv'.
func (mv Map) Json(safeEncoding ...bool) ([]byte, error)
Just a wrapper on json.Marshal. If option safeEncoding is'true' then safe encoding of '<', '>' and '&' is preserved. (see encoding/json#Marshal, encoding/json#Encode)
func (mv Map) JsonIndent(prefix, indent string, safeEncoding ...bool) ([]byte, error)
Just a wrapper on json.MarshalIndent. If option safeEncoding is'true' then safe encoding of '<' , '>' and '&' is preserved. (see encoding/json#Marshal, encoding/json#Encode)
func (mv Map) JsonIndentWriter(jsonWriter io.Writer, prefix, indent string, safeEncoding ...bool) error
Writes the Map as pretty JSON on the Writer. If 'safeEncoding' is 'true', then "safe" encoding of '<', '>' and '&' is preserved.
func (mv Map) JsonIndentWriterRaw(jsonWriter io.Writer, prefix, indent string, safeEncoding ...bool) ([]byte, error)
Writes the Map as pretty JSON on the Writer. []byte is the raw JSON that was written. If 'safeEncoding' is 'true', then "safe" encoding of '<', '>' and '&' is preserved.
func (mv Map) JsonWriter(jsonWriter io.Writer, safeEncoding ...bool) error
Writes the Map as JSON on the Writer. If 'safeEncoding' is 'true', then "safe" encoding of '<', '>' and '&' is preserved.
func (mv Map) JsonWriterRaw(jsonWriter io.Writer, safeEncoding ...bool) ([]byte, error)
Writes the Map as JSON on the Writer. []byte is the raw JSON that was written. If 'safeEncoding' is 'true', then "safe" encoding of '<', '>' and '&' is preserved.
func (mv Map) LeafNodes(no_attr ...bool) []LeafNode
LeafNodes - returns an array of all LeafNode values for the Map. The option no_attr argument suppresses attribute values (keys with prepended hyphen, '-') as well as the "#text" key for the associated simple element value.
PrependAttrWithHypen(false) will result in attributes having .attr-name as terminal node in 'path' while the path for the element value, itself, will be the base path w/o "#text".
LeafUseDotNotation(true) causes list members to be identified using ".N" syntax rather than "[N]" syntax.
func (mv Map) LeafPaths(no_attr ...bool) []string
LeafPaths - all paths that terminate in LeafNode values.
func (mv Map) LeafValues(no_attr ...bool) []interface{}
LeafValues - all terminal values in the Map.
func (mv Map) NewMap(keypairs ...string) (Map, error)
(Map)NewMap - create a new Map from data in the current Map.
'keypairs' are key mappings "oldKey:newKey" and specify that the current value of 'oldKey' should be the value for 'newKey' in the returned Map. - 'oldKey' supports dot-notation as described for (Map)ValuesForPath() - 'newKey' supports dot-notation but with no wildcards, '*', or indexed arrays - "oldKey" is shorthand for the keypair value "oldKey:oldKey" - "oldKey:" and ":newKey" are invalid keypair values - if 'oldKey' does not exist in the current Map, it is not written to the new Map. "null" is not supported unless it is the current Map. - see newmap_test.go for several syntax examples - mv.NewMap() == mxj.New() NOTE: "examples/partial.go" shows how to create arbitrary sub-docs of an XML doc.
func (mv Map) Old() map[string]interface{}
Cast a Map to map[string]interface{}
func (mv Map) PathForKeyShortest(key string) string
PathForKeyShortest extracts the shortest path from all possible paths - from PathsForKey() - in Map, 'mv'.. Paths are strings using dot-notation.
func (mv Map) PathsForKey(key string) []string
PathsForKey returns all paths through Map, 'mv', (in dot-notation) that terminate with the specified key. Results can be used with ValuesForPath.
func (mv Map) Remove(path string) error
Removes the path.
func (mv Map) RenameKey(path string, newName string) error
RenameKey renames a key in a Map. It works only for nested maps. It doesn't work for cases when the key is in a list.
func (mv Map) Root() (string, error)
Return the root element of the Map. If there is not a single key in Map, then an error is returned.
func (mv Map) SetValueForPath(value interface{}, path string) error
Sets the value for the path
func (mv Map) StringIndent(offset ...int) string
Pretty print a Map.
func (mv Map) StringIndentNoTypeInfo(offset ...int) string
Pretty print a Map without the value type information - just key:value entries.
func (mv Map) Struct(structPtr interface{}) error
Marshal a map[string]interface{} into a structure referenced by 'structPtr'. Error returned if argument is not a pointer or if json.Unmarshal returns an error.
json.Unmarshal structure encoding rules are followed to encode public structure fields.
▹ Example
func (mv Map) UpdateValuesForPath(newVal interface{}, path string, subkeys ...string) (int, error)
Update value based on path and possible sub-key values. A count of the number of values changed and any error are returned. If the count == 0, then no path (and subkeys) matched.
'newVal' can be a Map or map[string]interface{} value with a single 'key' that is the key to be modified or a string value "key:value[:type]" where type is "bool" or "num" to cast the value. 'path' is dot-notation list of keys to traverse; last key in path can be newVal key NOTE: 'path' spec does not currently support indexed array references. 'subkeys' are "key:value[:type]" entries that must match for path node - For attributes prefix the label with the attribute prefix character, by default a hyphen, '-', e.g., "-seq:3". (See SetAttrPrefix function.) - The subkey can be wildcarded - "key:*" - to require that it's there with some value. - If a subkey is preceeded with the '!' character, the key:value[:type] entry is treated as an exclusion critera - e.g., "!author:William T. Gaddis". NOTES: 1. Simple elements with attributes need a path terminated as ".#text" to modify the actual value. 2. Values in Maps created using NewMapXmlSeq are map[string]interface{} values with a "#text" key. 3. If values in 'newVal' or 'subkeys' args contain ":", use SetFieldSeparator to an unused symbol, perhaps "|".
▹ Example
func (mv Map) ValueForKey(key string, subkeys ...string) (interface{}, error)
ValueForKey is a wrapper on ValuesForKey. It returns the first member of []interface{}, if any. If there is no value, "nil, nil" is returned.
func (mv Map) ValueForPath(path string) (interface{}, error)
ValueForPath wraps ValuesFor Path and returns the first value returned. If no value is found it returns 'nil' and PathNotExistError.
func (mv Map) ValueForPathString(path string) (string, error)
ValuesForPathString returns the first found value for the path as a string.
func (mv Map) ValueOrEmptyForPathString(path string) string
ValueOrEmptyForPathString returns the first found value for the path as a string. If the path is not found then it returns an empty string.
func (mv Map) ValuesForKey(key string, subkeys ...string) ([]interface{}, error)
ValuesForKey return all values in Map, 'mv', associated with a 'key'. If len(returned_values) == 0, then no match. On error, the returned slice is 'nil'. NOTE: 'key' can be wildcard, "*".
'subkeys' (optional) are "key:val[:type]" strings representing attributes or elements in a list. - By default 'val' is of type string. "key:val:bool" and "key:val:float" to coerce them. - For attributes prefix the label with the attribute prefix character, by default a hyphen, '-', e.g., "-seq:3". (See SetAttrPrefix function.) - If the 'key' refers to a list, then "key:value" could select a list member of the list. - The subkey can be wildcarded - "key:*" - to require that it's there with some value. - If a subkey is preceeded with the '!' character, the key:value[:type] entry is treated as an exclusion critera - e.g., "!author:William T. Gaddis". - If val contains ":" symbol, use SetFieldSeparator to a unused symbol, perhaps "|".
func (mv Map) ValuesForPath(path string, subkeys ...string) ([]interface{}, error)
ValuesForPatb retrieves all values for a path from the Map. If len(returned_values) == 0, then no match. On error, the returned array is 'nil'.
'path' is a dot-separated path of key values. - If a node in the path is '*', then everything beyond is walked. - 'path' can contain indexed array references, such as, "*.data[1]" and "msgs[2].data[0].field" - even "*[2].*[0].field". 'subkeys' (optional) are "key:val[:type]" strings representing attributes or elements in a list. - By default 'val' is of type string. "key:val:bool" and "key:val:float" to coerce them. - For attributes prefix the label with the attribute prefix character, by default a hyphen, '-', e.g., "-seq:3". (See SetAttrPrefix function.) - If the 'path' refers to a list, then "tag:value" would return member of the list. - The subkey can be wildcarded - "key:*" - to require that it's there with some value. - If a subkey is preceeded with the '!' character, the key:value[:type] entry is treated as an exclusion critera - e.g., "!author:William T. Gaddis". - If val contains ":" symbol, use SetFieldSeparator to a unused symbol, perhaps "|".
▹ Example
func (mv Map) Xml(rootTag ...string) ([]byte, error)
Encode a Map as XML. The companion of NewMapXml(). The following rules apply.
The attributes tag=value pairs are alphabetized by "tag". Also, when encoding map[string]interface{} values - complex elements, etc. - the key:value pairs are alphabetized by key so the resulting tags will appear sorted.
func (mv Map) XmlIndent(prefix, indent string, rootTag ...string) ([]byte, error)
Encode a map[string]interface{} as a pretty XML string. See Xml for encoding rules.
func (mv Map) XmlIndentWriter(xmlWriter io.Writer, prefix, indent string, rootTag ...string) error
Writes the Map as pretty XML on the Writer. See Xml() for encoding rules.
func (mv Map) XmlWriter(xmlWriter io.Writer, rootTag ...string) error
Writes the Map as XML on the Writer. See Xml() for encoding rules.
type MapRaw struct { M Map R []byte }
func NewMapsFromJsonFileRaw(name string) ([]MapRaw, error)
ReadMapsFromJsonFileRaw - creates an array of MapRaw from a file of JSON values.
func NewMapsFromXmlFileRaw(name string) ([]MapRaw, error)
NewMapsFromXmlFileRaw - creates an array of MapRaw from a file of XML values. NOTE: the slice with the raw XML is clean with no extra capacity - unlike NewMapXmlReaderRaw(). It is slow at parsing a file from disk and is intended for relatively small utility files.
MapSeq is like Map but contains seqencing indices to allow recovering the original order of the XML elements when the map[string]interface{} is marshaled. Element attributes are stored as a map["#attr"]map[<attr_key>]map[string]interface{}{"#text":"<value>", "#seq":<attr_index>} value instead of denoting the keys with a prefix character. Also, comments, directives and process instructions are preserved.
type MapSeq map[string]interface{}
func NewMapFormattedXmlSeq(xmlVal []byte, cast ...bool) (MapSeq, error)
NewMapFormattedXmlSeq performs the same as NewMapXmlSeq but is useful for processing XML objects that are formatted using the whitespace character, " ". (The stdlib xml.Decoder, by default, treats all whitespace as significant; Decoder.Token() and Decoder.RawToken() will return strings of one or more whitespace characters and without alphanumeric or punctuation characters as xml.CharData values.)
If you're processing such XML, then this will convert all occurrences of whitespace-only strings into an empty string, "", prior to parsing the XML - irrespective of whether the occurrence is formatting or is a actual element value.
func NewMapXmlSeq(xmlVal []byte, cast ...bool) (MapSeq, error)
NewMapXmlSeq converts a XML doc into a MapSeq value with elements id'd with decoding sequence key represented as map["#seq"]<int value>. If the optional argument 'cast' is 'true', then values will be converted to boolean or float64 if possible. NOTE: "#seq" key/value pairs are removed on encoding with msv.Xml() / msv.XmlIndent().
attributes are a map - map["#attr"]map["attr_key"]map[string]interface{}{"#text":<aval>, "#seq":<num>}
all simple elements are decoded as map["#text"]interface{} with a "#seq" k:v pair, as well.
lists always decode as map["list_tag"][]map[string]interface{} where the array elements are maps that include a "#seq" k:v pair based on sequence they are decoded. Thus, XML like: <doc> <ltag>value 1</ltag> <newtag>value 2</newtag> <ltag>value 3</ltag> </doc> is decoded as: doc : ltag :[[]interface{}] [item: 0] #seq :[int] 0 #text :[string] value 1 [item: 1] #seq :[int] 2 #text :[string] value 3 newtag : #seq :[int] 1 #text :[string] value 2 It will encode in proper sequence even though the MapSeq representation merges all "ltag" elements in an array.
comments - "<!--comment-->" - are decoded as map["#comment"]map["#text"]"cmnt_text" with a "#seq" k:v pair.
directives - "<!text>" - are decoded as map["#directive"]map[#text"]"directive_text" with a "#seq" k:v pair.
process instructions - "<?instr?>" - are decoded as map["#procinst"]interface{} where the #procinst value is of map[string]interface{} type with the following keys: #target, #inst, and #seq.
comments, directives, and procinsts that are NOT part of a document with a root key will be returned as map[string]interface{} and the error value 'NoRoot'.
note: "<![CDATA[" syntax is lost in xml.Decode parser - and is not handled here, either. and: "\r\n" is converted to "\n"
NOTES: 1. The 'xmlVal' will be parsed looking for an xml.StartElement, xml.Comment, etc., so BOM and other extraneous xml.CharData will be ignored unless io.EOF is reached first. 2. CoerceKeysToLower() is NOT recognized, since the intent here is to eventually call m.XmlSeq() to re-encode the message in its original structure. 3. If CoerceKeysToSnakeCase() has been called, then all key values will be converted to snake case.
NAME SPACES: 1. Keys in the MapSeq value that are parsed from a <name space prefix>:<local name> tag preserve the "<prefix>:" notation rather than stripping it as with NewMapXml(). 2. Attribute keys for name space prefix declarations preserve "xmlns:<prefix>" notation.
ERRORS: 1. If a NoRoot error, "no root key," is returned, check the initial map key for a "#comment", "#directive" or #procinst" key. 2. Unmarshaling an XML doc that is formatted using the whitespace character, " ", will error, since Decoder.RawToken treats such occurances as significant. See NewMapFormattedXmlSeq().
func NewMapXmlSeqReader(xmlReader io.Reader, cast ...bool) (MapSeq, error)
NewMpaXmlSeqReader returns next XML doc from an io.Reader as a MapSeq value.
NOTES: 1. The 'xmlReader' will be parsed looking for an xml.StartElement, xml.Comment, etc., so BOM and other extraneous xml.CharData will be ignored unless io.EOF is reached first. 2. CoerceKeysToLower() is NOT recognized, since the intent here is to eventually call m.XmlSeq() to re-encode the message in its original structure. 3. If CoerceKeysToSnakeCase() has been called, then all key values will be converted to snake case. ERRORS: 1. If a NoRoot error, "no root key," is returned, check the initial map key for a "#comment", "#directive" or #procinst" key.
func NewMapXmlSeqReaderRaw(xmlReader io.Reader, cast ...bool) (MapSeq, []byte, error)
NewMapXmlSeqReaderRaw returns the next XML doc from an io.Reader as a MapSeq value. Returns MapSeq value, slice with the raw XML, and any error.
NOTES: 1. Due to the implementation of xml.Decoder, the raw XML off the reader is buffered to []byte using a ByteReader. If the io.Reader is an os.File, there may be significant performance impact. See the examples - getmetrics1.go through getmetrics4.go - for comparative use cases on a large data set. If the io.Reader is wrapping a []byte value in-memory, however, such as http.Request.Body you CAN use it to efficiently unmarshal a XML doc and retrieve the raw XML in a single call. 2. The 'raw' return value may be larger than the XML text value. 3. The 'xmlReader' will be parsed looking for an xml.StartElement, xml.Comment, etc., so BOM and other extraneous xml.CharData will be ignored unless io.EOF is reached first. 4. CoerceKeysToLower() is NOT recognized, since the intent here is to eventually call m.XmlSeq() to re-encode the message in its original structure. 5. If CoerceKeysToSnakeCase() has been called, then all key values will be converted to snake case. ERRORS: 1. If a NoRoot error, "no root key," is returned, check if the initial map key is "#comment", "#directive" or #procinst" key.
func (msv MapSeq) StringIndent(offset ...int) string
Pretty print a Map.
func (msv MapSeq) StringIndentNoTypeInfo(offset ...int) string
Pretty print a Map without the value type information - just key:value entries.
func (mv MapSeq) Xml(rootTag ...string) ([]byte, error)
Xml encodes a MapSeq as XML with elements sorted on #seq. The companion of NewMapXmlSeq(). The following rules apply.
func (mv MapSeq) XmlIndent(prefix, indent string, rootTag ...string) ([]byte, error)
XmlIndent encodes a map[string]interface{} as a pretty XML string. See MapSeq.XmlSeq() for encoding rules.
func (mv MapSeq) XmlIndentWriter(xmlWriter io.Writer, prefix, indent string, rootTag ...string) error
XmlIndentWriter writes the MapSeq value as pretty XML on the Writer. See MapSeq.Xml() for encoding rules.
func (mv MapSeq) XmlWriter(xmlWriter io.Writer, rootTag ...string) error
XmlWriter Writes the MapSeq value as XML on the Writer. See MapSeq.Xml() for encoding rules.
type Maps []Map
func NewMaps() Maps
func NewMapsFromJsonFile(name string) (Maps, error)
NewMapsFromXmlFile - creates an array from a file of JSON values.
func NewMapsFromXmlFile(name string) (Maps, error)
NewMapsFromXmlFile - creates an array from a file of XML values.
func (mvs Maps) JsonFile(file string, safeEncoding ...bool) error
JsonFile - write Maps to named file as JSON Note: the file will be created, if necessary; if it exists it will be truncated. If you need to append to a file, open it and use JsonWriter method.
func (mvs Maps) JsonFileIndent(file, prefix, indent string, safeEncoding ...bool) error
JsonFileIndent - write Maps to named file as pretty JSON Note: the file will be created, if necessary; if it exists it will be truncated. If you need to append to a file, open it and use JsonIndentWriter method.
func (mvs Maps) JsonString(safeEncoding ...bool) (string, error)
JsonString - analogous to mv.Json()
func (mvs Maps) JsonStringIndent(prefix, indent string, safeEncoding ...bool) (string, error)
JsonStringIndent - analogous to mv.JsonIndent()
func (mvs Maps) XmlFile(file string) error
XmlFile - write Maps to named file as XML Note: the file will be created, if necessary; if it exists it will be truncated. If you need to append to a file, open it and use XmlWriter method.
func (mvs Maps) XmlFileIndent(file, prefix, indent string) error
XmlFileIndent - write Maps to named file as pretty XML Note: the file will be created,if necessary; if it exists it will be truncated. If you need to append to a file, open it and use XmlIndentWriter method.
func (mvs Maps) XmlString() (string, error)
XmlString - analogous to mv.Xml()
func (mvs Maps) XmlStringIndent(prefix, indent string) (string, error)
XmlStringIndent - analogous to mv.XmlIndent()
Name | Synopsis |
---|---|
.. | |
examples | |
j2x | j2x.go - For (mostly) backwards compatibility with legacy j2x package. |
x2j | x2j - For (mostly) backwards compatibility with legacy x2j package. |
x2j-wrapper | Unmarshal dynamic / arbitrary XML docs and extract values (using wildcards, if necessary). |