我是 Go 新手。我有一个任务要做,我有一个具有以下结构的 xml 文件。该文件中还有许多其他标签记录。
我需要读取所有记录,并打印有关音乐种类的信息,但仅限于数据字段标记等于“650”且子字段代码标记=“a”的情况。
<record>
<leader>01153cjm a22002771a 4500</leader>
<controlfield tag="001"> 00000838 </controlfield>
<controlfield tag="003">DLC</controlfield>
<controlfield tag="005">20030506181700.0</controlfield>
<controlfield tag="007">sd|zsngnnmmned</controlfield>
<controlfield tag="008">000824s1998 nyuppn d</controlfield>
<datafield tag="050" ind1="0" ind2="0">
<subfield code="a">SDA 16949</subfield>
</datafield>
<datafield tag="010" ind1=" " ind2=" ">
<subfield code="a"> 00000838 </subfield>
</datafield>
<datafield tag="020" ind1=" " ind2=" ">
<subfield code="c">$15.98</subfield>
</datafield>
<datafield tag="024" ind1="1" ind2=" ">
<subfield code="a">601215312621</subfield>
</datafield>
<datafield tag="650" ind1=" " ind2="0">
<subfield code="a">Rap (Music)</subfield>
</datafield>
</record>
我的代码是:
package main
import (
"encoding/xml"
"fmt"
"io/ioutil"
"os"
)
type Record struct {
XMLName xml.Name `xml:"record"`
Text string `xml:",chardata"`
Leader string `xml:"leader"`
Controlfield []struct {
Text string `xml:",chardata"`
Tag string `xml:"tag,attr"`
} `xml:"controlfield"`
Datafield []struct {
Text string `xml:",chardata"`
Tag string `xml:"tag,attr"`
Ind1 string `xml:"ind1,attr"`
Ind2 string `xml:"ind2,attr"`
Subfield []struct {
Text string `xml:",chardata"`
Code string `xml:"code,attr"`
} `xml:"subfield"`
} `xml:"datafield"`
}
func main() {
xmlFile, err := os.Open("music_lite3.xml")
if err != nil {
fmt.Println(err)
}
fmt.Println("Successfully Opened music_lite3.xml")
defer xmlFile.Close()
data, _ := ioutil.ReadAll(xmlFile)
var record Record
xml.Unmarshal(data, &record)
for j := 0; j < len(record.Controlfield); j++ {
for i := 0; i < len(record.Datafield); i++ {
if record.Datafield == "650" {
if record.Datafield.Subfield.Code == "a" {
fmt.Println("Kind of Music: " + record.Datafield.Subfield.Text)
}
}
}
}
}
我在访问结构数据字段和子字段时遇到问题。 看来当调用record.Datafield和record.Datafield.Subfield.Code时 Go 无法识别结构。
有人可以帮助我吗? 提前致谢。
=)
最佳答案
你的代码甚至无法编译。您需要对循环内的 slice 进行索引,如果不对其进行索引,则无法引用 slice 元素的字段。此外,Record.Controlfield
和 Record.Datafield
并不“相关”,使用嵌入式循环处理它们是没有意义的。
但是,您确实需要使用嵌套循环来检查标签匹配的 Datafield
的 Subfield
。
类似这样的事情:
for i := range record.Datafield {
df := &record.Datafield[i]
if df.Tag == "650" {
for j := range df.Subfield {
if df.Subfield[j].Code == "a" {
fmt.Println("Kind of Music: " + df.Subfield[j].Text)
}
}
}
}
在 Go Playground 上尝试一下.
请注意,您可以使用 for range
来“获取”给定索引处的元素,但由于您有某种使用匿名结构(而不是指针)的生成结构,因此循环将复制所有元素(因此我保留“手动索引”)。
还要检查所有错误,例如ioutil.ReadAll(xmlFile) 和 xml.Unmarshal(data, &record)。
关于xml - 使用 Go 解析 XML 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57948561/