Last active
February 5, 2023 07:37
-
-
Save goura/ea24ee3775cd08d1beb6700753195323 to your computer and use it in GitHub Desktop.
Read Kifukinkoujo-ni-kansuru-shoumeisho (寄付金控除に関する証明書) from standard input and print items inside it
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
// Parse kifukinkoujoshoumeisho xml and print the donation entries inside it | |
// Disclaimer: This doesn't do XMLDsig verification | |
// Disclaimer: no warranty, use it at your own risk | |
// | |
// For example you can save this as furusato-sum.go and run it like | |
// $ cat aaaa.xml | go run furusato-sum.go | awk -F "\t" '{sum += $3} END {print sum}' | |
// To get the sum of the amount of donations inside the xml | |
package main | |
import ( | |
"encoding/xml" | |
"fmt" | |
"io" | |
"os" | |
"time" | |
) | |
// <TEG830> is the root tag | |
// Contains two similar but different containers | |
type Teg830 struct { | |
XMLName xml.Name `xml:"TEG830"` | |
Container1 _Teg830_1 `xml:"TEG830-1"` | |
Container2 _Teg830_2 `xml:"TEG830-2"` | |
} | |
// <TEG830-1> tag contains metadata and the first 10 items | |
// We're not interested in metadata, so I'll just pick up the items | |
// Items are under the <WML00000> tag | |
type _Teg830_1 struct { | |
WML00000 _WML00000 `xml:"WML00000"` | |
} | |
// <TEG830-2> tag contains 11th and beyond items | |
// It contains <WMN00000> which is the same shape as <WML00000> | |
// But under <TEG830-2> there are multiple <WMN00000>s | |
type _Teg830_2 struct { | |
WMN00000s []_WMN00000 `xml:"WMN00000"` | |
} | |
// <WML00000> contains multiple <WML00010>s | |
// <WMN00000> contains multiple <WMN00010>s | |
// <WML00010> and <WMN00010> are the same shape | |
type _WML00000 struct { | |
WML00010s []_WML00010 `xml:"WML00010"` | |
} | |
type _WMN00000 struct { | |
WMN00010s []_WMN00010 `xml:"WMN00010"` | |
} | |
// <WML00010> contains what we want | |
// The unique ID (?), date, city info and the amount of money you donated | |
// <WMN00010> is the same shape as <WML00010> | |
type _WML00010 struct { | |
UniqueID string `xml:"WML00020"` | |
DateInfo _WMx00030 `xml:"WML00030"` | |
LGInfo _WML00040 `xml:"WML00040"` | |
Amount int `xml:"WML00070"` | |
} | |
type _WMN00010 struct { | |
UniqueID string `xml:"WMN00020"` | |
DateInfo _WMx00030 `xml:"WMN00030"` | |
LGInfo _WMN00040 `xml:"WMN00040"` | |
Amount int `xml:"WMN00070"` | |
} | |
// _WMx00030 is for both <WMN00030> and <WML00030> | |
type _WMx00030 struct { | |
Year int `xml:"yyyy"` | |
Month int `xml:"mm"` | |
Day int `xml:"dd"` | |
} | |
// <WML00040> and <WML00040> contain the city info | |
type _WML00040 struct { | |
LGName string `xml:"WML00050"` | |
LGNumber string `xml:"WML00060>hojinbango"` | |
} | |
type _WMN00040 struct { | |
LGName string `xml:"WMN00050"` | |
LGNumber string `xml:"WMN00060>hojinbango"` | |
} | |
// Struct for info we are interested in | |
type FurusatoItem struct { | |
UniqueID string | |
Date time.Time | |
Amount int | |
LGName string | |
LGNumber string | |
} | |
// Utility function to create time.Time from YYYYMMDD | |
func WMx00030toDate(DateInfo _WMx00030) time.Time { | |
loc, _ := time.LoadLocation("Asia/Tokyo") | |
t := time.Date( | |
DateInfo.Year, | |
time.Month(DateInfo.Month), | |
DateInfo.Day, | |
0, 0, 0, 0, loc) | |
return t | |
} | |
func main() { | |
// Read from stdio and parse XML | |
byteValue, _ := io.ReadAll(os.Stdin) | |
var teg830 Teg830 | |
xml.Unmarshal(byteValue, &teg830) | |
furusatoItems := make([]FurusatoItem, 0) | |
// First pick up items under <TEG830-1> | |
for _, data := range teg830.Container1.WML00000.WML00010s { | |
item := FurusatoItem{ | |
UniqueID: data.UniqueID, | |
Date: WMx00030toDate(data.DateInfo), | |
Amount: data.Amount, | |
LGName: data.LGInfo.LGName, | |
LGNumber: data.LGInfo.LGNumber, | |
} | |
furusatoItems = append(furusatoItems, item) | |
} | |
// Next pick up items under <TEG830-2> | |
for _, container := range teg830.Container2.WMN00000s { | |
for _, data := range container.WMN00010s { | |
item := FurusatoItem{ | |
UniqueID: data.UniqueID, | |
Date: WMx00030toDate(data.DateInfo), | |
Amount: data.Amount, | |
LGName: data.LGInfo.LGName, | |
LGNumber: data.LGInfo.LGNumber, | |
} | |
furusatoItems = append(furusatoItems, item) | |
} | |
} | |
// Output as lines of tab separated values | |
for _, item := range furusatoItems { | |
datestr := item.Date.Format("2006/01/02") | |
fmt.Printf("%v\t%v\t%v\t%v\t%v\n", item.UniqueID, datestr, item.Amount, item.LGNumber, item.LGName) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment