// This methods reads the xml representation of a response // to a io.Writer. It is public mostly for debugging or alternate // communication. To call a remote function you should use // `xmlrpc.Call`. func ReadResponse(in io.Reader) (Response, os.Error) { p := tokenStream{xml.NewParser(in)} p.next(false) // Discard <methodResponse> t, err := p.next(false) if err != nil { return Response{}, err } resp, ok := t.(xml.StartElement) if !ok { return Response{}, error("Invalid Response") } switch strings.ToLower(resp.Name.Local) { case "fault": f, err := Fault{}.LoadXML(p.Parser) if err == nil { err = f.(Fault) } return Response{}, err case "params": p.next(false) // Eat <param> p.next(false) // Eat <value> a, err := parseMessage(p.Parser) return Response{a}, err } return Response{}, error("Invalid Response") }
func main() { log.SetPrefix("") log.SetFlags(0) flag.Parse() if flag.NArg() < 2 { log.Fatalf("usage: xmlenum FIRST_ELEMENT_NAME FILES*\n") } firstElementName := flag.Args()[0] filepaths := flag.Args()[1:] files := make([]*os.File, len(filepaths)) for i, fp := range filepaths { f, err := os.Open(fp) if err != nil { log.Fatalf("Couldn't open %s: %v\n", fp, err) } files[i] = f defer f.Close() } toplevel := TagMap{} for i, f := range files { p := xml.NewParser(f) err := start(p, firstElementName, toplevel) if err != nil && err != os.EOF { log.Fatalf("Couldn't parse %s: %v\n", filepaths[i], err) } } sortedPrint(toplevel, 0) }
// Parse the given html and return the root node of the document. // Parsing starts at the first StartToken and will ignore other stuff. func ParseHtml(h string) (root *Node, err os.Error) { trace("%s", h) r := strings.NewReader(h) parser := xml.NewParser(r) parser.Strict = false parser.AutoClose = xml.HTMLAutoClose parser.Entity = xml.HTMLEntity for { var tok xml.Token tok, err = parser.Token() if err != nil { error("Cannot find start node of html! %s", err.String()) return } switch tok.(type) { case xml.StartElement: debug("Starting parsing from %v", tok) root, err = parse(tok, parser, nil) if err != nil && strings.HasPrefix(err.String(), "Javascript: ") { h = removeJavascript(h) debug("Retrying parsing html without javascript.") root, err = ParseHtml(h) // last try... } trace("=========== Parser ==========\nConstructed Structure: \n" + root.HtmlRep(0)) trace("\n----------------------------\nRe-Constructed Html: \n" + root.Html() + "\n===============================") return } } return }
func DiscoverXml(id string) (*string, os.Error) { resp, _, err := http.Get(id) if err != nil { return nil, err } defer resp.Body.Close() parser := xml.NewParser(resp.Body) inURI := false for { t, err := parser.Token() if err != nil { return nil, err } switch tt := t.(type) { case xml.StartElement: if tt.Name.Local == "URI" { inURI = true } case xml.CharData: if inURI { s := string([]byte(tt)) return &s, nil } } } return nil, &DiscoveryError{str: "URI not found"} }
func (site *Site) GetRooms() { url := site.CampfireUrl("/rooms.xml") parsed_url := ParseURL(url) //fmt.Printf("Going to request URL: %s\n", parsedUrl.String()) response, err := http.Get(parsed_url.String()) if err != nil { log.Fatal(err) } defer response.Body.Close() if response.StatusCode != 200 { log.Printf("Status: %s\n", response.Status) log.Fatal("Could not list rooms") } parser := xml.NewParser(response.Body) rooms := Rooms{Room: nil} err = parser.Unmarshal(&rooms, nil) if err != nil { log.Fatal("Error unmarshalling xml:", err) } site.Rooms = rooms.Room fmt.Println("Rooms", rooms) }
// loadCodewalk reads a codewalk from the named XML file. func loadCodewalk(file string) (*Codewalk, os.Error) { f, err := os.Open(file) if err != nil { return nil, err } defer f.Close() cw := new(Codewalk) p := xml.NewParser(f) p.Entity = xml.HTMLEntity err = p.Unmarshal(cw, nil) if err != nil { return nil, &os.PathError{"parsing", file, err} } // Compute file list, evaluate line numbers for addresses. m := make(map[string]bool) for _, st := range cw.Step { i := strings.Index(st.Src, ":") if i < 0 { i = len(st.Src) } file := st.Src[0:i] data, err := ioutil.ReadFile(absolutePath(file, *goroot)) if err != nil { st.Err = err continue } if i < len(st.Src) { lo, hi, err := addrToByteRange(st.Src[i+1:], 0, data) if err != nil { st.Err = err continue } // Expand match to line boundaries. for lo > 0 && data[lo-1] != '\n' { lo-- } for hi < len(data) && (hi == 0 || data[hi-1] != '\n') { hi++ } st.Lo = byteToLine(data, lo) st.Hi = byteToLine(data, hi-1) } st.Data = data st.File = file m[file] = true } // Make list of files cw.File = make([]string, len(m)) i := 0 for f := range m { cw.File[i] = f i++ } sort.SortStrings(cw.File) return cw, nil }
func getParser(filename string) *xml.Parser { var parser *xml.Parser if filepath.Ext(filename) == ".zip" { zipcontainer, err := zip.OpenReader(filename) if err != nil { panic(err) } zippedfile := zipcontainer.File[0] reader, err := zippedfile.Open() if err != nil { panic(err) } if filepath.Ext(zippedfile.FileHeader.Name) == ".bz2" { log.Println("Uncompressing and unmarshaling XML of zip file") parser = xml.NewParser(bzip2.NewReader(reader)) } else { log.Println("Unmarshaling XML of zip file") parser = xml.NewParser(reader) } reader.Close() if err != nil { panic(err) } } else { openfile, err := os.Open(filename) if err != nil { panic(err) } if filepath.Ext(filename) == ".bz2" { log.Println("Uncompressing and unmarshaling XML") parser = xml.NewParser(bzip2.NewReader(openfile)) } else { log.Println("Unmarshaling XML") parser = xml.NewParser(openfile) } if err != nil { panic(err) } } return parser }
func readXmlFromFile(in io.Reader) (gmeta GangliaXml, err os.Error) { p := xml.NewParser(in) p.CharsetReader = CharsetReader gmeta = GangliaXml{} err = p.Unmarshal(&gmeta, nil) return }
// Handles xml unmarshalling to a generic object from // an http.Response func ParseResponse(resp *http.Response, o interface{}) (err os.Error) { if resp.Body == nil { err = os.NewError("Response body is empty") } else { parser := xml.NewParser(resp.Body) err = parser.Unmarshal(o, nil) } return }
func Parse(r io.Reader) (doc Document, err os.Error) { // Create parser and get first token p := xml.NewParser(r) t, err := p.Token() if err != nil { return nil, err } d := newDoc() e := (Node)(nil) // e is the current parent for t != nil { switch token := t.(type) { case xml.StartElement: el := newElem(token) for ar := range token.Attr { el.SetAttribute(token.Attr[ar].Name.Local, token.Attr[ar].Value) } if e == nil { // set doc root // this element is a child of e, the last element we found e = d.setRoot(el) } else { // this element is a child of e, the last element we found e = e.AppendChild(el) } case xml.CharData: e.AppendChild(newText(token)) case xml.Comment: e.AppendChild(newComment(token)) case xml.EndElement: e = e.ParentNode() default: // TODO: add handling for other types (text nodes, etc) } // get the next token t, err = p.Token() } // Make sure that reading stopped on EOF if err != os.EOF { return nil, err } // All is good, return the document return d, nil }
func (room *Room) Show() { room_path := fmt.Sprintf("/room/%d.xml", room.Id) url := room.Site.CampfireUrl(room_path) response, err := http.Get(url) if err != nil { log.Fatal("Could not get room") } defer response.Body.Close() parser := xml.NewParser(response.Body) err = parser.Unmarshal(&room, nil) if err != nil { log.Fatal("Error unmarshalling room:", err) } var body []byte body, err = ioutil.ReadAll(response.Body) fmt.Printf("Body: %s\n", string(body)) }
func main() { // Print the XML comments from the test file, which should // contain most of the printable ISO-8859-1 characters. r, err := os.Open("ISO88591.xml") if err != nil { fmt.Println(err) return } defer r.Close() fmt.Println("file:", r.Name()) p := xml.NewParser(r) p.CharsetReader = CharsetReader for t, err := p.Token(); t != nil && err == nil; t, err = p.Token() { switch t := t.(type) { case xml.ProcInst: fmt.Println(t.Target, string(t.Inst)) case xml.Comment: fmt.Println(string([]byte(t))) } } }
func searchHTMLMeta(r io.Reader) (string, os.Error) { parser := xml.NewParser(r) var token xml.Token var err os.Error for { token, err = parser.Token() if token == nil || err != nil { if err == os.EOF { break } return "", err } switch token.(type) { case xml.StartElement: if token.(xml.StartElement).Name.Local == "meta" { // Found a meta token. Verify that it is a X-XRDS-Location and return the content var content string var contentE bool var httpEquivOK bool contentE = false httpEquivOK = false for _, v := range token.(xml.StartElement).Attr { if v.Name.Local == "http-equiv" && v.Value == "X-XRDS-Location" { httpEquivOK = true } if v.Name.Local == "content" { content = v.Value contentE = true } } if contentE && httpEquivOK { return fmt.Sprint(content), nil } } } } return "", os.ErrorString("Value not found") }
func main() { // // Parse XML // contents, err := ioutil.ReadFile("note.xml") if err != nil { fmt.Printf("Error: %v\n", err) } else { xml_parser := xml.NewParser(strings.NewReader(string(contents))) // token, err := xml_parser.Token() // if err != nil { // fmt.Printf("Error: %v\n", err) // } else { // fmt.Printf("token is of type %T\n", token) // } note := new(Note) if err := xml_parser.Unmarshal(note, nil); err != nil { fmt.Printf("Error: %v\n", err) } else { //fmt.Printf("Note: %v\n", *note) fmt.Printf("%v\n", (*note).from) } } }
func GetSoapEnvelope(query string, numero uint, mdp string) (envelope *SoapEnvelope) { httpClient := new(http.Client) soapRequestContent := fmt.Sprintf(query, numero, mdp) resp, err := httpClient.Post(MH_SOAP_URL, "text/xml; charset=utf-8", bytes.NewBufferString(soapRequestContent)) if err != nil { fmt.Println("Erreur : " + err.String()) return nil } // là on fait du lourd : on passe par une chaine car j'ai pas le temps ce soir de trouver comment sauter directement un bout du flux jusqu'au début du xml b, e := ioutil.ReadAll(resp.Body) if e != nil { fmt.Println("Erreur lecture :") fmt.Println(e) } in := string(b) indexDebutXml := strings.Index(in, "<?xml version") if indexDebutXml > 0 { fmt.Printf("Erreur message SOAP. Début XML à l'index %d\n", indexDebutXml) in = in[indexDebutXml:len(in)] } //fmt.Print(in) parser := xml.NewParser(bytes.NewBufferString(in)) parser.CharsetReader = CharsetReader envelope = new(SoapEnvelope) err = parser.Unmarshal(&envelope, nil) if err != nil { fmt.Println("Erreur au décodage du XML : " + err.String()) return nil } resp.Body.Close() return }
func (site *Site) Whoami() (user *User) { url := site.CampfireUrl("/users/me.xml") parsed_url := ParseURL(url) response, err := http.Get(parsed_url.String()) if err != nil { log.Fatal(err) } defer response.Body.Close() if response.StatusCode != 200 { log.Printf("Status: %s\n", response.Status) log.Fatal("Could not get me") } parser := xml.NewParser(response.Body) user = &User{} err = parser.Unmarshal(&user, nil) if err != nil { log.Fatal("Error unmarshalling xml:", err) } return user }
func main() { parser := xml.NewParser(os.Stdin) mode := 0 //var title []byte; title := bytes.NewBuffer(make([]byte, 0, 0)) page := bytes.NewBuffer(make([]byte, 0, 0)) redirects, rerr := os.Open("redirects.txt", os.O_WRONLY, 0666) wiki, werr := os.Open("wiki.txt", os.O_WRONLY, 0666) zbuf := bytes.NewBuffer(make([]byte, 0, 0)) zwiki := lzma.NewWriterLevel(zbuf, 3) unsorted, uerr := os.Open("unsorted.txt", os.O_WRONLY, 0666) if rerr != nil { fmt.Printf("Error %s\n", rerr) os.Exit(1) } if werr != nil { fmt.Printf("Error %s\n", werr) os.Exit(1) } if uerr != nil { fmt.Printf("Error %s\n", uerr) os.Exit(1) } var redirectFinder = regexp.MustCompile(`#REDIRECT.*\[\[([^\]]+)\]\]`) var nsFinder = regexp.MustCompile(`.+:`) for { token, err := parser.Token() if err == nil { switch t := token.(type) { case xml.StartElement: //fmt.Printf("Start Element %s\n", t.Name.Local) if t.Name.Local == "title" { mode = 1 } else if t.Name.Local == "text" { mode = 2 } else { mode = 0 } case xml.EndElement: //fmt.Printf("End Element %s\n", t.Name.Local) if t.Name.Local == "page" { stitle := strings.Trim(title.String(), " \n\t\r") text := strings.Trim(page.String(), " \n\t\r") if !nsFinder.MatchString(stitle) { if redirectFinder.MatchString(text) { //its a redirect! fmt.Fprintf(redirects, "%s;%s\n", redirectFinder.FindStringSubmatch(text)[1], stitle) } else { fmt.Fprintf(unsorted, "%s\n", stitle) } if zbuf.Len()+len(text) > 30000 { fmt.Printf("(%s %d)\n", stitle, zbuf.Len()) zwiki.Close() wiki.Write(zbuf.Bytes()) //wiki.Sync() zbuf.Reset() zwiki = lzma.NewWriterLevel(zbuf, 3) } fmt.Fprintf(zwiki, "=%s=\n\n\n\n%s", stitle, text) } title.Reset() page.Reset() } case xml.CharData: if mode == 1 { title.Write(t) } else if mode == 2 { page.Write(t) } } } else { os.Exit(0) } } }
func ParseMessage(r io.Reader) (ParamValue, os.Error) { p := xml.NewParser(r) return parseMessage(p) }
// Load the contents of this document from the supplied reader. func (this *Document) LoadStream(r io.Reader) (err os.Error) { xp := xml.NewParser(r) xp.Entity = this.Entity xp.CharsetReader = func(enc string, input io.Reader) (io.Reader, os.Error) { return charset.NewReader(enc, input) } this.Root = NewNode(NT_ROOT) ct := this.Root var tok xml.Token var t *Node var doctype string for { if tok, err = xp.Token(); err != nil { if err == os.EOF { return nil } return err } switch tt := tok.(type) { case xml.SyntaxError: return os.NewError(tt.String()) case xml.CharData: ct.Value = strings.TrimSpace(string([]byte(tt))) case xml.Comment: t := NewNode(NT_COMMENT) t.Value = strings.TrimSpace(string([]byte(tt))) ct.AddChild(t) case xml.Directive: t = NewNode(NT_DIRECTIVE) t.Value = strings.TrimSpace(string([]byte(tt))) ct.AddChild(t) case xml.StartElement: t = NewNode(NT_ELEMENT) t.Name = tt.Name t.Attributes = make([]*Attr, len(tt.Attr)) for i, v := range tt.Attr { t.Attributes[i] = new(Attr) t.Attributes[i].Name = v.Name t.Attributes[i].Value = v.Value } ct.AddChild(t) ct = t case xml.ProcInst: if tt.Target == "xml" { // xml doctype doctype = strings.TrimSpace(string(tt.Inst)) if i := strings.Index(doctype, `standalone="`); i > -1 { this.StandAlone = doctype[i+len(`standalone="`) : len(doctype)] i = strings.Index(this.StandAlone, `"`) this.StandAlone = this.StandAlone[0:i] } } else { t = NewNode(NT_PROCINST) t.Target = strings.TrimSpace(tt.Target) t.Value = strings.TrimSpace(string(tt.Inst)) ct.AddChild(t) } case xml.EndElement: if ct = ct.Parent; ct == nil { return } } } return }
func parsexml(r io.Reader) *xmlparser { x := &xmlparser{p: xml.NewParser(r)} x.next() return x }
func main() { var r *strings.Reader if len(os.Args) > 2 { fmt.Println("Usage: ", os.Args[0], "[<XML file>]") os.Exit(1) } else if len(os.Args) == 2 { file := os.Args[1] bytes, err := ioutil.ReadFile(file) checkError(err) r = strings.NewReader(string(bytes)) } else { feed_data := fetchXMLFeed(guardian_url) r = strings.NewReader(feed_data) } parser := xml.NewParser(r) item_tags_seen := 0 var photos []Photo var photo Photo for { // Only read the top (most recent) "item" in the feed if item_tags_seen == 2 { break } token, err := parser.Token() if err != nil { break } switch t := token.(type) { case xml.StartElement: elmt := xml.StartElement(t) name := elmt.Name.Local switch name { case "item": item_tags_seen++ case "content": if photo.Credit != "" && photo.Description != "" && photo.Link != "" { fmt.Println("Appending photo") photos = append(photos, photo) } else { photo = Photo{Link: getAttributeFromTag("url", elmt)} } case "credit": photo.Credit = getTagContents(parser) case "description": photo.Description = getTagContents(parser) } /* Unused token types: case xml.EndElement: continue case xml.CharData: bytes := xml.CharData(t) printElmt("\""+string([]byte(bytes))+"\"", depth) case xml.Comment: printElmt("Comment", depth) case xml.ProcInst: printElmt("ProcInst", depth) case xml.Directive: printElmt("Directive", depth) */ } } fmt.Println("Number of photos: ", len(photos)) for i, p := range photos { fmt.Println("Photo #", i, ":") fmt.Println("\tDesc: ", p.Description) fmt.Println("\tCred: ", p.Credit) fmt.Println("\tLink: ", p.Link) } }
func (c *Client) init(user, passwd string) os.Error { // For debugging: the following causes the plaintext of the connection to be duplicated to stdout. // c.p = xml.NewParser(tee{c.tls, os.Stdout}); c.p = xml.NewParser(c.tls) a := strings.Split(user, "@", 2) if len(a) != 2 { return os.ErrorString("xmpp: invalid username (want user@domain): " + user) } user = a[0] domain := a[1] // Declare intent to be a jabber client. fmt.Fprintf(c.tls, "<?xml version='1.0'?>\n"+ "<stream:stream to='%s' xmlns='%s'\n"+ " xmlns:stream='%s' version='1.0'>\n", xmlEscape(domain), nsClient, nsStream) // Server should respond with a stream opening. se, err := nextStart(c.p) if err != nil { return err } if se.Name.Space != nsStream || se.Name.Local != "stream" { return os.ErrorString("xmpp: expected <stream> but got <" + se.Name.Local + "> in " + se.Name.Space) } // Now we're in the stream and can use Unmarshal. // Next message should be <features> to tell us authentication options. // See section 4.6 in RFC 3920. var f streamFeatures if err = c.p.Unmarshal(&f, nil); err != nil { return os.ErrorString("unmarshal <features>: " + err.String()) } havePlain := false for _, m := range f.Mechanisms.Mechanism { if m == "PLAIN" { havePlain = true break } } if !havePlain { return os.ErrorString(fmt.Sprintf("PLAIN authentication is not an option: %v", f.Mechanisms.Mechanism)) } // Plain authentication: send base64-encoded \x00 user \x00 password. raw := "\x00" + user + "\x00" + passwd enc := make([]byte, base64.StdEncoding.EncodedLen(len(raw))) base64.StdEncoding.Encode(enc, []byte(raw)) fmt.Fprintf(c.tls, "<auth xmlns='%s' mechanism='PLAIN'>%s</auth>\n", nsSASL, enc) // Next message should be either success or failure. name, val, err := next(c.p) switch v := val.(type) { case *saslSuccess: case *saslFailure: // v.Any is type of sub-element in failure, // which gives a description of what failed. return os.ErrorString("auth failure: " + v.Any.Local) default: return os.ErrorString("expected <success> or <failure>, got <" + name.Local + "> in " + name.Space) } // Now that we're authenticated, we're supposed to start the stream over again. // Declare intent to be a jabber client. fmt.Fprintf(c.tls, "<stream:stream to='%s' xmlns='%s'\n"+ " xmlns:stream='%s' version='1.0'>\n", xmlEscape(domain), nsClient, nsStream) // Here comes another <stream> and <features>. se, err = nextStart(c.p) if err != nil { return err } if se.Name.Space != nsStream || se.Name.Local != "stream" { return os.ErrorString("expected <stream>, got <" + se.Name.Local + "> in " + se.Name.Space) } if err = c.p.Unmarshal(&f, nil); err != nil { // TODO: often stream stop. //return os.ErrorString("unmarshal <features>: " + err.String()) } // Send IQ message asking to bind to the local user name. fmt.Fprintf(c.tls, "<iq type='set' id='x'><bind xmlns='%s'/></iq>\n", nsBind) var iq clientIQ if err = c.p.Unmarshal(&iq, nil); err != nil { return os.ErrorString("unmarshal <iq>: " + err.String()) } if &iq.Bind == nil { return os.ErrorString("<iq> result missing <bind>") } c.jid = iq.Bind.Jid // our local id // We're connected and can now receive and send messages. fmt.Fprintf(c.tls, "<presence xml:lang='en'><show>xa</show><status>I for one welcome our new codebot overlords.</status></presence>") return nil }
// Tidy takes an HTML string and tidys it up. func Tidy(str string) (html string, err os.Error) { parser := xml.NewParser(strings.NewReader(str)) // read str, token by token, and spit it out // // xml.Parser does most of the work for us here - we do a small // bit by indenting indent := 0 // the current indent level token, err := parser.Token() inpre := false // true if we are in a <pre> tag for err == nil { switch token.(type) { case xml.StartElement: elem := token.(xml.StartElement) if !inpre { for i := 0; i < indent; i++ { html += indentation } } html += "<" + String(elem.Name) for _, attr := range elem.Attr { html += fmt.Sprintf(" %s=\"%s\"", String(attr.Name), attr.Value) } html += ">" if String(elem.Name) == "pre" { inpre = true } if !inpre { html += "\n" } indent++ case xml.EndElement: elem := token.(xml.EndElement) indent-- if !inpre { for i := 0; i < indent; i++ { html += indentation } } html += fmt.Sprintf("</%s>", String(elem.Name)) if String(elem.Name) == "pre" { inpre = false } if !inpre { html += fmt.Sprintf("\n") } case xml.CharData: data := token.(xml.CharData) str := bytes.NewBuffer(data).String() if !inpre { str = strings.Trim(str, " \r\n\t") } if len(str) > 0 { if !inpre { for i := 0; i < indent; i++ { html += indentation } } html += str if !inpre { html += "\n" } } case xml.Comment: // don't print comments case xml.ProcInst: // TODO handle these somehow (server-side xslt?) case xml.Directive: // just spit it out directive := token.(xml.Directive) html += "<!" + bytes.NewBuffer(directive).String() + ">" default: // yikes! Not much to do about this... } token, err = parser.Token() } if err != os.EOF { fmt.Fprint(os.Stderr, err) // return the original string return str, err } err = nil return }
func (e *XMLConnector) init() { parser := xml.NewParser(e.db) a, err := parser.Token() schema := false lastType := NullKind var lastAttr string = "" var lastTable *XMLTable var lastItem map[string]Value for ; err == nil; a, err = parser.Token() { switch a.(type) { case xml.StartElement: xel := a.(xml.StartElement) el := xel.Name.Local //fmt.Println(el) if el == "schema" { schema = true } if schema { switch el { case "table": if attr, found := xml_attribute(xel, "name"); found { // fmt.Println("Found Table ! " + attr.Value) lastTable = e.CreateTableWithoutId(attr.Value) } else { // fmt.Println(os.Stderr, "Missing required attribute name on <table>") } case "attribute": if attr, found := xml_attribute(xel, "type"); found { // fmt.Println("Found Attribute ! on" + fmt.Sprint(lastTable) + " " + attr.Value) //fmt.Println(xel) lastType = typeFromName(attr.Value) } else { fmt.Println(os.Stderr, "Missing required attribute type on <attribute>") } } } else { switch el { case "tabledata": if attr, found := xml_attribute(xel, "name"); found { lastTable = e.Table(attr.Value) } else { fmt.Println(os.Stderr, "Missing required attribute name on <tabledata>") } case "item": lastItem = make(map[string]Value) case "value": if attr, found := xml_attribute(xel, "name"); found { lastAttr = attr.Value } else { fmt.Println(os.Stderr, "Missing required attribute name on <tabledata>") } } } case xml.CharData: if schema && lastType != NullKind { b := bytes.NewBuffer(a.(xml.CharData)) lastTable.AddAttribute(b.String(), lastType) lastType = NullKind } else if lastAttr != "" { b := bytes.NewBuffer(a.(xml.CharData)) switch lastTable.Attributes()[lastAttr] { case StringKind: lastItem[lastAttr] = SysString(b.String()).Value() case IntKind: i, _ := strconv.Atoi(b.String()) lastItem[lastAttr] = SysInt(i).Value() } lastAttr = "" } case xml.EndElement: el := a.(xml.EndElement).Name.Local //fmt.Println("/" + el) if el == "schema" { schema = false } if schema { if el == "table" { lastTable = nil } } else { switch el { case "tabledata": lastTable = nil case "item": lastTable.data.Push(lastItem) } } } } if _, oser := err.(os.Error); err != nil && !oser { fmt.Printf("%T ", err) fmt.Println(err) } }