在Golang中解析XML字符串时,<nil>表示空值或空指针。

huangapple go评论85阅读模式
英文:

<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)
}

以上是你提供的代码,已经进行了一些修改。请注意以下几点:

  1. Book结构体中,将title字段的标签改为xml:"title,attr",以指示它是一个属性。
  2. Books结构体中,将BookList字段的标签改为xml:"Books>Book",以指示它是Books元素下的Book元素列表。
  3. main函数中,将xml.Unmarshal的返回值存储在变量err中,并通过调用check函数来检查错误。
  4. 打印解析后的结果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 (
    &quot;fmt&quot;
	//&quot;io/ioutil&quot;
    &quot;encoding/xml&quot;
)

func check(e error) {
    if e != nil {
	    panic(e)
    }
}

type Books struct {
    XMLName xml.Name `xml:&quot;Books&quot;`
    BookList []Book `xml:&quot;Books&gt;Book&quot;`
}

type Book struct {
    title string `xml:&quot;title,attr&quot;`
	author string
    published string
}

func main() {
    //f, err := ioutil.ReadFile(&quot;xml/Books.xml&quot;)
	//check(err)

	var data = []byte(`
		&lt;Books&gt;
			&lt;Book title=&quot;A Brief History of Time&quot; author=&quot;Stephen Hawking&quot; published=&quot;1988&quot;&gt;
				&lt;title&gt;title here&lt;/title&gt;
				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.
			&lt;/Book&gt;
			&lt;Book title=&quot;Steve Jobs&quot; author=&quot;Walter Isaacson&quot; published=&quot;2011&quot;&gt;
				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.
			&lt;/Book&gt;
		&lt;/Books&gt;
	`)

	b := Books{}
	o := xml.Unmarshal([]byte(data), &amp;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 (
    &quot;fmt&quot;
    //&quot;io/ioutil&quot;
    &quot;encoding/xml&quot;
)

func check(e error) {
    if e != nil {
        panic(e)
    }
}

type Books struct {
    XMLName xml.Name `xml:&quot;Books&quot;`
    BookList []Book `xml:&quot;Book&quot;`
}

type Book struct {
    Title string `xml:&quot;title,attr&quot;`
    Author string `xml:&quot;author,attr&quot;`
    Published string `xml:&quot;published,attr&quot;`
}

func main() {
    //f, err := ioutil.ReadFile(&quot;xml/Books.xml&quot;)
    //check(err)

    var data = []byte(`
        &lt;Books&gt;
            &lt;Book title=&quot;A Brief History of Time&quot; author=&quot;Stephen Hawking&quot; published=&quot;1988&quot;&gt;
                &lt;title&gt;title here&lt;/title&gt;
                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.
            &lt;/Book&gt;
            &lt;Book title=&quot;Steve Jobs&quot; author=&quot;Walter Isaacson&quot; published=&quot;2011&quot;&gt;
                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.
            &lt;/Book&gt;
        &lt;/Books&gt;
    `)

    b := Books{}
    o := xml.Unmarshal([]byte(data), &amp;b)
    fmt.Println(o)
    fmt.Println(b)
}

Here's a rundown of the four changes I made;

  1. print the Books object instead of the err returned from Unmarshal

  2. 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)

  3. 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

  4. 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 is Books, the elements you want in that list would have a relative xpath of simply Book so that's what you put there.

huangapple
  • 本文由 发表于 2015年10月14日 04:42:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/33112235.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定