英文:
<nil> when parsing xml string in golang
问题
我想使用golang
解析xml
。作为一个新手,我已经阅读了一些网上的文章,解释了如何解析XML,但我不确定为什么在这种情况下我的返回值是nil
。
package main
import (
"fmt"
"encoding/xml"
)
func check(e error) {
if e != nil {
panic(e)
}
}
type Books struct {
XMLName xml.Name `xml:"Books"`
BookList []Book `xml:"Books>Book"`
}
type Book struct {
Title string `xml:"title,attr"`
Author string
Published string
}
func main() {
var data = []byte(`
<Books>
<Book title="A Brief History of Time" author="Stephen Hawking" published="1988">
<title>title here</title>
A Brief History of Time: From the Big Bang to Black Holes is a 1988 popular-science book by British physicist Stephen Hawking. It became a bestseller and sold more than 10 million copies in 20 years.
</Book>
<Book title="Steve Jobs" author="Walter Isaacson" published="2011">
Steve Jobs is the authorized self-titled biography book of Steve Jobs. The book was written at the request of Jobs by Walter Isaacson, a former executive at CNN.
</Book>
</Books>
`)
b := Books{}
err := xml.Unmarshal([]byte(data), &b)
check(err)
fmt.Println(b)
}
以上是你提供的代码,已经进行了一些修改。请注意以下几点:
- 在
Book
结构体中,将title
字段的标签改为xml:"title,attr"
,以指示它是一个属性。 - 在
Books
结构体中,将BookList
字段的标签改为xml:"Books>Book"
,以指示它是Books
元素下的Book
元素列表。 - 在
main
函数中,将xml.Unmarshal
的返回值存储在变量err
中,并通过调用check
函数来检查错误。 - 打印解析后的结果
b
。
希望这可以帮助你解决问题!
英文:
I would like to parse xml
using golang
. Being new to using go
, I've read articles around the web, explaining how to parse XML but I'm not sure why my return value is nil
in this case.
package main
import (
"fmt"
//"io/ioutil"
"encoding/xml"
)
func check(e error) {
if e != nil {
panic(e)
}
}
type Books struct {
XMLName xml.Name `xml:"Books"`
BookList []Book `xml:"Books>Book"`
}
type Book struct {
title string `xml:"title,attr"`
author string
published string
}
func main() {
//f, err := ioutil.ReadFile("xml/Books.xml")
//check(err)
var data = []byte(`
<Books>
<Book title="A Brief History of Time" author="Stephen Hawking" published="1988">
<title>title here</title>
A Brief History of Time: From the Big Bang to Black Holes is a 1988 popular-science book by British physicist Stephen Hawking. It became a bestseller and sold more than 10 million copies in 20 years.
</Book>
<Book title="Steve Jobs" author="Walter Isaacson" published="2011">
Steve Jobs is the authorized self-titled biography book of Steve Jobs. The book was written at the request of Jobs by Walter Isaacson, a former executive at CNN.
</Book>
</Books>
`)
b := Books{}
o := xml.Unmarshal([]byte(data), &b)
fmt.Println(o)
}
答案1
得分: 2
我将调试反馈放在了注释中,但我刚刚修改了你的示例使其可以工作,并且可以在这里进行测试:https://play.golang.org/p/_UIph2je7f
package main
import (
"fmt"
// "io/ioutil"
"encoding/xml"
)
func check(e error) {
if e != nil {
panic(e)
}
}
type Books struct {
XMLName xml.Name `xml:"Books"`
BookList []Book `xml:"Book"`
}
type Book struct {
Title string `xml:"title,attr"`
Author string `xml:"author,attr"`
Published string `xml:"published,attr"`
}
func main() {
// f, err := ioutil.ReadFile("xml/Books.xml")
// check(err)
var data = []byte(`
<Books>
<Book title="A Brief History of Time" author="Stephen Hawking" published="1988">
<title>title here</title>
A Brief History of Time: From the Big Bang to Black Holes is a 1988 popular-science book by British physicist Stephen Hawking. It became a bestseller and sold more than 10 million copies in 20 years.
</Book>
<Book title="Steve Jobs" author="Walter Isaacson" published="2011">
Steve Jobs is the authorized self-titled biography book of Steve Jobs. The book was written at the request of Jobs by Walter Isaacson, a former executive at CNN.
</Book>
</Books>
`)
b := Books{}
o := xml.Unmarshal([]byte(data), &b)
fmt.Println(o)
fmt.Println(b)
}
以下是我所做的四个更改的概述:
1)打印Unmarshal
返回的Books
对象,而不是错误。
2)将Book
中的字段的首字母大写,使它们成为“可导出”的,以便其他包可以获取/设置它们(在这种情况下是解组器)。
3)添加XML属性。通过导出字段,可以避免隐式字符串匹配,因此您需要明确指定将读入每个字段的XML值。
4)更新BookList
的XML路径。你说它应该是Books>Book,但这意味着在你的XML中存在另一层嵌套。这个对象是Books
,你想要的列表中的元素的相对XPath只是Book
,所以你在那里放置了它。
英文:
I put the debugging feedback in a comment but I've just modified your example to work and it can be tested here; https://play.golang.org/p/_UIph2je7f
package main
import (
"fmt"
//"io/ioutil"
"encoding/xml"
)
func check(e error) {
if e != nil {
panic(e)
}
}
type Books struct {
XMLName xml.Name `xml:"Books"`
BookList []Book `xml:"Book"`
}
type Book struct {
Title string `xml:"title,attr"`
Author string `xml:"author,attr"`
Published string `xml:"published,attr"`
}
func main() {
//f, err := ioutil.ReadFile("xml/Books.xml")
//check(err)
var data = []byte(`
<Books>
<Book title="A Brief History of Time" author="Stephen Hawking" published="1988">
<title>title here</title>
A Brief History of Time: From the Big Bang to Black Holes is a 1988 popular-science book by British physicist Stephen Hawking. It became a bestseller and sold more than 10 million copies in 20 years.
</Book>
<Book title="Steve Jobs" author="Walter Isaacson" published="2011">
Steve Jobs is the authorized self-titled biography book of Steve Jobs. The book was written at the request of Jobs by Walter Isaacson, a former executive at CNN.
</Book>
</Books>
`)
b := Books{}
o := xml.Unmarshal([]byte(data), &b)
fmt.Println(o)
fmt.Println(b)
}
Here's a rundown of the four changes I made;
-
print the
Books
object instead of the err returned fromUnmarshal
-
uppercase the first letter of fields on
Book
to make them 'exported' so they can be get/set by other packages (the unmarshaller in this case) -
add xml attributes. In exporting the fields it makes it so there isn't an implicit string match so you gotta explicitly specify which xml value is read into each field
-
update the XML path for
BookList
for this you said it would be Books>Book but that implies another level of nesting that didn't exist in your xml. This object isBooks
, the elements you want in that list would have a relative xpath of simplyBook
so that's what you put there.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论