xml - 使用 Go 解析 XML 文件

标签 xml parsing go

我是 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.ControlfieldRecord.Datafield 并不“相关”,使用嵌入式循环处理它们是没有意义的。

但是,您确实需要使用嵌套循环来检查标签匹配的 DatafieldSubfield

类似这样的事情:

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/

相关文章:

java - 如何拆分XML?一些例子?

javascript - 如何单独用jQuery解析xml属性?

go - Beego框架如何进行数据库迁移?

go - 如何在没有嵌套循环的情况下将嵌套结构塑造成另一个结构?

android - 如何在android中的一个按钮中放置2个不同的文本?

c++ - C++中的命令行解析器

java - 如何使用 SAX 增加 entityExpansionLimit 来解析 XML 文件

javascript - 迭代 JSON 对象数组

html-parsing - 我如何获取 html.Node 的内容

xml - 如何使用 XSLT 2.0 或 XPath 2.0 获取引用具有不同值的元素的 href?