-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathextract.go
More file actions
73 lines (67 loc) · 1.56 KB
/
Copy pathextract.go
File metadata and controls
73 lines (67 loc) · 1.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package metadata
import (
"encoding/xml"
"io"
"regexp"
"strconv"
"strings"
)
// Extractor processes metadata elements
type Extractor struct {
Body io.ReadCloser
parser *xml.Decoder
}
// Open a metadata stream and read in the RETS response
func (e *Extractor) Open() (RETSResponse, error) {
// TODO extract common work from rets/rets_response.go
rets := RETSResponse{}
e.parser = xml.NewDecoder(e.Body)
start, err := e.skipTo("(RETS|RETS-STATUS)")
if err != nil {
return rets, err
}
attrs := make(map[string]string)
for _, v := range start.Attr {
attrs[strings.ToLower(v.Name.Local)] = v.Value
}
code, err := strconv.ParseInt(attrs["replycode"], 10, 16)
if err != nil {
return rets, err
}
rets.ReplyCode = int(code)
rets.ReplyText = attrs["replytext"]
return rets, nil
}
// DecodeNext the provided elemment
func (e *Extractor) DecodeNext(match string, elem interface{}) error {
next, err := e.skipTo(match)
if err != nil {
return err
}
return e.parser.DecodeElement(elem, &next)
}
// skipTo advances the cursor to the named xml.StartElement
func (e *Extractor) skipTo(match string) (xml.StartElement, error) {
next, err := regexp.Compile(match)
if err != nil {
return xml.StartElement{}, err
}
for {
token, err := e.parser.Token()
if err != nil {
return xml.StartElement{}, err
}
switch t := token.(type) {
case xml.StartElement:
if next.MatchString(t.Name.Local) {
return t, nil
}
}
}
}
// RETSResponse ...
type RETSResponse struct {
// TODO extract common work from rets/rets_response.go
ReplyCode int
ReplyText string
}