mirror of
https://gitee.com/johng/gf
synced 2026-07-08 14:39:50 +08:00
新增go modules支持,自行管理第三方包依赖,方便开发者使用
This commit is contained in:
347
third/github.com/clbanning/mxj/example_test.go
Normal file
347
third/github.com/clbanning/mxj/example_test.go
Normal file
@ -0,0 +1,347 @@
|
||||
// +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"
|
||||
"gitee.com/johng/gf/third/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)
|
||||
// Note: example output is conformed to pass "go test". "mxj_test" is example_test.go package name.
|
||||
|
||||
// Unordered 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 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(`
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<data>
|
||||
<netid>
|
||||
<disable>no</disable>
|
||||
<text1>default:text</text1>
|
||||
<word1>default:word</word1>
|
||||
</netid>
|
||||
</data>
|
||||
`)
|
||||
|
||||
var msg2 = []byte(`
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<data>
|
||||
<idnet>
|
||||
<disable>yes</disable>
|
||||
<text1>default:text</text1>
|
||||
<word1>default:word</word1>
|
||||
</idnet>
|
||||
</data>
|
||||
`)
|
||||
|
||||
// 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(`
|
||||
<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
|
||||
}
|
||||
...
|
||||
*/
|
||||
}
|
||||
|
||||
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
|
||||
//
|
||||
}
|
||||
Reference in New Issue
Block a user