package main import ( "encoding/xml" "fmt" ) func main() { type DateRange struct { Begin int `xml:"begin"` End int `xml:"end"` } type ReportMetadata struct { OrgName string `xml:"org_name"` Email string `xml:"email"` ExtraContact string `xml:"extra_contact_info"` ReportId string `xml:"report_id"` DateRange DateRange `xml:"date_range"` } type PolicyPublished struct { Domain string `xml:"domain"` Adkim string `xml:"adkim"` Aspf string `xml:"aspf"` Policy string `xml:"p"` SubdomainPolicy string `xml:"sp"` Percentage int `xml:"pct"` } type PolicyEvaluated struct { Disposition string `xml:"disposition"` Dkim string `xml:"dkim"` Spf string `xml:"spf"` } type Row struct { // TODO: Figure out how to cast this to an IP SourceIp string `xml:"source_ip"` Count int `xml:"count"` PolicyEvaluated PolicyEvaluated `xml:"policy_evaluated"` } type Identifiers struct { HeaderFrom string `xml:"header_from"` } type AuthResult struct { // FIXME: this could be either DKIM or SPF XMLName xml.Name Domain string `xml:"domain"` Result string `xml:"result"` } type AuthResults struct { AuthResult []AuthResult `xml:",any"` } type Record struct { Row Row `xml:"row"` Identifiers Identifiers `xml:"identifiers"` AuthResults AuthResults `xml:"auth_results"` } type FeedbackReport struct { XMLName xml.Name `xml:"feedback"` ReportMetadata ReportMetadata `xml:"report_metadata"` PolicyPublished PolicyPublished `xml:"policy_published"` Record []Record `xml:"record"` } v := FeedbackReport{} data := ` google.com noreply-dmarc-support@google.com https://support.google.com/a/answer/2466580 11295852759969162400 1448236800 1448323199 colbs.net r r

reject

reject 100
2607:f8b0:400c:c05::249 1 none pass fail colbs.net google.com pass colbs.net pass calendar-server.bounces.google.com pass 2a00:1450:400c:c09::235 1 none pass pass colbs.net colbs.net pass colbs.net pass
` err := xml.Unmarshal([]byte(data), &v) if err != nil { fmt.Printf("error: %v", err) return } fmt.Printf("XMLName: %#v\n", v) // fmt.Printf("org_name: %#q\n", v.ReportMetadata.OrgName) // fmt.Printf("domain: %#q\n", v.PolicyPublished.Domain) // fmt.Printf("Name: %q\n", v.Name) // fmt.Printf("Phone: %q\n", v.Phone) // fmt.Printf("Email: %v\n", v.Email) // fmt.Printf("Groups: %v\n", v.Groups) // fmt.Printf("Address: %v\n", v.Address) }