Вопрос или проблема
Я пытаюсь разобрать метаданные EPUB с использованием языка программирования Go. XML, который я сейчас разбираю, очень простой:
<?xml version="1.0" encoding="UTF-8"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
<rootfiles>
<rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>
</rootfiles>
</container>
Я хочу получить атрибуты full-path
и media-type
, и код на Go выглядит так:
package main
import (
"fmt"
"encoding/xml"
)
type RootFile struct {
FullPath string `xml:"full-path,attr"`
MediaType string `xml:"media-type,attr"`
}
func main() {
xmlData := `
<?xml version="1.0" encoding="UTF-8"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
<rootfiles>
<rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>
</rootfiles>
</container>
`
var rootFile RootFile
xml.Unmarshal([]byte(xmlData), &rootFile)
fmt.Println(rootFile)
}
Но я получаю пустой результат:
{ }
Что не так с моим кодом?
Я не верю, что Go поддерживает тег container
“из коробки”, поэтому я думаю, что вы просто не разбираете XML полностью.
Эти типы должны быть полным разбором:
type Container struct {
Version string `xml:"version,attr"`
Xmlns string `xml:"xmlns,attr"`
RootFiles RootFiles `xml:"rootfiles"`
}
type RootFiles struct {
Rootfile RootFile `xml:"rootfile"`
}
type RootFile struct {
FullPath string `xml:"full-path,attr"`
MediaType string `xml:"media-type,attr"`
}
Но вам не нужно объявлять поля, которые вас не интересуют, такие как version
и xmlns
. Тем не менее, вам все равно нужно выразить всю структуру дерева XML. Вот полный рабочий пример:
package main
import (
"encoding/xml"
"fmt"
)
type Container struct {
Version string `xml:"version,attr"`
Xmlns string `xml:"xmlns,attr"`
RootFiles RootFiles `xml:"rootfiles"`
}
type RootFiles struct {
RootFile RootFile `xml:"rootfile"`
}
type RootFile struct {
FullPath string `xml:"full-path,attr"`
MediaType string `xml:"media-type,attr"`
}
func main() {
xmlData := `
<?xml version="1.0" encoding="UTF-8"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
<rootfiles>
<rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>
</rootfiles>
</container>
`
var rootFile Container
err := xml.Unmarshal([]byte(xmlData), &rootFile)
if err != nil {
fmt.Printf("Что-то пошло не так: %v", err)
}
fmt.Printf("RootFile->full-path %v\nRootFile->media-type %v\n",
rootFile.RootFiles.RootFile.FullPath,
rootFile.RootFiles.RootFile.MediaType)
}
Ответ или решение
Конечно! Давайте разберёмся с вашей проблемой, связанной с парсингом XML в языке Go. Ваша задача состоит в том, чтобы извлечь атрибуты full-path
и media-type
из XML-документа, однако исходный код не обеспечивает полного разбора структуры XML.
Вот исправленный пример кода, который правильно организует структуру Go для вашего XML, чтобы избежать проблем с отсутствием значений:
package main
import (
"encoding/xml"
"fmt"
)
// Определяем структуры для представления XML
type Container struct {
Version string `xml:"version,attr"`
Xmlns string `xml:"xmlns,attr"`
RootFiles RootFiles `xml:"rootfiles"`
}
type RootFiles struct {
RootFile RootFile `xml:"rootfile"`
}
type RootFile struct {
FullPath string `xml:"full-path,attr"`
MediaType string `xml:"media-type,attr"`
}
func main() {
xmlData := `
<?xml version="1.0" encoding="UTF-8"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
<rootfiles>
<rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>
</rootfiles>
</container>
`
var container Container
err := xml.Unmarshal([]byte(xmlData), &container)
if err != nil {
fmt.Printf("Что-то пошло не так: %v\n", err)
return
}
fmt.Printf("Полный путь: %v\nТип медиа: %v\n",
container.RootFiles.RootFile.FullPath,
container.RootFiles.RootFile.MediaType)
}
Объяснение кода:
-
Структура
Container
: Это основная структура, которая представляет корневой элемент<container>
. В ней указаны атрибутыversion
иxmlns
, а также содержимоеRootFiles
. -
Структура
RootFiles
: Представляет элемент<rootfiles>
и содержит структуруRootFile
. -
Структура
RootFile
: В этой структуре представлена информация, которую вы хотите извлечь, включая атрибутыfull-path
иmedia-type
. -
Функция
main
: Здесь мы объявляем XML-строку, парсим её с помощьюxml.Unmarshal
, и выводим на экран желаемые атрибуты.
Примечание:
В вашем исходном коде вы не разбирали древовидную структуру XML. Важно создавать структуры, соответствующие иерархии XML для корректной работы с Unmarshal
. Обратите внимание, что в XML в вашем примере использовались символы <
и >
, которые являются HTML-сущностями для «<» и «>». Они должны быть заменены соответствующими символами, как показано в исправленном коде.
Теперь вы должны получить корректные значения атрибутов full-path
и media-type
. Надеюсь, что это поможет вам успешно решить вашу задачу с парсингом EPUB-метаданных!