This commit is contained in:
John
2019-04-03 00:03:46 +08:00
parent 8a8fea1257
commit c4c7e6caf4
297 changed files with 5215 additions and 5350 deletions

View File

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

View File

@ -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.
}

View File

@ -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"

View File

@ -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 {

View File

@ -145,4 +145,3 @@ func TestMarshalPrefixUnderscore(t *testing.T) {
}
fmt.Println(string(x))
}

View File

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

View File

@ -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 '&amp;' will be re-escaped as '&amp;amp;'.
//
//
/*
The values are:
" &quot;
@ -26,7 +26,7 @@ func XMLEscapeChars(b bool) {
xmlEscapeChars = b
}
// Scan for '&' first, since 's' may contain "&amp;" that is parsed to "&amp;amp;"
// Scan for '&' first, since 's' may contain "&amp;" that is parsed to "&amp;amp;"
// - or "&lt;" that is parsed to "&amp;lt;".
var escapechars = [][2][]byte{
{[]byte(`&`), []byte(`&amp;`)},
@ -51,4 +51,3 @@ func escapeChars(s string) string {
}
return string(b)
}

View File

@ -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 {

View File

@ -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

View File

@ -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
}

View File

@ -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")
}
}
}

View File

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

View File

@ -44,4 +44,3 @@ func TestSetSubkeyFieldSeparator(t *testing.T) {
t.Fatal("|expecting: value 2; got:", vals[0].(map[string]interface{})["#text"])
}
}

View File

@ -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 {

View File

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

View File

@ -78,4 +78,3 @@ func TestCastNanInf(t *testing.T) {
}
fmt.Println("foo.bar:", v)
}

View File

@ -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

View File

@ -66,4 +66,3 @@ func TestStakeCase(t *testing.T) {
t.Fatal(string(x), "!=", data2)
}
}

View File

@ -27,4 +27,3 @@ func useCustomDecoder(d *xml.Decoder) {
d.CharsetReader = CustomDecoder.CharsetReader
d.DefaultSpace = CustomDecoder.DefaultSpace
}

View File

@ -10,24 +10,24 @@ func TestStrictModeXml(t *testing.T) {
fmt.Println("----------------- TestStrictModeXml ...")
data := []byte(`<document> <name>Bill & Hallett</name> <salute>Duc &amp; 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 &amp; 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")
}

View File

@ -8,7 +8,6 @@ import (
"encoding/json"
"errors"
"reflect"
// "github.com/gogf/gf/third/github.com/fatih/structs"
)

View File

@ -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))
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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
}
}
}

View File

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

View File

@ -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
}

View File

@ -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)
}

View File

@ -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)
}
}
}

View File

@ -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)
}

View File

@ -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
}

View File

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