Created
February 20, 2015 17:30
-
-
Save michaeljs1990/540fdd00aace78a44093 to your computer and use it in GitHub Desktop.
xml parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package parsing | |
import ( | |
"encoding/xml" | |
"io" | |
"log" | |
"reflect" | |
"code.google.com/p/go-charset/charset" | |
_ "code.google.com/p/go-charset/data" // | |
) | |
// StreamXML holds the chan that you will | |
// need to read your xml from. | |
type StreamXML struct { | |
Stream chan interface{} | |
Element string | |
} | |
// NewStreamXML returns a new StreamXML | |
// struct that will parse on tokens matching | |
// the passed in element and makes a stream | |
// of type x. Paincs on wront input types. | |
func NewStreamXML(element string) *StreamXML { | |
return &StreamXML{ | |
Stream: make(chan interface{}), | |
Element: element, | |
} | |
} | |
// StreamingDecode takes an io.Reader and marshals the | |
// value into a given structure | |
func (s *StreamXML) StreamingDecode(r io.Reader, x interface{}) { | |
if reflect.TypeOf(x).Elem().Kind() != reflect.Struct && | |
reflect.TypeOf(x).Kind() == reflect.Ptr { | |
panic("StreamingDecode expects a ptr to a struct for the second param") | |
} | |
decoder := xml.NewDecoder(r) | |
decoder.CharsetReader = charset.NewReader | |
for { | |
t, err := decoder.Token() | |
// This code is really just checking if | |
// err is signaling to us that we have | |
// hit the end of the file with io.EOF | |
if err != nil { | |
close(s.Stream) | |
break | |
} | |
switch e := t.(type) { | |
case xml.StartElement: | |
// Look for tokens that are the same as the passed in | |
// elem string and decode them into a struct | |
if e.Name.Local == s.Element { | |
err = decoder.DecodeElement(reflect.ValueOf(x).Interface(), &e) | |
if err != nil { | |
log.Printf("%s", err.Error()) | |
} | |
// send it down stream | |
s.Stream <- x | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment