Documentation
¶
Overview ¶
Marshal/Unmarshal XML to/from JSON and map[string]interface{} values, and extract/modify values from maps by key or key-path, including wildcards.
mxj supplants the legacy x2j and j2x packages. If you want the old syntax, use mxj/x2j or mxj/j2x packages.
Note: this library was designed for processing ad hoc anonymous messages. Bulk processing large data sets may be much more efficiently performed using the encoding/xml or encoding/json packages from Go's standard library directly.
Note:
2014-08-02: AnyXml() and AnyXmlIndent() will try to marshal arbitrary values to XML.
SUMMARY
type Map map[string]interface{} Create a Map value, 'm', from any map[string]interface{} value, 'v': m := Map(v) Unmarshal / marshal XML as a Map value, 'm': m, err := NewMapXml(xmlValue) // unmarshal xmlValue, err := m.Xml() // marshal Unmarshal XML from an io.Reader as a Map value, 'm': m, err := NewMapReader(xmlReader) // repeated calls, as with an os.File Reader, will process stream m, raw, err := NewMapReaderRaw(xmlReader) // 'raw' is the raw XML that was decoded Marshal Map value, 'm', to an XML Writer (io.Writer): err := m.XmlWriter(xmlWriter) raw, err := m.XmlWriterRaw(xmlWriter) // 'raw' is the raw XML that was written on xmlWriter Also, for prettified output: xmlValue, err := m.XmlIndent(prefix, indent, ...) err := m.XmlIndentWriter(xmlWriter, prefix, indent, ...) raw, err := m.XmlIndentWriterRaw(xmlWriter, prefix, indent, ...) Bulk process XML with error handling (note: handlers must return a boolean value): err := HandleXmlReader(xmlReader, mapHandler(Map), errHandler(error)) err := HandleXmlReaderRaw(xmlReader, mapHandler(Map, []byte), errHandler(error, []byte)) Converting XML to JSON: see Examples for NewMapXml and HandleXmlReader. There are comparable functions and methods for JSON processing. Arbitrary structure values can be decoded to / encoded from Map values: m, err := NewMapStruct(structVal) err := m.Struct(structPointer) To work with XML tag values, JSON or Map key values or structure field values, decode the XML, JSON or structure to a Map value, 'm', or cast a map[string]interface{} value to a Map value, 'm', then: paths := m.PathsForKey(key) path := m.PathForKeyShortest(key) values, err := m.ValuesForKey(key, subkeys) values, err := m.ValuesForPath(path, subkeys) // 'path' can be dot-notation with wildcards and indexed arrays. count, err := m.UpdateValuesForPath(newVal, path, subkeys) Get everything at once, irrespective of path depth: leafnodes := m.LeafNodes() leafvalues := m.LeafValues() A new Map with whatever keys are desired can be created from the current Map and then encoded in XML or JSON. (Note: keys can use dot-notation. 'oldKey' can also use wildcards and indexed arrays.) newMap := m.NewMap("oldKey_1:newKey_1", "oldKey_2:newKey_2", ..., "oldKey_N:newKey_N") newXml := newMap.Xml() // for example newJson := newMap.Json() // ditto
XML PARSING CONVENTIONS
- Attributes are parsed to map[string]interface{} values by prefixing a hyphen, '-', to the attribute label. (PrependAttrWithHyphen(false) will override this.)
- If the element is a simple element and has attributes, the element value is given the key '#text' for its map[string]interface{} representation.
XML ENCODING CONVENTIONS
- 'nil' Map values, which may represent 'null' JSON values, are encoded as "<tag/>". NOTE: the operation is not symmetric as "<tag/>" elements are decoded as 'tag:""' Map values, which, then, encode in JSON as '"tag":""' values..
Index ¶
- Constants
- Variables
- func AnyXml(v interface{}, tags ...string) ([]byte, error)
- func AnyXmlIndent(v interface{}, prefix, indent string, tags ...string) ([]byte, error)
- func HandleJsonReader(jsonReader io.Reader, mapHandler func(Map) bool, errHandler func(error) bool) error
- func HandleJsonReaderRaw(jsonReader io.Reader, mapHandler func(Map, []byte) bool, ...) error
- func HandleXmlReader(xmlReader io.Reader, mapHandler func(Map) bool, errHandler func(error) bool) error
- func HandleXmlReaderRaw(xmlReader io.Reader, mapHandler func(Map, []byte) bool, ...) error
- func IncludeTagSeqNum(b bool)
- func PrependAttrWithHyphen(v bool)
- func SetArraySize(size int) int
- func XmlDefaultEmptyElemSyntax()
- func XmlGoEmptyElemSyntax()
- type LeafNode
- type Map
- func New() Map
- func NewMapJson(jsonVal []byte) (Map, error)
- func NewMapJsonReader(jsonReader io.Reader) (Map, error)
- func NewMapJsonReaderRaw(jsonReader io.Reader) (Map, []byte, error)
- func NewMapStruct(structVal interface{}) (Map, error)
- func NewMapXml(xmlVal []byte, cast ...bool) (Map, error)
- func NewMapXmlReader(xmlReader io.Reader, cast ...bool) (Map, error)
- func NewMapXmlReaderRaw(xmlReader io.Reader, cast ...bool) (Map, []byte, error)
- func (mv Map) Copy() (Map, error)
- func (mv Map) Exists(path string) bool
- func (mv Map) Json(safeEncoding ...bool) ([]byte, error)
- func (mv Map) JsonIndent(prefix, indent string, safeEncoding ...bool) ([]byte, error)
- func (mv Map) JsonIndentWriter(jsonWriter io.Writer, prefix, indent string, safeEncoding ...bool) error
- func (mv Map) JsonIndentWriterRaw(jsonWriter io.Writer, prefix, indent string, safeEncoding ...bool) ([]byte, error)
- func (mv Map) JsonWriter(jsonWriter io.Writer, safeEncoding ...bool) error
- func (mv Map) JsonWriterRaw(jsonWriter io.Writer, safeEncoding ...bool) ([]byte, error)
- func (mv Map) LeafNodes(no_attr ...bool) []LeafNode
- func (mv Map) LeafPaths(no_attr ...bool) []string
- func (mv Map) LeafValues(no_attr ...bool) []interface{}
- func (mv Map) NewMap(keypairs ...string) (Map, error)
- func (mv Map) Old() map[string]interface{}
- func (mv Map) PathForKeyShortest(key string) string
- func (mv Map) PathsForKey(key string) []string
- func (mv Map) Remove(path string) error
- func (mv Map) RenameKey(path string, newName string) error
- func (mv Map) SetValueForPath(value interface{}, path string) error
- func (mv Map) StringIndent(offset ...int) string
- func (mv Map) Struct(structPtr interface{}) error
- func (mv Map) UpdateValuesForPath(newVal interface{}, path string, subkeys ...string) (int, error)
- func (mv Map) ValueForPath(path string) (interface{}, error)
- func (mv Map) ValueForPathString(path string) (string, error)
- func (mv Map) ValueOrEmptyForPathString(path string) string
- func (mv Map) ValuesForKey(key string, subkeys ...string) ([]interface{}, error)
- func (mv Map) ValuesForPath(path string, subkeys ...string) ([]interface{}, error)
- func (mv Map) Xml(rootTag ...string) ([]byte, error)
- func (mv Map) XmlIndent(prefix, indent string, rootTag ...string) ([]byte, error)
- func (mv Map) XmlIndentWriter(xmlWriter io.Writer, prefix, indent string, rootTag ...string) error
- func (mv Map) XmlIndentWriterRaw(xmlWriter io.Writer, prefix, indent string, rootTag ...string) ([]byte, error)
- func (mv Map) XmlWriter(xmlWriter io.Writer, rootTag ...string) error
- func (mv Map) XmlWriterRaw(xmlWriter io.Writer, rootTag ...string) ([]byte, error)
- type MapRaw
- type Maps
- func (mvs Maps) JsonFile(file string, safeEncoding ...bool) error
- func (mvs Maps) JsonFileIndent(file, prefix, indent string, safeEncoding ...bool) error
- func (mvs Maps) JsonString(safeEncoding ...bool) (string, error)
- func (mvs Maps) JsonStringIndent(prefix, indent string, safeEncoding ...bool) (string, error)
- func (mvs Maps) XmlFile(file string) error
- func (mvs Maps) XmlFileIndent(file, prefix, indent string) error
- func (mvs Maps) XmlString() (string, error)
- func (mvs Maps) XmlStringIndent(prefix, indent string) (string, error)
Examples ¶
Constants ¶
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
)
Variables ¶
var JsonUseNumber bool
Parse numeric values as json.Number types - see encoding/json#Number
If XmlCharsetReader != nil, it will be used to decode the XML, if required.
import ( charset "code.google.com/p/go-charset/charset" github.com/clbanning/mxj ) ... mxj.XmlCharsetReader = charset.NewReader m, merr := mxj.NewMapXml(xmlValue)
var XmlWriterBufSize int = 256
XmlWriterBufSize - set the size of io.Writer for the TeeReader used by NewMapXmlReaderRaw() and HandleXmlReaderRaw(). This reduces repeated memory allocations and copy() calls in most cases.
Functions ¶
func AnyXml ¶
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>
Alternative values for DefaultRootTag and DefaultElementTag can be set as: AnyXmlIndent( v, myRootTag, myElementTag).
func AnyXmlIndent ¶
Encode an arbitrary value as a pretty XML string. Alternative values for DefaultRootTag and DefaultElementTag can be set as: AnyXmlIndent( v, "", " ", myRootTag, myElementTag).
func HandleJsonReader ¶
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 ¶
package main import () func main() { /* See: bulk_test.go for working example. Run "go test" in package directory then scroll back to find output. Basic logic for bulk JSON to XML processing is similar to that for bulk XML to JSON processing as outlined in the HandleXmlReader example. The test case is also a good example. */ }
Output:
func HandleJsonReaderRaw ¶
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 ¶
package main import () func main() { /* See: bulkraw_test.go for working example. Run "go test" in package directory then scroll back to find output. Basic logic for bulk JSON to XML processing is similar to that for bulk XML to JSON processing as outlined in the HandleXmlReader example. The test case is also a good example. */ }
Output:
func HandleXmlReader ¶
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 ¶
package main import () func main() { /* Bulk processing XML to JSON seems to be a common requirement. See: bulk_test.go for working example. Run "go test" in package directory then scroll back to find output. The logic is as follows. // need somewhere to write the JSON. var jsonWriter io.Writer // probably want to log any errors in reading the XML stream var xmlErrLogger io.Writer // func to handle Map value from XML Reader func maphandler(m mxj.Map) bool { // marshal Map as JSON jsonVal, err := m.Json() if err != nil { // log error return false // stops further processing of XML Reader } // write JSON somewhere _, err = jsonWriter.Write(jsonVal) if err != nil { // log error return false // stops further processing of XML Reader } // continue - get next XML from Reader return true } // func to handle error from unmarshaling XML Reader func errhandler(errVal error) bool { // log error somewhere _, err := xmlErrLogger.Write([]byte(errVal.Error())) if err != nil { // log error return false // stops further processing of XML Reader } // continue processing return true } // func that starts bulk processing of the XML ... // set up io.Reader for XML data - perhaps an os.File ... err := mxj.HandleXmlReader(xmlReader, maphandler, errhandler) if err != nil { // handle error } ... */ }
Output:
func HandleXmlReaderRaw ¶
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 ¶
package main import () func main() { /* See: bulkraw_test.go for working example. Run "go test" in package directory then scroll back to find output. Basic logic for bulk XML to JSON processing is in HandleXmlReader example; the only major difference is in handler function signatures so they are passed the raw XML. (Read documentation on NewXmlReader regarding performance.) */ }
Output:
func IncludeTagSeqNum ¶
func IncludeTagSeqNum(b bool)
IncludeTagSeqNum - include a "_seq":N key:value pair with each inner tag, denoting its position when parsed. E.g.,
<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 PrependAttrWithHyphen ¶
func PrependAttrWithHyphen(v bool)
PrependAttrWithHyphen. Prepend attribute tags with a hyphen. Default is 'true'.
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 ¶
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 XmlDefaultEmptyElemSyntax ¶
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 ¶
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. Alternatively, you can replace the encoding/xml/marshal.go file in the standard libary with the patched version in the "xml_marshal" folder in this package. Then use xml.SetUseNullEndTag(true) to have all XML encoding use <tag .../> for empty elements.
Types ¶
type LeafNode ¶
type LeafNode struct { Path string // a dot-notation representation of the path with array subscripting Value interface{} // the value at the path termination }
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 Map ¶
type Map map[string]interface{}
func NewMapJson ¶
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 ¶
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 ¶
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 ¶
Create a new Map value from a structure. Error returned if argument is not a structure or if there is a json.Marshal or json.Unmarshal error.
Only public structure fields are decoded in the Map value. Also, json.Marshal structure encoding rules are followed for decoding the structure fields.
Example ¶
package main import ( "fmt" "github.com/clbanning/mxj" ) func main() { type str struct { IntVal int `json:"int"` StrVal string `json:"str"` FloatVal float64 `json:"float"` BoolVal bool `json:"bool"` private string } strVal := str{IntVal: 4, StrVal: "now's the time", FloatVal: 3.14159, BoolVal: true, private: "Skies are blue"} mapVal, merr := mxj.NewMapStruct(strVal) if merr != nil { // handle error } fmt.Printf("strVal: %#v\n", strVal) fmt.Printf("mapVal: %#v\n", mapVal) // Note: example output is conformed to pass "go test". "mxj_test" is example_test.go package name. }
Output: strVal: mxj_test.str{IntVal:4, StrVal:"now's the time", FloatVal:3.14159, BoolVal:true, private:"Skies are blue"} mapVal: mxj.Map{"int":4, "str":"now's the time", "float":3.14159, "bool":true}
func NewMapXml ¶
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 }
func NewMapXmlReader ¶
Get next XML doc from an io.Reader as a Map value. Returns Map value.
func NewMapXmlReaderRaw ¶
Get next XML doc from an io.Reader as a Map value. Returns Map value and slice with the raw XML.
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. To log it, cast it to a string.
func (Map) Copy ¶
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 ¶
package main import ( "fmt" "github.com/clbanning/mxj" ) func main() { // Hand-crafted Map values that include structures do NOT Copy() as expected, // since to simulate a deep copy the original Map value is JSON encoded then decoded. type str struct { IntVal int `json:"int"` StrVal string `json:"str"` FloatVal float64 `json:"float"` BoolVal bool `json:"bool"` private string } s := str{IntVal: 4, StrVal: "now's the time", FloatVal: 3.14159, BoolVal: true, private: "Skies are blue"} m := make(map[string]interface{}, 0) m["struct"] = interface{}(s) m["struct_ptr"] = interface{}(&s) m["misc"] = interface{}(`Now is the time`) mv := mxj.Map(m) cp, _ := mv.Copy() fmt.Printf("mv:%s\n", mv.StringIndent(2)) fmt.Printf("cp:%s\n", cp.StringIndent(2)) }
Output: mv: struct :[unknown] mxj_test.str{IntVal:4, StrVal:"now's the time", FloatVal:3.14159, BoolVal:true, private:"Skies are blue"} struct_ptr :[unknown] &mxj_test.str{IntVal:4, StrVal:"now's the time", FloatVal:3.14159, BoolVal:true, private:"Skies are blue"} misc :[string] Now is the time cp: misc :[string] Now is the time struct : int :[float64] 4.00e+00 str :[string] now's the time float :[float64] 3.14e+00 bool :[bool] true struct_ptr : int :[float64] 4.00e+00 str :[string] now's the time float :[float64] 3.14e+00 bool :[bool] true
func (Map) Json ¶
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 (Map) JsonIndent ¶
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 (Map) JsonIndentWriter ¶
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 (Map) JsonIndentWriterRaw ¶
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 (Map) JsonWriter ¶
Writes the Map as JSON on the Writer. If 'safeEncoding' is 'true', then "safe" encoding of '<', '>' and '&' is preserved.
func (Map) JsonWriterRaw ¶
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 (Map) LeafNodes ¶
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.
func (Map) LeafValues ¶
LeafValues - all terminal values in the Map.
func (Map) NewMap ¶
(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 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 NOTE: mv.NewMap() == mxj.New().
func (Map) PathForKeyShortest ¶
Extract the shortest path from all possible paths - from PathsForKey() - in Map, 'mv'.. Paths are strings using dot-notation.
func (Map) PathsForKey ¶
Get all paths through Map, 'mv', (in dot-notation) that terminate with the specified key. Results can be used with ValuesForPath.
func (Map) RenameKey ¶
RenameKey renames a key in a Map. It works only for nested maps. It doesn't work for cases when it buried in a list.
func (Map) SetValueForPath ¶
Sets the value for the path
func (Map) Struct ¶
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 ¶
package main import ( "fmt" "github.com/clbanning/mxj" ) func main() { type str struct { IntVal int `json:"int"` StrVal string `json:"str"` FloatVal float64 `json:"float"` BoolVal bool `json:"bool"` private string } mapVal := mxj.Map{"int": 4, "str": "now's the time", "float": 3.14159, "bool": true, "private": "Somewhere over the rainbow"} var strVal str mverr := mapVal.Struct(&strVal) if mverr != nil { // handle error } fmt.Printf("mapVal: %#v\n", mapVal) fmt.Printf("strVal: %#v\n", strVal) // Note: example output is conformed to pass "go test". "mxj_test" is example_test.go package name. }
Output: mapVal: mxj.Map{"int":4, "str":"now's the time", "float":3.14159, "bool":true, "private":"Somewhere over the rainbow"} strVal: mxj_test.str{IntVal:4, StrVal:"now's the time", FloatVal:3.14159, BoolVal:true, private:""}
func (Map) UpdateValuesForPath ¶
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 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".
Example ¶
package main import () func main() { /* var biblioDoc = []byte(` <biblio> <author> <name>William Gaddis</name> <books> <book> <title>The Recognitions</title> <date>1955</date> <review>A novel that changed the face of American literature.</review> </book> <book> <title>JR</title> <date>1975</date> <review>Winner of National Book Award for Fiction.</review> </book> </books> </author> </biblio>`) ... m, merr := mxj.NewMapXml(biblioDoc) if merr != nil { // handle error } // change 'review' for a book count, err := m.UpdateValuesForPath("review:National Book Award winner." "*.*.*.*", "title:JR") if err != nil { // handle error } ... // change 'date' value from string type to float64 type // Note: the following is equivalent to m, merr := NewMapXml(biblioDoc, mxj.Cast). path := m.PathForKeyShortest("date") v, err := m.ValuesForPath(path) if err != nil { // handle error } var total int for _, vv := range v { oldVal := "date:" + vv.(string) newVal := "date:" + vv.(string) + ":num" n, err := m.UpdateValuesForPath(newVal, path, oldVal) if err != nil { // handle error } total += n } ... */ }
Output:
func (Map) ValueForPath ¶
Returns the first found value for the path.
func (Map) ValueForPathString ¶
Returns the first found value for the path as a string.
func (Map) 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 (Map) ValuesForKey ¶
Return all values in Map, 'mv', associated with a 'key'. If len(returned_values) == 0, then no match. On error, the returned array 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 a hyphen, '-', e.g., "-seq:3". - 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".
func (Map) ValuesForPath ¶
Retrieve 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 a hyphen, '-', e.g., "-seq:3". - 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".
func (Map) Xml ¶
Encode a Map as XML. The companion of NewMapXml(). The following rules apply.
- The key label "#text" is treated as the value for a simple element with attributes.
- Map keys that begin with a hyphen, '-', are interpreted as attributes. It is an error if the attribute doesn't have a []byte, string, number, or boolean value.
- Map value type encoding: > string, bool, float64, int, int32, int64, float32: per "%v" formating > []bool, []uint8: by casting to string > structures, etc.: handed to xml.Marshal() - if there is an error, the element value is "UNKNOWN"
- Elements with only attribute values or are null are terminated using "/>".
- If len(mv) == 1 and no rootTag is provided, then the map key is used as the root tag, possible. Thus, `{ "key":"value" }` encodes as "<key>value</key>".
- To encode empty elements in a syntax consistent with encoding/xml call UseGoXmlEmptyElementSyntax().
func (Map) XmlIndent ¶
Encode a map[string]interface{} as a pretty XML string. See Xml for encoding rules.
func (Map) XmlIndentWriter ¶
Writes the Map as pretty XML on the Writer. See Xml() for encoding rules.
func (Map) XmlIndentWriterRaw ¶
func (mv Map) XmlIndentWriterRaw(xmlWriter io.Writer, prefix, indent string, rootTag ...string) ([]byte, error)
Writes the Map as pretty XML on the Writer. []byte is the raw XML that was written. See Xml() for encoding rules.
type MapRaw ¶
func NewMapsFromJsonFileRaw ¶
ReadMapsFromJsonFileRaw - creates an array of MapRaw from a file of JSON values.
func NewMapsFromXmlFileRaw ¶
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.
type Maps ¶
type Maps []Map
func NewMapsFromJsonFile ¶
NewMapsFromXmlFile - creates an array from a file of JSON values.
func NewMapsFromXmlFile ¶
NewMapsFromXmlFile - creates an array from a file of XML values.
func (Maps) JsonFile ¶
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 (Maps) JsonFileIndent ¶
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 (Maps) JsonString ¶
JsonString - analogous to mv.Json()
func (Maps) JsonStringIndent ¶
JsonStringIndent - analogous to mv.JsonIndent()
func (Maps) XmlFile ¶
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 (Maps) XmlFileIndent ¶
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.
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
j2x.go - For (mostly) backwards compatibility with legacy j2x package.
|
j2x.go - For (mostly) backwards compatibility with legacy j2x package. |
x2j - For (mostly) backwards compatibility with legacy x2j package.
|
x2j - For (mostly) backwards compatibility with legacy x2j package. |