使用 Go 讀取大型 XML 檔案

環境

  • Go 1.13.4

做法

當讀取大型 XML 檔案時,應避免使用 ioutil.ReadAll()xml.Unmarshal() 方法,而是使用 xml.Decoder.Token() 方法,來達到串流處理。

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
// 讀取檔案
resource := "file.xml"
file, err := os.Open(resource)
defer file.Close()

if err != nil {
log.Fatalln(err.Error())
return
}

// 取得串流
decoder := xml.NewDecoder(file)

for {
// 取得串流中下一个元素的令牌
token, err := decoder.Token()

// 判斷是否為文件的結尾,如果是則停止
if err == io.EOF {
break
}

// 判斷是否出錯,如果是則停止
if err != nil {
log.Fatalln(err.Error())
return
}

// 判斷是否讀取完畢,如果是則停止
if token == nil {
break
}

// 判斷令牌是否為起始元素
switch element := token.(type) {
case xml.StartElement:
// 判斷起始元素是否為指定元素
switch element.Name.Local {
case "Record":
record := Record{}

if err = decoder.DecodeElement(&record, &element); err != nil {
log.Fatalln(err.Error())
return
}

// 處理指定元素
}
}
}

參考資料