Golang Decode MusicXML

Я пишу программу, которая может читать полный файл MusicXML, редактировать его и записывать новый файл. Я использую xml.Decode для чтения данных в структуру для файла MusicXML, но когда я запускаю его, кажется, ничего не происходит. Я попытался распечатать объект Decode на экране, но он напечатал структуру, полную байтов.

Я просмотрел страницу пакета xml и, похоже, не могу найти какие-либо темы, охватывающие функцию Decode. Я пытался использовать UnMarshall в соответствии с некоторыми найденными указателями, но это не сработало (большинство из этих потоков были более старыми, поэтому, возможно, UnMarshall работает немного иначе, так как декодирование было реализовано?).

Вот функция ввода:

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
}

Вот первые несколько структур (остальные следуют тому же формату):

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"`
}

Я очень ценю любое понимание.

1 ответ

Я думаю, вы неправильно поняли поведение декодера: он декодирует XML в объект, который вы передаетеDecode:

song := xml.NewDecoder(io.Reader(f))
score := Score{}
err = song.Decode(&score)
// Decoded document is in score, *NOT* in song
return score

Вы рассматриваете декодер так, как будто он будет содержать ваш документ, но это просто декодер. Это декодирует. Чтобы сделать его более понятным в коде, его не следует называть song - это должно быть названо, скажем, decoder или же scoreDecoder или что у тебя. Вы почти наверняка не хотите возвращать *xml.Decoder* от вашей функции, а точнее декодированной Score,

Другие вопросы по тегам