mirror of
https://gitee.com/johng/gf
synced 2026-06-07 10:22:11 +08:00
gofmt
This commit is contained in:
@ -18,7 +18,7 @@ const (
|
||||
// The Encoder or Decoder should have output a substitute character.
|
||||
INVALID_CHAR
|
||||
|
||||
// NO_ROOM means there were not enough input bytes to form a complete character,
|
||||
// NO_ROOM means there were not enough input bytes to form a complete character,
|
||||
// or there was not enough room in the output buffer to write a complete character.
|
||||
// No bytes were written, and no internal state was changed in the Encoder or Decoder.
|
||||
NO_ROOM
|
||||
@ -52,7 +52,7 @@ type Charset struct {
|
||||
NewEncoder func() Encoder
|
||||
}
|
||||
|
||||
// The charsets are stored in charsets under their canonical names.
|
||||
// The charsets are stored in charsets under their canonical names.
|
||||
var charsets = make(map[string]*Charset)
|
||||
|
||||
// aliases maps their aliases to their canonical names.
|
||||
|
||||
@ -155,7 +155,7 @@ func EntityDecoder() Decoder {
|
||||
|
||||
// This table is copied from /src/pkg/html/escape.go in the Go source
|
||||
//
|
||||
// These replacements permit compatibility with old numeric entities that
|
||||
// These replacements permit compatibility with old numeric entities that
|
||||
// assumed Windows-1252 encoding.
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#consume-a-character-reference
|
||||
var replacementTable = [...]rune{
|
||||
@ -191,6 +191,6 @@ var replacementTable = [...]rune{
|
||||
'\u009D',
|
||||
'\u017E',
|
||||
'\u0178', // Last entry is 0x9F.
|
||||
// 0x00->'\uFFFD' is handled programmatically.
|
||||
// 0x00->'\uFFFD' is handled programmatically.
|
||||
// 0x0D->'\u000D' is a no-op.
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/third/github.com/axgle/mahonia"
|
||||
"flag"
|
||||
"github.com/gogf/gf/third/github.com/axgle/mahonia"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
@ -19,7 +19,7 @@ type MBCSTable struct {
|
||||
fromUnicode map[rune]string
|
||||
}
|
||||
|
||||
// AddCharacter adds a character to the table. rune is its Unicode code point,
|
||||
// AddCharacter adds a character to the table. rune is its Unicode code point,
|
||||
// and bytes contains the bytes used to encode it in the character set.
|
||||
func (table *MBCSTable) AddCharacter(c rune, bytes string) {
|
||||
if table.fromUnicode == nil {
|
||||
|
||||
@ -145,4 +145,3 @@ func TestMarshalPrefixUnderscore(t *testing.T) {
|
||||
}
|
||||
fmt.Println(string(x))
|
||||
}
|
||||
|
||||
|
||||
@ -103,13 +103,13 @@ XML PARSING CONVENTIONS
|
||||
Using NewMapXmlSeq()
|
||||
|
||||
- Attributes are parsed to `map["#attr"]map[<attr_label>]map[string]interface{}`values
|
||||
where the `<attr_label>` value has "#text" and "#seq" keys - the "#text" key holds the
|
||||
where the `<attr_label>` value has "#text" and "#seq" keys - the "#text" key holds the
|
||||
value for `<attr_label>`.
|
||||
- All elements, except for the root, have a "#seq" key.
|
||||
- Comments, directives, and process instructions are unmarshalled into the Map using the
|
||||
keys "#comment", "#directive", and "#procinst", respectively. (See documentation for more
|
||||
specifics.)
|
||||
- Name space syntax is preserved:
|
||||
- Name space syntax is preserved:
|
||||
- <ns:key>something</ns.key> parses to map["ns:key"]interface{}{"something"}
|
||||
- xmlns:ns="http://myns.com/ns" parses to map["xmlns:ns"]interface{}{"http://myns.com/ns"}
|
||||
|
||||
@ -119,7 +119,7 @@ XML PARSING CONVENTIONS
|
||||
to be cast, set a flag to cast them using CastNanInf(true).
|
||||
|
||||
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..
|
||||
|
||||
@ -13,7 +13,7 @@ var xmlEscapeChars 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:
|
||||
" "
|
||||
@ -26,7 +26,7 @@ func XMLEscapeChars(b bool) {
|
||||
xmlEscapeChars = b
|
||||
}
|
||||
|
||||
// Scan for '&' first, since 's' may contain "&" that is parsed to "&amp;"
|
||||
// Scan for '&' first, since 's' may contain "&" that is parsed to "&amp;"
|
||||
// - or "<" that is parsed to "&lt;".
|
||||
var escapechars = [][2][]byte{
|
||||
{[]byte(`&`), []byte(`&`)},
|
||||
@ -51,4 +51,3 @@ func escapeChars(s string) string {
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ func TestXMLEscapeChars(t *testing.T) {
|
||||
XMLEscapeChars(true)
|
||||
defer XMLEscapeChars(false)
|
||||
|
||||
m := map[string]interface{}{"mychars":s}
|
||||
m := map[string]interface{}{"mychars": s}
|
||||
|
||||
x, err := AnyXmlIndent(s, "", " ")
|
||||
if err != nil {
|
||||
|
||||
@ -333,12 +333,12 @@ func ExampleMap_Copy() {
|
||||
// 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 :
|
||||
// struct :
|
||||
// bool : [bool] true
|
||||
// float : [float64] 3.14159
|
||||
// int : [float64] 4
|
||||
// str : [string] now's the time
|
||||
// struct_ptr :
|
||||
// struct_ptr :
|
||||
// bool : [bool] true
|
||||
// float : [float64] 3.14159
|
||||
// int : [float64] 4
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package mxj
|
||||
|
||||
// Checks whether the path exists
|
||||
func (mv Map) Exists(path string, subkeys... string) bool {
|
||||
func (mv Map) Exists(path string, subkeys ...string) bool {
|
||||
v, err := mv.ValuesForPath(path, subkeys...)
|
||||
return err == nil && len(v) > 0
|
||||
}
|
||||
|
||||
@ -34,4 +34,4 @@ func TestExistsWithSubKeys(t *testing.T) {
|
||||
if mv.Exists("doc.books.book", "-seq:2") {
|
||||
t.Fatal("Have found a non existing element")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,7 +105,7 @@ func (mv Map) JsonIndentWriterRaw(jsonWriter io.Writer, prefix, indent string, s
|
||||
// --------------------------- read JSON -----------------------------
|
||||
|
||||
// Decode numericvalues as json.Number type Map values - see encoding/json#Number.
|
||||
// NOTE: this is for decoding JSON into a Map with NewMapJson(), NewMapJsonReader(),
|
||||
// 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.
|
||||
|
||||
@ -44,4 +44,3 @@ func TestSetSubkeyFieldSeparator(t *testing.T) {
|
||||
t.Fatal("|expecting: value 2; got:", vals[0].(map[string]interface{})["#text"])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -25,9 +25,9 @@ type LeafNode struct {
|
||||
// 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".
|
||||
// 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.
|
||||
@ -101,7 +101,7 @@ var useDotNotation 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
|
||||
// syntax. Calling LeafUseDotNotation with no arguments toggles the
|
||||
// flag on/off; otherwise, the argument sets the flag value 'true'/'false'.
|
||||
func LeafUseDotNotation(b ...bool) {
|
||||
if len(b) == 0 {
|
||||
|
||||
@ -37,9 +37,9 @@ func TestMap(t *testing.T) {
|
||||
fmt.Println("TestMap, m_fromXML:")
|
||||
fmt.Printf("%#v\n", m)
|
||||
fmt.Println("TestMap, StringIndent -")
|
||||
fmt.Println( m.StringIndent())
|
||||
fmt.Println(m.StringIndent())
|
||||
fmt.Println("TestMap, StringIndent NoTypeInfo -")
|
||||
fmt.Println( m.StringIndentNoTypeInfo())
|
||||
fmt.Println(m.StringIndentNoTypeInfo())
|
||||
|
||||
mm, _ := m.Copy()
|
||||
fmt.Println("TestMap, m.Copy() -\n", mm)
|
||||
|
||||
@ -78,4 +78,3 @@ func TestCastNanInf(t *testing.T) {
|
||||
}
|
||||
fmt.Println("foo.bar:", v)
|
||||
}
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@ var fieldSep 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.
|
||||
//
|
||||
// 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
|
||||
|
||||
@ -66,4 +66,3 @@ func TestStakeCase(t *testing.T) {
|
||||
t.Fatal(string(x), "!=", data2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -27,4 +27,3 @@ func useCustomDecoder(d *xml.Decoder) {
|
||||
d.CharsetReader = CustomDecoder.CharsetReader
|
||||
d.DefaultSpace = CustomDecoder.DefaultSpace
|
||||
}
|
||||
|
||||
|
||||
@ -10,24 +10,24 @@ func TestStrictModeXml(t *testing.T) {
|
||||
fmt.Println("----------------- TestStrictModeXml ...")
|
||||
data := []byte(`<document> <name>Bill & Hallett</name> <salute>Duc & 123xx</salute> <goes_by/> <lang>E</lang> </document>`)
|
||||
|
||||
CustomDecoder = &xml.Decoder{Strict:false}
|
||||
CustomDecoder = &xml.Decoder{Strict: false}
|
||||
m, err := NewMapXml(data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fmt.Println("m:",m)
|
||||
fmt.Println("m:", m)
|
||||
}
|
||||
|
||||
func TestStrictModeXmlSeq(t *testing.T) {
|
||||
fmt.Println("----------------- TestStrictModeXmlSeq ...")
|
||||
data := []byte(`<document> <name>Bill & Hallett</name> <salute>Duc & 123xx</salute> <goes_by/> <lang>E</lang> </document>`)
|
||||
|
||||
CustomDecoder = &xml.Decoder{Strict:false}
|
||||
CustomDecoder = &xml.Decoder{Strict: false}
|
||||
m, err := NewMapXmlSeq(data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fmt.Println("m:",m)
|
||||
fmt.Println("m:", m)
|
||||
}
|
||||
|
||||
func TestStrictModeFail(t *testing.T) {
|
||||
@ -45,4 +45,3 @@ func TestStrictModeFail(t *testing.T) {
|
||||
}
|
||||
fmt.Println("OK")
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"reflect"
|
||||
|
||||
// "github.com/gogf/gf/third/github.com/fatih/structs"
|
||||
)
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
func TestGoofy(t *testing.T) {
|
||||
var doc = `<xml><tag one="1" pi="3.1415962535" bool="true"/><tagJR key="value"/></xml>`
|
||||
type goofy struct {
|
||||
S string
|
||||
S string
|
||||
Sp *string
|
||||
}
|
||||
g := new(goofy)
|
||||
@ -19,7 +19,7 @@ func TestGoofy(t *testing.T) {
|
||||
|
||||
m, err := DocToMap(doc)
|
||||
if err != nil {
|
||||
fmt.Println("err:",err.Error())
|
||||
fmt.Println("err:", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@ -27,13 +27,13 @@ func TestGoofy(t *testing.T) {
|
||||
m["byteVal"] = interface{}([]byte(`the aid of their country`))
|
||||
m["nilVal"] = interface{}(nil)
|
||||
|
||||
fmt.Println("\nTestGoofy ... MapToDoc:",m)
|
||||
fmt.Println("\nTestGoofy ... MapToDoc:", m)
|
||||
var v []byte
|
||||
v,err = json.Marshal(m)
|
||||
v, err = json.Marshal(m)
|
||||
if err != nil {
|
||||
fmt.Println("err:",err.Error())
|
||||
fmt.Println("err:", err.Error())
|
||||
}
|
||||
fmt.Println("v:",string(v))
|
||||
fmt.Println("v:", string(v))
|
||||
|
||||
type goofier struct {
|
||||
G *goofy
|
||||
@ -46,11 +46,10 @@ func TestGoofy(t *testing.T) {
|
||||
gg.N = nil
|
||||
m["goofierVal"] = interface{}(gg)
|
||||
|
||||
fmt.Println("\nTestGoofier ... MapToDoc:",m)
|
||||
v,err = json.Marshal(m)
|
||||
fmt.Println("\nTestGoofier ... MapToDoc:", m)
|
||||
v, err = json.Marshal(m)
|
||||
if err != nil {
|
||||
fmt.Println("err:",err.Error())
|
||||
fmt.Println("err:", err.Error())
|
||||
}
|
||||
fmt.Println("v:",string(v))
|
||||
fmt.Println("v:", string(v))
|
||||
}
|
||||
|
||||
|
||||
@ -8,69 +8,67 @@ import (
|
||||
|
||||
var doc = `<entry><vars><foo>bar</foo><foo2><hello>world</hello></foo2></vars></entry>`
|
||||
|
||||
|
||||
func TestToMap(t *testing.T) {
|
||||
fmt.Println("\nToMap - Read doc:",doc)
|
||||
fmt.Println("\nToMap - Read doc:", doc)
|
||||
rdr := bytes.NewBufferString(doc)
|
||||
m,err := ToMap(rdr)
|
||||
m, err := ToMap(rdr)
|
||||
if err != nil {
|
||||
fmt.Println("err:",err.Error())
|
||||
fmt.Println("err:", err.Error())
|
||||
}
|
||||
fmt.Println(WriteMap(m))
|
||||
}
|
||||
|
||||
func TestToJson(t *testing.T) {
|
||||
fmt.Println("\nToJson - Read doc:",doc)
|
||||
fmt.Println("\nToJson - Read doc:", doc)
|
||||
rdr := bytes.NewBufferString(doc)
|
||||
s,err := ToJson(rdr)
|
||||
s, err := ToJson(rdr)
|
||||
if err != nil {
|
||||
fmt.Println("err:",err.Error())
|
||||
fmt.Println("err:", err.Error())
|
||||
}
|
||||
fmt.Println("json:",s)
|
||||
fmt.Println("json:", s)
|
||||
}
|
||||
|
||||
func TestToJsonIndent(t *testing.T) {
|
||||
fmt.Println("\nToJsonIndent - Read doc:",doc)
|
||||
fmt.Println("\nToJsonIndent - Read doc:", doc)
|
||||
rdr := bytes.NewBufferString(doc)
|
||||
s,err := ToJsonIndent(rdr)
|
||||
s, err := ToJsonIndent(rdr)
|
||||
if err != nil {
|
||||
fmt.Println("err:",err.Error())
|
||||
fmt.Println("err:", err.Error())
|
||||
}
|
||||
fmt.Println("json:",s)
|
||||
fmt.Println("json:", s)
|
||||
}
|
||||
|
||||
func TestBulkParser(t *testing.T) {
|
||||
s := doc + `<this><is>an</err>`+ doc
|
||||
fmt.Println("\nBulkParser (with error) - Read doc:",s)
|
||||
s := doc + `<this><is>an</err>` + doc
|
||||
fmt.Println("\nBulkParser (with error) - Read doc:", s)
|
||||
rdr := bytes.NewBufferString(s)
|
||||
err := XmlMsgsFromReader(rdr,phandler,ehandler)
|
||||
err := XmlMsgsFromReader(rdr, phandler, ehandler)
|
||||
if err != nil {
|
||||
fmt.Println("reader terminated:",err.Error())
|
||||
fmt.Println("reader terminated:", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func phandler(m map[string]interface{}) bool {
|
||||
fmt.Println("phandler m:",m)
|
||||
fmt.Println("phandler m:", m)
|
||||
return true
|
||||
}
|
||||
|
||||
func ehandler(err error) bool {
|
||||
fmt.Println("ehandler err:",err.Error())
|
||||
fmt.Println("ehandler err:", err.Error())
|
||||
return true
|
||||
}
|
||||
|
||||
func TestBulkParserToJson(t *testing.T) {
|
||||
s := doc + `<this><is>an</err>`+ doc
|
||||
fmt.Println("\nBulkParser (with error) - Read doc:",s)
|
||||
s := doc + `<this><is>an</err>` + doc
|
||||
fmt.Println("\nBulkParser (with error) - Read doc:", s)
|
||||
rdr := bytes.NewBufferString(s)
|
||||
err := XmlMsgsFromReaderAsJson(rdr,phandlerj,ehandler)
|
||||
err := XmlMsgsFromReaderAsJson(rdr, phandlerj, ehandler)
|
||||
if err != nil {
|
||||
fmt.Println("reader terminated:",err.Error())
|
||||
fmt.Println("reader terminated:", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func phandlerj(s string) bool {
|
||||
fmt.Println("phandlerj s:",s)
|
||||
fmt.Println("phandlerj s:", s)
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@ -12,18 +12,18 @@
|
||||
|
||||
One useful function is:
|
||||
|
||||
- Unmarshal(doc []byte, v interface{}) error
|
||||
- Unmarshal(doc []byte, v interface{}) error
|
||||
where v is a pointer to a variable of type 'map[string]interface{}', 'string', or
|
||||
any other type supported by xml.Unmarshal().
|
||||
|
||||
To retrieve a value for specific tag use:
|
||||
To retrieve a value for specific tag use:
|
||||
|
||||
- DocValue(doc, path string, attrs ...string) (interface{},error)
|
||||
- DocValue(doc, path string, attrs ...string) (interface{},error)
|
||||
- MapValue(m map[string]interface{}, path string, attr map[string]interface{}, recast ...bool) (interface{}, error)
|
||||
|
||||
The 'path' argument is a period-separated tag hierarchy - also known as dot-notation.
|
||||
It is the program's responsibility to cast the returned value to the proper type; possible
|
||||
types are the normal JSON unmarshaling types: string, float64, bool, []interface, map[string]interface{}.
|
||||
It is the program's responsibility to cast the returned value to the proper type; possible
|
||||
types are the normal JSON unmarshaling types: string, float64, bool, []interface, map[string]interface{}.
|
||||
|
||||
To retrieve all values associated with a tag occurring anywhere in the XML document use:
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
|
||||
Returned values should be one of map[string]interface, []interface{}, or string.
|
||||
|
||||
All the values assocated with a tag-path that may include one or more wildcard characters -
|
||||
All the values assocated with a tag-path that may include one or more wildcard characters -
|
||||
'*' - can also be retrieved using:
|
||||
|
||||
- ValuesFromTagPath(doc, path string, getAttrs ...bool) ([]interface{}, error)
|
||||
@ -47,7 +47,7 @@
|
||||
|
||||
NOTE: care should be taken when using "*" at the end of a path - i.e., "books.book.*". See
|
||||
the x2jpath_test.go case on how the wildcard returns all key values and collapses list values;
|
||||
the same message structure can load a []interface{} or a map[string]interface{} (or an interface{})
|
||||
the same message structure can load a []interface{} or a map[string]interface{} (or an interface{})
|
||||
value for a tag.
|
||||
|
||||
See the test cases in "x2jpath_test.go" and programs in "example" subdirectory for more.
|
||||
@ -89,7 +89,7 @@ import (
|
||||
// ...
|
||||
// x2j.X2jCharsetReader = charset.NewReader
|
||||
// s, err := x2j.DocToJson(doc)
|
||||
var X2jCharsetReader func(charset string, input io.Reader)(io.Reader, error)
|
||||
var X2jCharsetReader func(charset string, input io.Reader) (io.Reader, error)
|
||||
|
||||
// DocToJson - return an XML doc as a JSON string.
|
||||
// If the optional argument 'recast' is 'true', then values will be converted to boolean or float64 if possible.
|
||||
@ -452,4 +452,3 @@ func ByteDocToMap(doc []byte, recast ...bool) (map[string]interface{}, error) {
|
||||
}
|
||||
return mxj.NewMapXml(doc, r)
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ import (
|
||||
// Note: phandler() and ehandler() 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 arguments to a go routine in handler and return true.
|
||||
func XmlMsgsFromFileAsJson(fname string, phandler func(string)(bool), ehandler func(error)(bool), recast ...bool) error {
|
||||
func XmlMsgsFromFileAsJson(fname string, phandler func(string) bool, ehandler func(error) bool, recast ...bool) error {
|
||||
var r bool
|
||||
if len(recast) == 1 {
|
||||
r = recast[0]
|
||||
@ -37,26 +37,26 @@ func XmlMsgsFromFileAsJson(fname string, phandler func(string)(bool), ehandler f
|
||||
return fherr
|
||||
}
|
||||
defer fh.Close()
|
||||
buf := make([]byte,fi.Size())
|
||||
_, rerr := fh.Read(buf)
|
||||
buf := make([]byte, fi.Size())
|
||||
_, rerr := fh.Read(buf)
|
||||
if rerr != nil {
|
||||
return rerr
|
||||
}
|
||||
doc := string(buf)
|
||||
|
||||
// xml.Decoder doesn't properly handle whitespace in some doc
|
||||
// see songTextString.xml test case ...
|
||||
reg,_ := regexp.Compile("[ \t\n\r]*<")
|
||||
doc = reg.ReplaceAllString(doc,"<")
|
||||
// see songTextString.xml test case ...
|
||||
reg, _ := regexp.Compile("[ \t\n\r]*<")
|
||||
doc = reg.ReplaceAllString(doc, "<")
|
||||
b := bytes.NewBufferString(doc)
|
||||
|
||||
for {
|
||||
s, serr := XmlBufferToJson(b,r)
|
||||
s, serr := XmlBufferToJson(b, r)
|
||||
if serr != nil && serr != io.EOF {
|
||||
if ok := ehandler(serr); !ok {
|
||||
// caused reader termination
|
||||
return serr
|
||||
}
|
||||
}
|
||||
}
|
||||
if s != "" {
|
||||
if ok := phandler(s); !ok {
|
||||
@ -73,7 +73,7 @@ func XmlMsgsFromFileAsJson(fname string, phandler func(string)(bool), ehandler f
|
||||
// XmlBufferToJson - process XML message from a bytes.Buffer
|
||||
// 'b' is the buffer
|
||||
// Optional argument 'recast' coerces values to float64 or bool where possible.
|
||||
func XmlBufferToJson(b *bytes.Buffer,recast ...bool) (string,error) {
|
||||
func XmlBufferToJson(b *bytes.Buffer, recast ...bool) (string, error) {
|
||||
var r bool
|
||||
if len(recast) == 1 {
|
||||
r = recast[0]
|
||||
@ -101,19 +101,19 @@ func XmlBufferToJson(b *bytes.Buffer,recast ...bool) (string,error) {
|
||||
// Note: phandler() and ehandler() 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 arguments to a go routine in handler and return true.
|
||||
func XmlMsgsFromReaderAsJson(rdr io.Reader, phandler func(string)(bool), ehandler func(error)(bool), recast ...bool) error {
|
||||
func XmlMsgsFromReaderAsJson(rdr io.Reader, phandler func(string) bool, ehandler func(error) bool, recast ...bool) error {
|
||||
var r bool
|
||||
if len(recast) == 1 {
|
||||
r = recast[0]
|
||||
}
|
||||
|
||||
for {
|
||||
s, serr := ToJson(rdr,r)
|
||||
s, serr := ToJson(rdr, r)
|
||||
if serr != nil && serr != io.EOF {
|
||||
if ok := ehandler(serr); !ok {
|
||||
// caused reader termination
|
||||
return serr
|
||||
}
|
||||
}
|
||||
}
|
||||
if s != "" {
|
||||
if ok := phandler(s); !ok {
|
||||
@ -126,4 +126,3 @@ func XmlMsgsFromReaderAsJson(rdr io.Reader, phandler func(string)(bool), ehandle
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -66,7 +66,7 @@ func BytePathForTagShortest(doc []byte, key string) (string, error) {
|
||||
// Get all paths through the map (in dot-notation) that terminate with the specified key.
|
||||
// Results can be used with ValuesAtKeyPath() and ValuesFromKeyPath().
|
||||
func PathsForKey(m map[string]interface{}, key string) []string {
|
||||
breadbasket := make(map[string]bool,0)
|
||||
breadbasket := make(map[string]bool, 0)
|
||||
breadcrumb := ""
|
||||
|
||||
hasKeyPath(breadcrumb, m, key, &breadbasket)
|
||||
@ -75,9 +75,9 @@ func PathsForKey(m map[string]interface{}, key string) []string {
|
||||
}
|
||||
|
||||
// unpack map keys to return
|
||||
res := make([]string,len(breadbasket))
|
||||
res := make([]string, len(breadbasket))
|
||||
var i int
|
||||
for k,_ := range breadbasket {
|
||||
for k, _ := range breadbasket {
|
||||
res[i] = k
|
||||
i++
|
||||
}
|
||||
@ -88,7 +88,7 @@ func PathsForKey(m map[string]interface{}, key string) []string {
|
||||
// Extract the shortest path from all possible paths - from PathsForKey().
|
||||
// Paths are strings using dot-notation.
|
||||
func PathForKeyShortest(m map[string]interface{}, key string) string {
|
||||
paths := PathsForKey(m,key)
|
||||
paths := PathsForKey(m, key)
|
||||
|
||||
lp := len(paths)
|
||||
if lp == 0 {
|
||||
@ -99,10 +99,10 @@ func PathForKeyShortest(m map[string]interface{}, key string) string {
|
||||
}
|
||||
|
||||
shortest := paths[0]
|
||||
shortestLen := len(strings.Split(shortest,"."))
|
||||
shortestLen := len(strings.Split(shortest, "."))
|
||||
|
||||
for i := 1 ; i < len(paths) ; i++ {
|
||||
vlen := len(strings.Split(paths[i],"."))
|
||||
for i := 1; i < len(paths); i++ {
|
||||
vlen := len(strings.Split(paths[i], "."))
|
||||
if vlen < shortestLen {
|
||||
shortest = paths[i]
|
||||
shortestLen = vlen
|
||||
@ -145,4 +145,3 @@ func hasKeyPath(crumb string, iv interface{}, key string, basket *map[string]boo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -12,83 +12,82 @@ func TestX2j(t *testing.T) {
|
||||
fmt.Println("\n=================== TestX2j ...")
|
||||
fi, fierr := os.Stat("x2j_test.xml")
|
||||
if fierr != nil {
|
||||
fmt.Println("fierr:",fierr.Error())
|
||||
fmt.Println("fierr:", fierr.Error())
|
||||
return
|
||||
}
|
||||
fh, fherr := os.Open("x2j_test.xml")
|
||||
if fherr != nil {
|
||||
fmt.Println("fherr:",fherr.Error())
|
||||
fmt.Println("fherr:", fherr.Error())
|
||||
return
|
||||
}
|
||||
defer fh.Close()
|
||||
buf := make([]byte,fi.Size())
|
||||
_, nerr := fh.Read(buf)
|
||||
buf := make([]byte, fi.Size())
|
||||
_, nerr := fh.Read(buf)
|
||||
if nerr != nil {
|
||||
fmt.Println("nerr:",nerr.Error())
|
||||
fmt.Println("nerr:", nerr.Error())
|
||||
return
|
||||
}
|
||||
doc := string(buf)
|
||||
fmt.Println("\nXML doc:\n",doc)
|
||||
fmt.Println("\nXML doc:\n", doc)
|
||||
|
||||
// test DocToMap() with recast
|
||||
mm, mmerr := DocToMap(doc,true)
|
||||
mm, mmerr := DocToMap(doc, true)
|
||||
if mmerr != nil {
|
||||
println("mmerr:",mmerr.Error())
|
||||
println("mmerr:", mmerr.Error())
|
||||
return
|
||||
}
|
||||
println("\nDocToMap(), recast==true:\n",WriteMap(mm))
|
||||
println("\nDocToMap(), recast==true:\n", WriteMap(mm))
|
||||
|
||||
// test DocToJsonIndent() with recast
|
||||
s,serr := DocToJsonIndent(doc,true)
|
||||
s, serr := DocToJsonIndent(doc, true)
|
||||
if serr != nil {
|
||||
fmt.Println("serr:",serr.Error())
|
||||
fmt.Println("serr:", serr.Error())
|
||||
}
|
||||
fmt.Println("\nDocToJsonIndent, recast==true:\n",s)
|
||||
fmt.Println("\nDocToJsonIndent, recast==true:\n", s)
|
||||
}
|
||||
|
||||
func TestGetValue(t *testing.T) {
|
||||
fmt.Println("\n=================== TestGetValue ...")
|
||||
// test MapValue()
|
||||
doc := `<entry><vars><foo>bar</foo><foo2><hello>world</hello></foo2></vars></entry>`
|
||||
fmt.Println("\nRead doc:",doc)
|
||||
fmt.Println("\nRead doc:", doc)
|
||||
fmt.Println("Looking for value: entry.vars")
|
||||
mm,mmerr := DocToMap(doc)
|
||||
mm, mmerr := DocToMap(doc)
|
||||
if mmerr != nil {
|
||||
fmt.Println("merr:",mmerr.Error())
|
||||
fmt.Println("merr:", mmerr.Error())
|
||||
}
|
||||
v,verr := MapValue(mm,"entry.vars",nil)
|
||||
v, verr := MapValue(mm, "entry.vars", nil)
|
||||
if verr != nil {
|
||||
fmt.Println("verr:",verr.Error())
|
||||
fmt.Println("verr:", verr.Error())
|
||||
} else {
|
||||
j, jerr := json.MarshalIndent(v,""," ")
|
||||
j, jerr := json.MarshalIndent(v, "", " ")
|
||||
if jerr != nil {
|
||||
fmt.Println("jerr:",jerr.Error())
|
||||
fmt.Println("jerr:", jerr.Error())
|
||||
} else {
|
||||
fmt.Println(string(j))
|
||||
}
|
||||
}
|
||||
fmt.Println("Looking for value: entry.vars.foo2.hello")
|
||||
v,verr = MapValue(mm,"entry.vars.foo2.hello",nil)
|
||||
v, verr = MapValue(mm, "entry.vars.foo2.hello", nil)
|
||||
if verr != nil {
|
||||
fmt.Println("verr:",verr.Error())
|
||||
fmt.Println("verr:", verr.Error())
|
||||
} else {
|
||||
fmt.Println(v.(string))
|
||||
}
|
||||
fmt.Println("Looking with error in path: entry.var")
|
||||
v,verr = MapValue(mm,"entry.var",nil)
|
||||
fmt.Println("verr:",verr.Error())
|
||||
v, verr = MapValue(mm, "entry.var", nil)
|
||||
fmt.Println("verr:", verr.Error())
|
||||
|
||||
// test DocValue()
|
||||
fmt.Println("DocValue() for tag path entry.vars")
|
||||
v,verr = DocValue(doc,"entry.vars")
|
||||
v, verr = DocValue(doc, "entry.vars")
|
||||
if verr != nil {
|
||||
fmt.Println("verr:",verr.Error())
|
||||
fmt.Println("verr:", verr.Error())
|
||||
}
|
||||
j,_ := json.MarshalIndent(v,""," ")
|
||||
j, _ := json.MarshalIndent(v, "", " ")
|
||||
fmt.Println(string(j))
|
||||
}
|
||||
|
||||
|
||||
func TestGetValueWithAttr(t *testing.T) {
|
||||
fmt.Println("\n=================== TestGetValueWithAttr ...")
|
||||
doc := `<entry><vars>
|
||||
@ -97,76 +96,76 @@ func TestGetValueWithAttr(t *testing.T) {
|
||||
<hello item="3">world</hello>
|
||||
<hello item="4">universe</hello>
|
||||
</foo></vars></entry>`
|
||||
fmt.Println("\nRead doc:",doc)
|
||||
fmt.Println("\nRead doc:", doc)
|
||||
fmt.Println("Looking for value: entry.vars")
|
||||
mm,mmerr := DocToMap(doc)
|
||||
mm, mmerr := DocToMap(doc)
|
||||
if mmerr != nil {
|
||||
fmt.Println("merr:",mmerr.Error())
|
||||
fmt.Println("merr:", mmerr.Error())
|
||||
}
|
||||
v,verr := MapValue(mm,"entry.vars",nil)
|
||||
v, verr := MapValue(mm, "entry.vars", nil)
|
||||
if verr != nil {
|
||||
fmt.Println("verr:",verr.Error())
|
||||
fmt.Println("verr:", verr.Error())
|
||||
} else {
|
||||
j, jerr := json.MarshalIndent(v,""," ")
|
||||
j, jerr := json.MarshalIndent(v, "", " ")
|
||||
if jerr != nil {
|
||||
fmt.Println("jerr:",jerr.Error())
|
||||
fmt.Println("jerr:", jerr.Error())
|
||||
} else {
|
||||
fmt.Println(string(j))
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("\nMapValue(): Looking for value: entry.vars.foo item=2")
|
||||
a,aerr := NewAttributeMap("item:2")
|
||||
a, aerr := NewAttributeMap("item:2")
|
||||
if aerr != nil {
|
||||
fmt.Println("aerr:",aerr.Error())
|
||||
fmt.Println("aerr:", aerr.Error())
|
||||
}
|
||||
v,verr = MapValue(mm,"entry.vars.foo",a)
|
||||
v, verr = MapValue(mm, "entry.vars.foo", a)
|
||||
if verr != nil {
|
||||
fmt.Println("verr:",verr.Error())
|
||||
fmt.Println("verr:", verr.Error())
|
||||
} else {
|
||||
j, jerr := json.MarshalIndent(v,""," ")
|
||||
j, jerr := json.MarshalIndent(v, "", " ")
|
||||
if jerr != nil {
|
||||
fmt.Println("jerr:",jerr.Error())
|
||||
fmt.Println("jerr:", jerr.Error())
|
||||
} else {
|
||||
fmt.Println(string(j))
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("\nMapValue(): Looking for hello item:4")
|
||||
a,_ = NewAttributeMap("item:4")
|
||||
v,verr = MapValue(mm,"hello",a)
|
||||
a, _ = NewAttributeMap("item:4")
|
||||
v, verr = MapValue(mm, "hello", a)
|
||||
if verr != nil {
|
||||
fmt.Println("verr:",verr.Error())
|
||||
fmt.Println("verr:", verr.Error())
|
||||
} else {
|
||||
j, jerr := json.MarshalIndent(v,""," ")
|
||||
j, jerr := json.MarshalIndent(v, "", " ")
|
||||
if jerr != nil {
|
||||
fmt.Println("jerr:",jerr.Error())
|
||||
fmt.Println("jerr:", jerr.Error())
|
||||
} else {
|
||||
fmt.Println(string(j))
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("\nDocValue(): Looking for entry.vars.foo.hello item:4")
|
||||
v,verr = DocValue(doc,"entry.vars.foo.hello","item:4")
|
||||
v, verr = DocValue(doc, "entry.vars.foo.hello", "item:4")
|
||||
if verr != nil {
|
||||
fmt.Println("verr:",verr.Error())
|
||||
fmt.Println("verr:", verr.Error())
|
||||
} else {
|
||||
j, jerr := json.MarshalIndent(v,""," ")
|
||||
j, jerr := json.MarshalIndent(v, "", " ")
|
||||
if jerr != nil {
|
||||
fmt.Println("jerr:",jerr.Error())
|
||||
fmt.Println("jerr:", jerr.Error())
|
||||
} else {
|
||||
fmt.Println(string(j))
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("\nDocValue(): Looking for empty nil")
|
||||
v,verr = DocValue(doc,"")
|
||||
v, verr = DocValue(doc, "")
|
||||
if verr != nil {
|
||||
fmt.Println("verr:",verr.Error())
|
||||
fmt.Println("verr:", verr.Error())
|
||||
} else {
|
||||
j, jerr := json.MarshalIndent(v,""," ")
|
||||
j, jerr := json.MarshalIndent(v, "", " ")
|
||||
if jerr != nil {
|
||||
fmt.Println("jerr:",jerr.Error())
|
||||
fmt.Println("jerr:", jerr.Error())
|
||||
} else {
|
||||
fmt.Println(string(j))
|
||||
}
|
||||
@ -174,22 +173,22 @@ func TestGetValueWithAttr(t *testing.T) {
|
||||
|
||||
// test 'recast' switch
|
||||
fmt.Println("\ntesting recast switch...")
|
||||
mm,mmerr = DocToMap(doc,true)
|
||||
mm, mmerr = DocToMap(doc, true)
|
||||
if mmerr != nil {
|
||||
fmt.Println("merr:",mmerr.Error())
|
||||
fmt.Println("merr:", mmerr.Error())
|
||||
}
|
||||
fmt.Println("MapValue(): Looking for value: entry.vars.foo item=2")
|
||||
a,aerr = NewAttributeMap("item:2")
|
||||
a, aerr = NewAttributeMap("item:2")
|
||||
if aerr != nil {
|
||||
fmt.Println("aerr:",aerr.Error())
|
||||
fmt.Println("aerr:", aerr.Error())
|
||||
}
|
||||
v,verr = MapValue(mm,"entry.vars.foo",a,true)
|
||||
v, verr = MapValue(mm, "entry.vars.foo", a, true)
|
||||
if verr != nil {
|
||||
fmt.Println("verr:",verr.Error())
|
||||
fmt.Println("verr:", verr.Error())
|
||||
} else {
|
||||
j, jerr := json.MarshalIndent(v,""," ")
|
||||
j, jerr := json.MarshalIndent(v, "", " ")
|
||||
if jerr != nil {
|
||||
fmt.Println("jerr:",jerr.Error())
|
||||
fmt.Println("jerr:", jerr.Error())
|
||||
} else {
|
||||
fmt.Println(string(j))
|
||||
}
|
||||
@ -205,34 +204,34 @@ func TestStuff_1(t *testing.T) {
|
||||
</doc>`
|
||||
|
||||
fmt.Println(doc)
|
||||
m,merr := DocToMap(doc)
|
||||
m, merr := DocToMap(doc)
|
||||
if merr != nil {
|
||||
fmt.Println("merr:",merr.Error())
|
||||
fmt.Println("merr:", merr.Error())
|
||||
} else {
|
||||
fmt.Println(WriteMap(m))
|
||||
}
|
||||
|
||||
fmt.Println("\nDocValue(): tag")
|
||||
v,verr := DocValue(doc,"doc.tag")
|
||||
v, verr := DocValue(doc, "doc.tag")
|
||||
if verr != nil {
|
||||
fmt.Println("verr:",verr.Error())
|
||||
fmt.Println("verr:", verr.Error())
|
||||
} else {
|
||||
j, jerr := json.MarshalIndent(v,""," ")
|
||||
j, jerr := json.MarshalIndent(v, "", " ")
|
||||
if jerr != nil {
|
||||
fmt.Println("jerr:",jerr.Error())
|
||||
fmt.Println("jerr:", jerr.Error())
|
||||
} else {
|
||||
fmt.Println(string(j))
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("\nDocValue(): item:2 instance:2")
|
||||
v,verr = DocValue(doc,"doc.tag","item:2","instance:2")
|
||||
v, verr = DocValue(doc, "doc.tag", "item:2", "instance:2")
|
||||
if verr != nil {
|
||||
fmt.Println("verr:",verr.Error())
|
||||
fmt.Println("verr:", verr.Error())
|
||||
} else {
|
||||
j, jerr := json.MarshalIndent(v,""," ")
|
||||
j, jerr := json.MarshalIndent(v, "", " ")
|
||||
if jerr != nil {
|
||||
fmt.Println("jerr:",jerr.Error())
|
||||
fmt.Println("jerr:", jerr.Error())
|
||||
} else {
|
||||
fmt.Println(string(j))
|
||||
}
|
||||
@ -247,34 +246,34 @@ func TestStuff_2(t *testing.T) {
|
||||
<tag item="2" instance="2">val3</tag>`
|
||||
|
||||
fmt.Println(doc)
|
||||
m,merr := DocToMap(doc)
|
||||
m, merr := DocToMap(doc)
|
||||
if merr != nil {
|
||||
fmt.Println("merr:",merr.Error())
|
||||
fmt.Println("merr:", merr.Error())
|
||||
} else {
|
||||
fmt.Println(WriteMap(m))
|
||||
}
|
||||
|
||||
fmt.Println("\nDocValue(): tag")
|
||||
v,verr := DocValue(doc,"tag")
|
||||
v, verr := DocValue(doc, "tag")
|
||||
if verr != nil {
|
||||
fmt.Println("verr:",verr.Error())
|
||||
fmt.Println("verr:", verr.Error())
|
||||
} else {
|
||||
j, jerr := json.MarshalIndent(v,""," ")
|
||||
j, jerr := json.MarshalIndent(v, "", " ")
|
||||
if jerr != nil {
|
||||
fmt.Println("jerr:",jerr.Error())
|
||||
fmt.Println("jerr:", jerr.Error())
|
||||
} else {
|
||||
fmt.Println(string(j))
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("\nDocValue(): item:2 instance:2")
|
||||
v,verr = DocValue(doc,"tag","item:2","instance:2")
|
||||
v, verr = DocValue(doc, "tag", "item:2", "instance:2")
|
||||
if verr != nil {
|
||||
fmt.Println("verr:",verr.Error())
|
||||
fmt.Println("verr:", verr.Error())
|
||||
} else {
|
||||
j, jerr := json.MarshalIndent(v,""," ")
|
||||
j, jerr := json.MarshalIndent(v, "", " ")
|
||||
if jerr != nil {
|
||||
fmt.Println("jerr:",jerr.Error())
|
||||
fmt.Println("jerr:", jerr.Error())
|
||||
} else {
|
||||
fmt.Println(string(j))
|
||||
}
|
||||
@ -282,18 +281,18 @@ func TestStuff_2(t *testing.T) {
|
||||
}
|
||||
|
||||
func procMap(m map[string]interface{}) bool {
|
||||
fmt.Println("procMap:",WriteMap(m))
|
||||
fmt.Println("procMap:", WriteMap(m))
|
||||
return true
|
||||
}
|
||||
|
||||
func procMapToJson(m map[string]interface{}) bool {
|
||||
b,_ := json.MarshalIndent(m,""," ")
|
||||
fmt.Println("procMap:",string(b))
|
||||
b, _ := json.MarshalIndent(m, "", " ")
|
||||
fmt.Println("procMap:", string(b))
|
||||
return true
|
||||
}
|
||||
|
||||
func procErr(err error) bool {
|
||||
fmt.Println("procError err:",err.Error())
|
||||
fmt.Println("procError err:", err.Error())
|
||||
return true
|
||||
}
|
||||
|
||||
@ -301,8 +300,8 @@ func TestBulk(t *testing.T) {
|
||||
fmt.Println("\n=================== TestBulkBuffer ...")
|
||||
fmt.Println("\nBulk Message Processing Tests")
|
||||
// if err := XmlMsgsFromFile("x2m_bulk.xml",procMap,procErr); err != nil {
|
||||
if err := XmlMsgsFromFile("x2m_bulk.xml",procMapToJson,procErr); err != nil {
|
||||
fmt.Println("XmlMsgsFromFile err:",err.Error())
|
||||
if err := XmlMsgsFromFile("x2m_bulk.xml", procMapToJson, procErr); err != nil {
|
||||
fmt.Println("XmlMsgsFromFile err:", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,31 +328,31 @@ func TestTagAndKey(t *testing.T) {
|
||||
</partitions>
|
||||
</doc>`
|
||||
|
||||
fmt.Println("\nTestTagAndKey()\n",doc)
|
||||
v,verr := ValuesForTag(doc,"parts")
|
||||
fmt.Println("\nTestTagAndKey()\n", doc)
|
||||
v, verr := ValuesForTag(doc, "parts")
|
||||
if verr != nil {
|
||||
fmt.Println("verr:",verr.Error())
|
||||
fmt.Println("verr:", verr.Error())
|
||||
}
|
||||
fmt.Println("tag: parts :: len:",len(v),"v:",v)
|
||||
v, _ = ValuesForTag(doc,"not_a_tag")
|
||||
fmt.Println("tag: parts :: len:", len(v), "v:", v)
|
||||
v, _ = ValuesForTag(doc, "not_a_tag")
|
||||
if v == nil {
|
||||
fmt.Println("no 'not_a_tag' tag")
|
||||
} else {
|
||||
fmt.Println("key: not_a_tag :: len:",len(v),"v:",v)
|
||||
fmt.Println("key: not_a_tag :: len:", len(v), "v:", v)
|
||||
}
|
||||
|
||||
m,merr := DocToMap(doc)
|
||||
m, merr := DocToMap(doc)
|
||||
if merr != nil {
|
||||
fmt.Println("merr:",merr.Error())
|
||||
fmt.Println("merr:", merr.Error())
|
||||
}
|
||||
v = ValuesForKey(m,"section")
|
||||
fmt.Println("key: section :: len:",len(v),"v:",v)
|
||||
v = ValuesForKey(m, "section")
|
||||
fmt.Println("key: section :: len:", len(v), "v:", v)
|
||||
|
||||
v = ValuesForKey(m,"not_a_key")
|
||||
v = ValuesForKey(m, "not_a_key")
|
||||
if v == nil {
|
||||
fmt.Println("no 'not_a_key' key")
|
||||
} else {
|
||||
fmt.Println("key: not_a-key :: len:",len(v),"v:",v)
|
||||
fmt.Println("key: not_a-key :: len:", len(v), "v:", v)
|
||||
}
|
||||
}
|
||||
|
||||
@ -377,7 +376,7 @@ func Test_F_DocToMap(t *testing.T) {
|
||||
<section>two</section>
|
||||
</sections>
|
||||
</parts>
|
||||
</partitions>
|
||||
</partitions>
|
||||
</doc>`
|
||||
fmt.Println("\nF_DocToMap()")
|
||||
fmt.Println(doc)
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file
|
||||
|
||||
// x2j_valuesAt.go: Extract values from an arbitrary XML doc that are at same level as "key".
|
||||
// x2j_valuesAt.go: Extract values from an arbitrary XML doc that are at same level as "key".
|
||||
// Tag path can include wildcard characters.
|
||||
|
||||
package x2j
|
||||
@ -42,7 +42,7 @@ func ValuesAtTagPath(doc, path string, getAttrs ...bool) ([]interface{}, error)
|
||||
}
|
||||
|
||||
// ValuesAtKeyPath - deliver all values at the same depth in a map[string]interface{} value
|
||||
// If v := ValuesAtKeyPath(m,"x.y.z")
|
||||
// If v := ValuesAtKeyPath(m,"x.y.z")
|
||||
// then there exists a _,vv := range v
|
||||
// such that v.(map[string]interface{})[z] == ValuesFromKeyPath(m,"x.y.z")
|
||||
// If there are no values for the path 'nil' is returned.
|
||||
@ -66,7 +66,7 @@ func ValuesAtKeyPath(m map[string]interface{}, path string, getAttrs ...bool) []
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
ret = append(ret,interface{}(m))
|
||||
ret = append(ret, interface{}(m))
|
||||
}
|
||||
|
||||
// scan the value set and see if key occurs
|
||||
@ -87,4 +87,3 @@ func ValuesAtKeyPath(m map[string]interface{}, path string, getAttrs ...bool) []
|
||||
// no instance of key in penultimate value set
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -85,49 +85,49 @@ func TestValuesAtKeyPath(t *testing.T) {
|
||||
fmt.Println("\n=============== TestValuesAtKeyPath ...")
|
||||
fmt.Println("\nValuesAtKeyPath ... doc1#author")
|
||||
m, _ := DocToMap(doc1)
|
||||
ss := PathsForKey(m,"author")
|
||||
ss := PathsForKey(m, "author")
|
||||
fmt.Println("ss:", ss)
|
||||
for _,v := range ss {
|
||||
vv := ValuesAtKeyPath(m,v,true)
|
||||
for _, v := range ss {
|
||||
vv := ValuesAtKeyPath(m, v, true)
|
||||
fmt.Println("vv:", vv)
|
||||
}
|
||||
|
||||
fmt.Println("\nValuesAtKeyPath ... doc1#first_name")
|
||||
// m, _ := DocToMap(doc1)
|
||||
ss = PathsForKey(m,"first_name")
|
||||
ss = PathsForKey(m, "first_name")
|
||||
fmt.Println("ss:", ss)
|
||||
for _,v := range ss {
|
||||
vv := ValuesAtKeyPath(m,v,true)
|
||||
for _, v := range ss {
|
||||
vv := ValuesAtKeyPath(m, v, true)
|
||||
fmt.Println("vv:", vv)
|
||||
}
|
||||
|
||||
fmt.Println("\nGetKeyPaths...doc2#book")
|
||||
m, _ = DocToMap(doc2)
|
||||
ss = PathsForKey(m,"book")
|
||||
ss = PathsForKey(m, "book")
|
||||
fmt.Println("ss:", ss)
|
||||
for _,v := range ss {
|
||||
vv := ValuesAtKeyPath(m,v,true)
|
||||
for _, v := range ss {
|
||||
vv := ValuesAtKeyPath(m, v, true)
|
||||
fmt.Println("vv:", vv)
|
||||
}
|
||||
s := PathForKeyShortest(m,"book")
|
||||
vv := ValuesAtKeyPath(m,s)
|
||||
fmt.Println("vv,shortest_path:",vv)
|
||||
s := PathForKeyShortest(m, "book")
|
||||
vv := ValuesAtKeyPath(m, s)
|
||||
fmt.Println("vv,shortest_path:", vv)
|
||||
|
||||
fmt.Println("\nValuesAtKeyPath ... msg1#pub")
|
||||
m, _ = DocToMap(msg1)
|
||||
ss = PathsForKey(m,"pub")
|
||||
ss = PathsForKey(m, "pub")
|
||||
fmt.Println("ss:", ss)
|
||||
for _,v := range ss {
|
||||
vv := ValuesAtKeyPath(m,v,true)
|
||||
for _, v := range ss {
|
||||
vv := ValuesAtKeyPath(m, v, true)
|
||||
fmt.Println("vv:", vv)
|
||||
}
|
||||
|
||||
fmt.Println("\nValuesAtKeyPath ... msg2#pub")
|
||||
m, _ = DocToMap(msg2)
|
||||
ss = PathsForKey(m,"pub")
|
||||
ss = PathsForKey(m, "pub")
|
||||
fmt.Println("ss:", ss)
|
||||
for _,v := range ss {
|
||||
vv := ValuesAtKeyPath(m,v,true)
|
||||
for _, v := range ss {
|
||||
vv := ValuesAtKeyPath(m, v, true)
|
||||
fmt.Println("vv:", vv)
|
||||
}
|
||||
}
|
||||
@ -136,32 +136,31 @@ func TestValuesAtTagPath(t *testing.T) {
|
||||
fmt.Println("\n=============== TestValuesAtTagPath ...")
|
||||
fmt.Println("\nValuesAtTagPath ... doc1#author")
|
||||
m, _ := DocToMap(doc1)
|
||||
ss := PathsForKey(m,"author")
|
||||
ss := PathsForKey(m, "author")
|
||||
fmt.Println("ss:", ss)
|
||||
for _,v := range ss {
|
||||
vv,_ := ValuesAtTagPath(doc1,v,true)
|
||||
for _, v := range ss {
|
||||
vv, _ := ValuesAtTagPath(doc1, v, true)
|
||||
fmt.Println("vv:", vv)
|
||||
}
|
||||
|
||||
fmt.Println("\nValuesAtTagPath ... doc1#first_name")
|
||||
// m, _ := DocToMap(doc1)
|
||||
ss = PathsForKey(m,"first_name")
|
||||
ss = PathsForKey(m, "first_name")
|
||||
fmt.Println("ss:", ss)
|
||||
for _,v := range ss {
|
||||
vv,_ := ValuesAtTagPath(doc1,v,true)
|
||||
for _, v := range ss {
|
||||
vv, _ := ValuesAtTagPath(doc1, v, true)
|
||||
fmt.Println("vv:", vv)
|
||||
}
|
||||
|
||||
fmt.Println("\nValuesAtTagPath...doc2#book")
|
||||
m, _ = DocToMap(doc2)
|
||||
ss = PathsForKey(m,"book")
|
||||
ss = PathsForKey(m, "book")
|
||||
fmt.Println("ss:", ss)
|
||||
for _,v := range ss {
|
||||
vv,_ := ValuesAtTagPath(doc2,v,true)
|
||||
for _, v := range ss {
|
||||
vv, _ := ValuesAtTagPath(doc2, v, true)
|
||||
fmt.Println("vv:", vv)
|
||||
}
|
||||
s := PathForKeyShortest(m,"book")
|
||||
vv,_ := ValuesAtTagPath(doc2,s)
|
||||
fmt.Println("vv,shortest_path:",vv)
|
||||
s := PathForKeyShortest(m, "book")
|
||||
vv, _ := ValuesAtTagPath(doc2, s)
|
||||
fmt.Println("vv,shortest_path:", vv)
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import (
|
||||
|
||||
// the basic demo/test case - a small bibliography with mixed element types
|
||||
func TestValuesFromTagPath(t *testing.T) {
|
||||
var doc = `
|
||||
var doc = `
|
||||
<doc>
|
||||
<books>
|
||||
<book seq="1">
|
||||
@ -36,7 +36,7 @@ var doc = `
|
||||
</books>
|
||||
</doc>
|
||||
`
|
||||
var doc2 = `
|
||||
var doc2 = `
|
||||
<doc>
|
||||
<books>
|
||||
<book seq="1">
|
||||
@ -47,82 +47,82 @@ var doc2 = `
|
||||
</books>
|
||||
</doc>
|
||||
`
|
||||
fmt.Println("\nTestValuesFromTagPath()\n",doc)
|
||||
fmt.Println("\nTestValuesFromTagPath()\n", doc)
|
||||
|
||||
m,_ := DocToMap(doc)
|
||||
fmt.Println("map:",WriteMap(m))
|
||||
m, _ := DocToMap(doc)
|
||||
fmt.Println("map:", WriteMap(m))
|
||||
|
||||
v,_ := ValuesFromTagPath(doc,"doc.books")
|
||||
fmt.Println("path == doc.books: len(v):",len(v))
|
||||
for key,val := range v {
|
||||
fmt.Println(key,":",val)
|
||||
v, _ := ValuesFromTagPath(doc, "doc.books")
|
||||
fmt.Println("path == doc.books: len(v):", len(v))
|
||||
for key, val := range v {
|
||||
fmt.Println(key, ":", val)
|
||||
}
|
||||
|
||||
v,_ = ValuesFromTagPath(doc,"doc.books.*")
|
||||
fmt.Println("path == doc.books.*: len(v):",len(v))
|
||||
for key,val := range v {
|
||||
fmt.Println(key,":",val)
|
||||
v, _ = ValuesFromTagPath(doc, "doc.books.*")
|
||||
fmt.Println("path == doc.books.*: len(v):", len(v))
|
||||
for key, val := range v {
|
||||
fmt.Println(key, ":", val)
|
||||
}
|
||||
|
||||
v,_ = ValuesFromTagPath(doc,"doc.books.book")
|
||||
fmt.Println("path == doc.books.book: len(v):",len(v))
|
||||
for key,val := range v {
|
||||
fmt.Println(key,":",val)
|
||||
v, _ = ValuesFromTagPath(doc, "doc.books.book")
|
||||
fmt.Println("path == doc.books.book: len(v):", len(v))
|
||||
for key, val := range v {
|
||||
fmt.Println(key, ":", val)
|
||||
}
|
||||
|
||||
v,_ = ValuesFromTagPath(doc2,"doc.books.book")
|
||||
fmt.Println("doc == doc2 / path == doc.books.book: len(v):",len(v))
|
||||
for key,val := range v {
|
||||
fmt.Println(key,":",val)
|
||||
v, _ = ValuesFromTagPath(doc2, "doc.books.book")
|
||||
fmt.Println("doc == doc2 / path == doc.books.book: len(v):", len(v))
|
||||
for key, val := range v {
|
||||
fmt.Println(key, ":", val)
|
||||
}
|
||||
|
||||
v,_ = ValuesFromTagPath(doc,"doc.books.book.*")
|
||||
fmt.Println("path == doc.books.book.*: len(v):",len(v))
|
||||
for key,val := range v {
|
||||
fmt.Println(key,":",val)
|
||||
v, _ = ValuesFromTagPath(doc, "doc.books.book.*")
|
||||
fmt.Println("path == doc.books.book.*: len(v):", len(v))
|
||||
for key, val := range v {
|
||||
fmt.Println(key, ":", val)
|
||||
}
|
||||
|
||||
v,_ = ValuesFromTagPath(doc2,"doc.books.book.*")
|
||||
fmt.Println("doc == doc2 / path == doc.books.book.*: len(v):",len(v))
|
||||
for key,val := range v {
|
||||
fmt.Println(key,":",val)
|
||||
v, _ = ValuesFromTagPath(doc2, "doc.books.book.*")
|
||||
fmt.Println("doc == doc2 / path == doc.books.book.*: len(v):", len(v))
|
||||
for key, val := range v {
|
||||
fmt.Println(key, ":", val)
|
||||
}
|
||||
|
||||
v,_ = ValuesFromTagPath(doc,"doc.books.*.author")
|
||||
fmt.Println("path == doc.books.*.author: len(v):",len(v))
|
||||
for key,val := range v {
|
||||
fmt.Println(key,":",val)
|
||||
v, _ = ValuesFromTagPath(doc, "doc.books.*.author")
|
||||
fmt.Println("path == doc.books.*.author: len(v):", len(v))
|
||||
for key, val := range v {
|
||||
fmt.Println(key, ":", val)
|
||||
}
|
||||
|
||||
v,_ = ValuesFromTagPath(doc,"doc.*.*.author")
|
||||
fmt.Println("path == doc.*.*.author: len(v):",len(v))
|
||||
for key,val := range v {
|
||||
fmt.Println(key,":",val)
|
||||
v, _ = ValuesFromTagPath(doc, "doc.*.*.author")
|
||||
fmt.Println("path == doc.*.*.author: len(v):", len(v))
|
||||
for key, val := range v {
|
||||
fmt.Println(key, ":", val)
|
||||
}
|
||||
|
||||
v,_ = ValuesFromTagPath(doc,"doc.*.*.title")
|
||||
fmt.Println("path == doc.*.*.title: len(v):",len(v))
|
||||
for key,val := range v {
|
||||
fmt.Println(key,":",val)
|
||||
v, _ = ValuesFromTagPath(doc, "doc.*.*.title")
|
||||
fmt.Println("path == doc.*.*.title: len(v):", len(v))
|
||||
for key, val := range v {
|
||||
fmt.Println(key, ":", val)
|
||||
}
|
||||
|
||||
v,_ = ValuesFromTagPath(doc,"doc.*.*.*")
|
||||
fmt.Println("path == doc.*.*.*: len(v):",len(v))
|
||||
for key,val := range v {
|
||||
fmt.Println(key,":",val)
|
||||
v, _ = ValuesFromTagPath(doc, "doc.*.*.*")
|
||||
fmt.Println("path == doc.*.*.*: len(v):", len(v))
|
||||
for key, val := range v {
|
||||
fmt.Println(key, ":", val)
|
||||
}
|
||||
|
||||
v,_ = ValuesFromTagPath(doc,"doc.*.*.*.*")
|
||||
fmt.Println("path == doc.*.*.*.*: len(v):",len(v))
|
||||
for key,val := range v {
|
||||
fmt.Println(key,":",val)
|
||||
v, _ = ValuesFromTagPath(doc, "doc.*.*.*.*")
|
||||
fmt.Println("path == doc.*.*.*.*: len(v):", len(v))
|
||||
for key, val := range v {
|
||||
fmt.Println(key, ":", val)
|
||||
}
|
||||
}
|
||||
|
||||
// demo how to compensate for irregular tag labels in data
|
||||
// "netid" vs. "idnet"
|
||||
func TestValuesFromTagPath2(t *testing.T) {
|
||||
var doc1 = `
|
||||
var doc1 = `
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<data>
|
||||
<netid>
|
||||
@ -132,7 +132,7 @@ var doc1 = `
|
||||
</netid>
|
||||
</data>
|
||||
`
|
||||
var doc2 = `
|
||||
var doc2 = `
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<data>
|
||||
<idnet>
|
||||
@ -142,28 +142,27 @@ var doc2 = `
|
||||
</idnet>
|
||||
</data>
|
||||
`
|
||||
var docs = []string{doc1,doc2}
|
||||
var docs = []string{doc1, doc2}
|
||||
|
||||
for n,doc := range docs {
|
||||
fmt.Println("\nTestValuesFromTagPath2(), iteration:",n,"\n",doc)
|
||||
for n, doc := range docs {
|
||||
fmt.Println("\nTestValuesFromTagPath2(), iteration:", n, "\n", doc)
|
||||
|
||||
m,_ := DocToMap(doc)
|
||||
fmt.Println("map:",WriteMap(m))
|
||||
m, _ := DocToMap(doc)
|
||||
fmt.Println("map:", WriteMap(m))
|
||||
|
||||
v,_ := ValuesFromTagPath(doc,"data.*")
|
||||
fmt.Println("\npath == data.*: len(v):",len(v))
|
||||
for key,val := range v {
|
||||
fmt.Println(key,":",val)
|
||||
v, _ := ValuesFromTagPath(doc, "data.*")
|
||||
fmt.Println("\npath == data.*: len(v):", len(v))
|
||||
for key, val := range v {
|
||||
fmt.Println(key, ":", val)
|
||||
}
|
||||
for key,val := range v[0].(map[string]interface{}) {
|
||||
fmt.Println("\t",key,":",val)
|
||||
for key, val := range v[0].(map[string]interface{}) {
|
||||
fmt.Println("\t", key, ":", val)
|
||||
}
|
||||
|
||||
v,_ = ValuesFromTagPath(doc,"data.*.*")
|
||||
fmt.Println("\npath == data.*.*: len(v):",len(v))
|
||||
for key,val := range v {
|
||||
fmt.Println(key,":",val)
|
||||
v, _ = ValuesFromTagPath(doc, "data.*.*")
|
||||
fmt.Println("\npath == data.*.*: len(v):", len(v))
|
||||
for key, val := range v {
|
||||
fmt.Println(key, ":", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,46 +1,46 @@
|
||||
package x2j
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"testing"
|
||||
"encoding/xml"
|
||||
)
|
||||
|
||||
func TestUnmarshal(t *testing.T) {
|
||||
var doc = []byte(`<doc> <name>Mayer Hawthorne</name> <song> <title>A Long Time</title> <verse no="1"> <line no="1">Henry was a renegade</line> <line no="2">Didn't like to play it safe</line> </verse> </song> </doc>`)
|
||||
|
||||
fmt.Println("\nUnmarshal test ... *map[string]interface{}, *string")
|
||||
m := make(map[string]interface{},0)
|
||||
err := Unmarshal(doc,&m)
|
||||
m := make(map[string]interface{}, 0)
|
||||
err := Unmarshal(doc, &m)
|
||||
if err != nil {
|
||||
fmt.Println("err:",err.Error())
|
||||
fmt.Println("err:", err.Error())
|
||||
}
|
||||
fmt.Println("m:",m)
|
||||
fmt.Println("m:", m)
|
||||
|
||||
var s string
|
||||
err = Unmarshal(doc,&s)
|
||||
err = Unmarshal(doc, &s)
|
||||
if err != nil {
|
||||
fmt.Println("err:",err.Error())
|
||||
fmt.Println("err:", err.Error())
|
||||
}
|
||||
fmt.Println("s:",s)
|
||||
fmt.Println("s:", s)
|
||||
}
|
||||
|
||||
func TestStructValue(t *testing.T) {
|
||||
var doc = []byte(`<info><name>clbanning</name><address>unknown</address></info>`)
|
||||
type Info struct {
|
||||
XMLName xml.Name `xml:"info"`
|
||||
Name string `xml:"name"`
|
||||
Name string `xml:"name"`
|
||||
Address string `xml:"address"`
|
||||
}
|
||||
|
||||
var myInfo Info
|
||||
|
||||
fmt.Println("\nUnmarshal test ... struct:",string(doc))
|
||||
err := Unmarshal(doc,&myInfo)
|
||||
fmt.Println("\nUnmarshal test ... struct:", string(doc))
|
||||
err := Unmarshal(doc, &myInfo)
|
||||
if err != nil {
|
||||
fmt.Println("err:",err.Error())
|
||||
fmt.Println("err:", err.Error())
|
||||
} else {
|
||||
fmt.Printf("myInfo: %+v\n",myInfo)
|
||||
fmt.Printf("myInfo: %+v\n", myInfo)
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,10 +48,10 @@ func TestMapValue(t *testing.T) {
|
||||
var doc = `<doc> <name>Mayer Hawthorne</name> <song> <title>A Long Time</title> <verse no="1"> <line no="1">Henry was a renegade</line> <line no="2">Didn't like to play it safe</line> </verse> </song> </doc>`
|
||||
|
||||
fmt.Println("\nTestMapValue of doc.song.verse w/ len(attrs) == 0.")
|
||||
fmt.Println("doc:",doc)
|
||||
v,err := DocValue(doc,"doc.song.verse")
|
||||
fmt.Println("doc:", doc)
|
||||
v, err := DocValue(doc, "doc.song.verse")
|
||||
if err != nil {
|
||||
fmt.Println("err:",err.Error())
|
||||
fmt.Println("err:", err.Error())
|
||||
}
|
||||
fmt.Println("result:",v)
|
||||
fmt.Println("result:", v)
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ import (
|
||||
// Note: phandler() and ehandler() 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 arguments to a go routine in handler and return true.
|
||||
func XmlMsgsFromFile(fname string, phandler func(map[string]interface{})(bool), ehandler func(error)(bool), recast ...bool) error {
|
||||
func XmlMsgsFromFile(fname string, phandler func(map[string]interface{}) bool, ehandler func(error) bool, recast ...bool) error {
|
||||
var r bool
|
||||
if len(recast) == 1 {
|
||||
r = recast[0]
|
||||
@ -36,26 +36,26 @@ func XmlMsgsFromFile(fname string, phandler func(map[string]interface{})(bool),
|
||||
return fherr
|
||||
}
|
||||
defer fh.Close()
|
||||
buf := make([]byte,fi.Size())
|
||||
_, rerr := fh.Read(buf)
|
||||
buf := make([]byte, fi.Size())
|
||||
_, rerr := fh.Read(buf)
|
||||
if rerr != nil {
|
||||
return rerr
|
||||
}
|
||||
doc := string(buf)
|
||||
|
||||
// xml.Decoder doesn't properly handle whitespace in some doc
|
||||
// see songTextString.xml test case ...
|
||||
reg,_ := regexp.Compile("[ \t\n\r]*<")
|
||||
doc = reg.ReplaceAllString(doc,"<")
|
||||
// see songTextString.xml test case ...
|
||||
reg, _ := regexp.Compile("[ \t\n\r]*<")
|
||||
doc = reg.ReplaceAllString(doc, "<")
|
||||
b := bytes.NewBufferString(doc)
|
||||
|
||||
for {
|
||||
m, merr := mxj.NewMapXmlReader(b,r)
|
||||
m, merr := mxj.NewMapXmlReader(b, r)
|
||||
if merr != nil && merr != io.EOF {
|
||||
if ok := ehandler(merr); !ok {
|
||||
// caused reader termination
|
||||
return merr
|
||||
}
|
||||
}
|
||||
}
|
||||
if m != nil {
|
||||
if ok := phandler(m); !ok {
|
||||
@ -72,7 +72,7 @@ func XmlMsgsFromFile(fname string, phandler func(map[string]interface{})(bool),
|
||||
// XmlBufferToMap - process XML message from a bytes.Buffer
|
||||
// 'b' is the buffer
|
||||
// Optional argument 'recast' coerces map values to float64 or bool where possible.
|
||||
func XmlBufferToMap(b *bytes.Buffer,recast ...bool) (map[string]interface{},error) {
|
||||
func XmlBufferToMap(b *bytes.Buffer, recast ...bool) (map[string]interface{}, error) {
|
||||
var r bool
|
||||
if len(recast) == 1 {
|
||||
r = recast[0]
|
||||
@ -90,19 +90,19 @@ func XmlBufferToMap(b *bytes.Buffer,recast ...bool) (map[string]interface{},erro
|
||||
// Note: phandler() and ehandler() 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 arguments to a go routine in handler and return true.
|
||||
func XmlMsgsFromReader(rdr io.Reader, phandler func(map[string]interface{})(bool), ehandler func(error)(bool), recast ...bool) error {
|
||||
func XmlMsgsFromReader(rdr io.Reader, phandler func(map[string]interface{}) bool, ehandler func(error) bool, recast ...bool) error {
|
||||
var r bool
|
||||
if len(recast) == 1 {
|
||||
r = recast[0]
|
||||
}
|
||||
|
||||
for {
|
||||
m, merr := ToMap(rdr,r)
|
||||
m, merr := ToMap(rdr, r)
|
||||
if merr != nil && merr != io.EOF {
|
||||
if ok := ehandler(merr); !ok {
|
||||
// caused reader termination
|
||||
return merr
|
||||
}
|
||||
}
|
||||
}
|
||||
if m != nil {
|
||||
if ok := phandler(m); !ok {
|
||||
@ -115,4 +115,3 @@ func XmlMsgsFromReader(rdr io.Reader, phandler func(map[string]interface{})(bool
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -20,13 +20,10 @@ func TestNewMapXml(t *testing.T) {
|
||||
t.Fatal("merr:", merr.Error())
|
||||
}
|
||||
|
||||
want := Map{"root2":
|
||||
map[string]interface{}{
|
||||
"newtag":
|
||||
map[string]interface{}{"-newattr": "some_attr_value", "#text":"something more"},
|
||||
"list":
|
||||
map[string]interface{}{"-listattr":"val", "item":[]interface{}{"1", "2"}},
|
||||
}}
|
||||
want := Map{"root2": map[string]interface{}{
|
||||
"newtag": map[string]interface{}{"-newattr": "some_attr_value", "#text": "something more"},
|
||||
"list": map[string]interface{}{"-listattr": "val", "item": []interface{}{"1", "2"}},
|
||||
}}
|
||||
if !reflect.DeepEqual(mv, want) {
|
||||
fmt.Println("NewMapXml, x :", string(x))
|
||||
fmt.Printf("NewMapXml, mv : %#v\n", mv)
|
||||
@ -45,13 +42,10 @@ func TestAttrHyphenFalse(t *testing.T) {
|
||||
t.Fatal("merr:", merr.Error())
|
||||
}
|
||||
|
||||
want := Map{"root2":
|
||||
map[string]interface{}{
|
||||
"newtag":
|
||||
map[string]interface{}{"newattr": "some_attr_value", "#text":"something more"},
|
||||
"list":
|
||||
map[string]interface{}{"listattr":"val", "item":[]interface{}{"1", "2"}},
|
||||
}}
|
||||
want := Map{"root2": map[string]interface{}{
|
||||
"newtag": map[string]interface{}{"newattr": "some_attr_value", "#text": "something more"},
|
||||
"list": map[string]interface{}{"listattr": "val", "item": []interface{}{"1", "2"}},
|
||||
}}
|
||||
if !reflect.DeepEqual(mv, want) {
|
||||
fmt.Println("AttrHyphenFalse, x :", string(x))
|
||||
fmt.Printf("AttrHyphenFalse, mv : %#v\n", mv)
|
||||
@ -161,7 +155,6 @@ func TestXml_5(t *testing.T) {
|
||||
fmt.Println("Xml_5, x :", string(x))
|
||||
}
|
||||
|
||||
|
||||
func TestXml_Strings(t *testing.T) {
|
||||
mv := Map{"sometag": "some data", "strings": []string{"string1", "string2"}}
|
||||
|
||||
@ -174,7 +167,6 @@ func TestXml_Strings(t *testing.T) {
|
||||
fmt.Println("Xml_strings, x :", string(x))
|
||||
}
|
||||
|
||||
|
||||
func TestXmlWriter(t *testing.T) {
|
||||
mv := Map{"tag1": "some data", "tag2": "more data", "boolean": true, "float": 3.14159625}
|
||||
w := new(bytes.Buffer)
|
||||
@ -194,7 +186,6 @@ func TestXmlWriter(t *testing.T) {
|
||||
fmt.Println("XmlWriter, b :", string(b))
|
||||
}
|
||||
|
||||
|
||||
// -------------------------- XML Handler test cases -------------------------
|
||||
|
||||
/* tested in bulk_test.go ...
|
||||
|
||||
Reference in New Issue
Block a user