I'm new on Go. I have a task to do where I have a xml file with the following structure. There many other tag record in this file.
I need to read all the records, and print the information about the Kind of music but only where datafield tag is equal "650" and the subfield code tag = "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>
My code is:
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)
}
}
}
}
}
I'm having problems to acess the structs datafield and subfield. It seems that when a call record.Datafield and record.Datafield.Subfield.Code Go is not recognizing the structs.
Anyone can help me? Thanks in advance.
=)
Your code doesn't even compile. You need to index the slices inside the loops, you can't refer to fields of elements of slices without indexing them. Also Record.Controlfield
and Record.Datafield
are not "related", it's senseless to process them with embedded loops.
However, you do need to use nested loops to check Subfield
of a Datafield
whose tag matches.
Something like this:
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)
}
}
}
}
Try it on the Go Playground.
Note that you could use for range
to also "get" the element at the given index, but since you have some kind of generated struct which uses anonymous structs (and not pointers), such a loop would copy all elements (hence I stayed with "manual indexing").
Also do check all errors, e.g. ioutil.ReadAll(xmlFile)
and xml.Unmarshal(data, &record)
.