// +test OMIT // note - "// Output:" is a key for "go test" to match function ouput with the lines that follow. // It is also use by "godoc" to build the Output block of the function / method documentation. // To skip processing Example* functions, use: go test -run "Test*" // or make sure example function output matches // Output: documentation EXACTLY. package mxj_test import ( /* "bytes" "fmt" "github.com/clbanning/mxj" "io" */ ) func ExampleHandleXmlReader() { /* 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 } ... */ } func ExampleHandleXmlReaderRaw() { /* 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.) */ } func ExampleHandleJsonReader() { /* 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. */ } func ExampleHandleJsonReaderRaw() { /* 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. */ } /* func ExampleNewMapXmlReaderRaw() { // in an http.Handler mapVal, raw, err := mxj.NewMapXmlReader(req.Body) if err != nil { // handle error } logger.Print(string(*raw)) // do something with mapVal } */ /* func ExampleNewMapStruct() { type str struct { IntVal int `structs:"int"` StrVal string `structs:"str"` FloatVal float64 `structs:"float"` BoolVal bool `structs:"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. // NoFail output: // strVal: mxj_test.str{IntVal:4, StrVal:"now's the time", FloatVal:3.14159, BoolVal:true, private:"Skies are blue"} // mapVal: mxj.Map{"float":3.14159, "bool":true, "int":4, "str":"now's the time"} } */ func ExampleMap_Struct() { /* 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) // Unordered output for above: // 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 ExampleMap_ValuesForPath() { /* // a snippet from examples/gonuts1.go // How to compensate for irregular tag labels in data. // Need to extract from an XML stream the values for "netid" and "idnet". // Solution: use a wildcard path "data.*" to anonymize the "netid" and "idnet" tags. var msg1 = []byte(` no default:text default:word `) var msg2 = []byte(` yes default:text default:word `) // let's create a message stream buf := new(bytes.Buffer) // load a couple of messages into it _, _ = buf.Write(msg1) _, _ = buf.Write(msg2) n := 0 for { n++ // Read the stream as Map values - quit on io.EOF. // Get the raw XML as well as the Map value. m, merr := mxj.NewMapXmlReader(buf) if merr != nil && merr != io.EOF { // handle error - for demo we just print it and continue fmt.Printf("msg: %d - merr: %s\n", n, merr.Error()) continue } else if merr == io.EOF { break } // get the values for "netid" or "idnet" key using path == "data.*" values, _ := m.ValuesForPath("data.*") fmt.Println("\nmsg:", n, "> path == data.* - got array of values, len:", len(values)) for i, val := range values { fmt.Println("ValuesForPath result array member -", i, ":", val) fmt.Println(" k:v pairs for array member:", i) for key, val := range val.(map[string]interface{}) { // You'd probably want to process the value, as appropriate. // Here we just print it out. fmt.Println("\t\t", key, ":", val) } } } // NoFail output: // msg: 1 > path == data.* - got array of values, len: 1 // ValuesForPath result array member - 0 : map[disable:no text1:default:text word1:default:word] // k:v pairs for array member: 0 // disable : no // text1 : default:text // word1 : default:word // // msg: 2 > path == data.* - got array of values, len: 1 // ValuesForPath result array member - 0 : map[disable:yes text1:default:text word1:default:word] // k:v pairs for array member: 0 // disable : yes // text1 : default:text // word1 : default:word */ } func ExampleMap_UpdateValuesForPath() { /* var biblioDoc = []byte(` William Gaddis The Recognitions 1955 A novel that changed the face of American literature. JR 1975 Winner of National Book Award for Fiction. `) ... 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 } ... */ } func ExampleMap_Copy() { /* // 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:\n%s\n", mv.StringIndent(2)) fmt.Printf("cp:\n%s\n", cp.StringIndent(2)) // NoFail output: // mv: // misc : [string] Now is the time // struct : [mxj_test.str] {IntVal:4 StrVal:now's the time FloatVal:3.14159 BoolVal:true private:Skies are blue} // struct_ptr : [*mxj_test.str] &{IntVal:4 StrVal:now's the time FloatVal:3.14159 BoolVal:true private:Skies are blue} // cp: // misc : [string] Now is the time // struct : // bool : [bool] true // float : [float64] 3.14159 // int : [float64] 4 // str : [string] now's the time // struct_ptr : // bool : [bool] true // float : [float64] 3.14159 // int : [float64] 4 // str : [string] now's the time // */ }