Giter VIP home page Giter VIP logo

mxj's Introduction

mxj - to/from maps, XML and JSON

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 and mxj/j2x packages.

Notices

2015-05-20: New: mv.StringIndentNoTypeInfo(). Also, alphabetically sort map[string]interface{} values by key to prettify output for mv.Xml(), mv.XmlIndent(), mv.StringIndent(), mv.StringIndentNoTypeInfo(). 2014-11-09: IncludeTagSeqNum() adds "_seq" key with XML doc positional information. (NOTE: PreserveXmlList() is similar and will be here soon.) 2014-09-18: inspired by NYTimes fork, added PrependAttrWithHyphen() to allow stripping hyphen from attribute tag. 2014-08-02: AnyXml() and AnyXmlIndent() will try to marshal arbitrary values to XML. 2014-04-28: ValuesForPath() and NewMap() now accept path with indexed array references.

Basic Unmarshal XML / JSON / struct

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)

Extract / modify Map values

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)
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.)

newMap := m.NewMap("oldKey_1:newKey_1", "oldKey_2:newKey_2", ..., "oldKey_N:newKey_N")
newXml := newMap.Xml()   // for example
newJson := newMap.Json() // ditto

Usage

The package is fairly well self-documented with examples. (http://godoc.org/github.com/clbanning/mxj)

Also, the subdirectory "examples" contains a wide range of examples, several taken from golang-nuts discussions.

XML parsing conventions

  • Attributes are parsed to map[string]interface{} values by prefixing a hyphen, -, to the attribute label. (Unless overridden by PrependAttrWithHyphen(false).)
  • If the element is a simple element and has attributes, the element value is given the key #text for its map[string]interface{} representation. (See the 'atomFeedString.xml' test data, below.)

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.

Running "go test"

Because there are no guarantees on the sequence map elements are retrieved, the tests have been written for visual verification in most cases. One advantage is that you can easily use the output from running "go test" as examples of calling the various functions and methods.

Motivation

I make extensive use of JSON for messaging and typically unmarshal the messages into map[string]interface{} variables. This is easily done using json.Unmarshal from the standard Go libraries. Unfortunately, many legacy solutions use structured XML messages; in those environments the applications would have to be refitted to interoperate with my components.

The better solution is to just provide an alternative HTTP handler that receives XML messages and parses it into a map[string]interface{} variable and then reuse all the JSON-based code. The Go xml.Unmarshal() function does not provide the same option of unmarshaling XML messages into map[string]interface{} variables. So I wrote a couple of small functions to fill this gap and released them as the x2j package.

Over the next year and a half additional features were added, and the companion j2x package was released to address XML encoding of arbitrary JSON and map[string]interface{} values. As part of a refactoring of our production system and looking at how we had been using the x2j and j2x packages we found that we rarely performed direct XML-to-JSON or JSON-to_XML conversion and that working with the XML or JSON as map[string]interface{} values was the primary value. Thus, everything was refactored into the mxj package.

mxj's People

Contributors

clbanning avatar fatih avatar fkautz avatar mrsln avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.