英文:
Golang Decode MusicXML
问题
我正在编写一个程序,可以读取完整的MusicXML文件,对其进行编辑,并将新文件写出。我正在使用xml.Decode将数据读入MusicXML文件的结构体中,但运行时似乎没有任何反应。我尝试将Decode对象打印到屏幕上,但打印出来的是一个由字节组成的结构体。
我查看了xml包的页面,似乎找不到任何关于Decode函数的线程。我尝试根据我找到的一些指针使用UnMarshall,但没有成功(大多数线程都比较旧,所以也许UnMarshall在实现Decode之后有了一些不同的用法)。
这是输入函数:
func ImportXML(infile string) *xml.Decoder {
// 读取音乐XML文件到内存
f, err := os.Open(infile)
if err != nil {
fmt.Fprintf(os.Stderr, "打开音乐XML文件时出错:%v\n", err)
os.Exit(1)
}
defer f.Close()
fmt.Println("\n\t正在读取musicXML文件...")
song := xml.NewDecoder(io.Reader(f))
// 必须传递一个接口指针给Decode
err = song.Decode(&Score{})
if err != nil {
fmt.Fprintf(os.Stderr, "将musicXML文件分配给结构体时出错:%v\n", err)
os.Exit(1)
}
return song
}
这是前几个结构体(其余的结构体遵循相同的格式):
type Score struct {
Work Work `xml:"work"`
Identification Identification `xml:"identification"`
Defaults Defaults `xml:"defaults"`
Credit Credit `xml:"credit"`
Partlist []Scorepart `xml:"score-part"`
Part []Part `xml:"part"`
}
// 名称和其他标识
type Work struct {
Number string `xml:"work-number"`
Title string `xml:"work-title"`
}
type Identification struct {
Type string `xml:"type,attr"`
Creator string `xml:"creator"`
Software string `xml:"software"`
Date string `xml:"encoding-date"`
Supports []Supports `xml:"supports"`
Source string `xml:"source"`
}
我非常感谢任何见解。
<details>
<summary>英文:</summary>
I am writing a program that can read in a complete MusicXML file, edit it, and write a new file out. I am using xml.Decode to read the data into a struct for the MusicXML file, but when I run it nothing seems to happen. I tried printing the Decode object to the screen, but it printed a struct full of bytes.
I've looked over the xml package page and I can't seem to find any threads covering the Decode function. I tried using UnMarshall according to some of the pointers I found, but that didn't work (most of those threads were older, so maybe UnMarshall works a bit differently since Decode was implemented?).
Here's the input function:
func ImportXML(infile string) *xml.Decoder {
// Reads music xml file to memory
f, err := os.Open(infile)
if err != nil {
fmt.Fprintf(os.Stderr, "Error opening music xml file: %v\n", err)
os.Exit(1)
}
defer f.Close()
fmt.Println("\n\tReading musicXML file...")
song := xml.NewDecoder(io.Reader(f))
// must pass an interface pointer to Decode
err = song.Decode(&Score{})
if err != nil {
fmt.Fprintf(os.Stderr, "Error assigning musicXML file to struct: %v\n", err)
os.Exit(1)
}
return song
}
Here's the first few structs (the rest follow the same format):
type Score struct {
Work Work `xml:"work"`
Identification Identification `xml:"identification"`
Defaults Defaults `xml:"defaults"`
Credit Credit `xml:"credit"`
Partlist []Scorepart `xml:"score-part"`
Part []Part `xml:"part"`
}
// Name and other idenfication
type Work struct {
Number string `xml:"work-number"`
Title string `xml:"work-title"`
}
type Identification struct {
Type string `xml:"type,attr"`
Creator string `xml:"creator"`
Software string `xml:"software"`
Date string `xml:"encoding-date"`
Supports []Supports `xml:"supports"`
Source string `xml:"source"`
}
I greatly appreciate any insight.
</details>
# 答案1
**得分**: 1
我认为你误解了解码器的行为:它将 XML 解码为你传递给 `Decode` 方法的对象:
```go
song := xml.NewDecoder(io.Reader(f))
score := Score{}
err = song.Decode(&score)
// 解码后的文档在 score 中,而不是在 song 中
return score
你把解码器当作包含文档的对象处理,但它只是一个解码器。它用于解码。为了在代码中更清晰,它的名称不应该是 song
,可以命名为 decoder
、scoreDecoder
或其他适当的名称。你几乎肯定不想从函数中返回一个 *xml.Decoder*
,而是返回解码后的 Score
对象。
英文:
I think you've misunderstood the behavior of the decoder: it decodes XML into the object you pass to Decode
:
song := xml.NewDecoder(io.Reader(f))
score := Score{}
err = song.Decode(&score)
// Decoded document is in score, *NOT* in song
return score
You're treating the decoder as if it will contain your document, but it's just a decoder. It decodes. To make it clearer in code, it should not be named song
- it should be named, say, decoder
or scoreDecoder
or what have you. You almost certainly don't want to return an *xml.Decoder*
from your function, but rather the decoded Score
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论