func TestSearchXMLComplex(t *testing.T) { type Listing struct { Business string `xml:"Business>RESIOWNS"` Approved bool `xml:"Listing>Approved"` MLS string `xml:"Listing>MLS"` Disclaimer string `xml:"Listing>Disclaimer"` Status string `xml:"Listing>Status"` ListingPrice float64 `xml:"Listing>Price>ListingPrice"` OriginalPrice float64 `xml:"Listing>Price>OriginalPrice"` SellPrice float64 `xml:"Listing>Price>SellingPrice"` } body := ioutil.NopCloser(strings.NewReader(standardXML)) cr, err := NewStandardXMLSearchResult(body) testutils.Ok(t, err) var listings []Listing count, maxRows, err := cr.ForEach(minidom.ByName("PropertyListing"), func(elem io.ReadCloser, err error) error { if err != nil { return err } listing := Listing{} xml.NewDecoder(elem).Decode(&listing) listings = append(listings, listing) return err }) testutils.Ok(t, err) testutils.Equals(t, true, maxRows) testutils.Equals(t, 10, count) testutils.Equals(t, 2, len(listings)) }
func TestSimple(t *testing.T) { doms := ioutil.NopCloser(strings.NewReader(example)) parser := xml.NewDecoder(doms) listings := Listings{} // minidom isnt necessary but its crazy useful for massive streams md := minidom.MiniDom{ StartFunc: func(start xml.StartElement) { switch start.Name.Local { case "Listings": attrs := map[string]string{} for _, v := range start.Attr { attrs[v.Name.Local] = v.Value } listings.ListingsKey = attrs["listingsKey"] listings.Version = attrs["version"] listings.VersionTimestamp = attrs["versionTimestamp"] listings.Language = attrs["lang"] case "Disclaimer": parser.DecodeElement(listings.Disclaimer, &start) } }, // quit on the the xml tag EndFunc: minidom.QuitAt("Listings"), } err := md.Walk(parser, minidom.ByName("Listing"), ToListing(func(l Listing, err error) error { listings.Listings = append(listings.Listings, l) return err })) testutils.Ok(t, err) testutils.Equals(t, 1, len(listings.Listings)) testutils.Equals(t, "http://www.somemls.com/lisings/1234567890", listings.Listings[0].ListingURL) testutils.Equals(t, "New Light Fixtures", *listings.Listings[0].Photos[1].Caption) testutils.Equals(t, "1100.0", listings.Listings[0].Expenses[2].Value.Value) }
func TestSearchXML(t *testing.T) { body := ioutil.NopCloser(strings.NewReader(standardXML)) cr, err := NewStandardXMLSearchResult(body) testutils.Ok(t, err) var listings []io.ReadCloser count, maxRows, err := cr.ForEach(minidom.ByName("PropertyListing"), func(elem io.ReadCloser, err error) error { listings = append(listings, elem) return err }) testutils.Ok(t, err) testutils.Equals(t, true, maxRows) testutils.Equals(t, 10, count) testutils.Equals(t, 2, len(listings)) }
func TestSearchXMLParseSearchQuit(t *testing.T) { noEnd := strings.Split(standardXML, "Commercial")[0] body := ioutil.NopCloser(strings.NewReader(noEnd)) cr, err := NewStandardXMLSearchResult(body) testutils.Ok(t, err) var listings [][]byte count, maxRows, err := cr.ForEach(minidom.ByName("PropertyListing"), func(elem io.ReadCloser, err error) error { tmp, _ := ioutil.ReadAll(elem) listings = append(listings, tmp) return err }) testutils.NotOk(t, err) testutils.Equals(t, false, maxRows) testutils.Equals(t, 10, count) testutils.Equals(t, 1, len(listings)) }
func TestSearchXMLBadChar(t *testing.T) { type Listing struct { Row string } rets := `<?xml version="1.0" encoding="UTF-8" ?> <RETS ReplyCode="0" ReplyText="Operation Successful"> <COUNT Records="5" /> <Listings> <PropertyListing> <Row>bad` + "\x0b" + `row</Row> </PropertyListing> <PropertyListing> <Row>good row</Row> </PropertyListing> </Listings> <MAXROWS/> </RETS>` body := ioutil.NopCloser(strings.NewReader(rets)) cr, err := NewStandardXMLSearchResult(body) testutils.Ok(t, err) testutils.Equals(t, StatusOK, cr.Response.Code) var listings []Listing count, maxRows, err := cr.ForEach(minidom.ByName("PropertyListing"), func(elem io.ReadCloser, err error) error { listing := Listing{} xml.NewDecoder(elem).Decode(&listing) listings = append(listings, listing) return err }) testutils.Ok(t, err) testutils.Equals(t, true, maxRows) testutils.Equals(t, 5, count) testutils.Equals(t, 2, len(listings)) testutils.Equals(t, "bad row", listings[0].Row) testutils.Equals(t, "good row", listings[1].Row) }