英文:
Golang specify top-level tag in xml structure
问题
所以我正在尝试将一些XML解组或解码为类型(我还不完全清楚它们之间的区别),但似乎无法指定最外层的类型(在这种情况下是<people>
)。当我尝试指定此标签时,不会出现错误,但编组值不包含我期望的任何内容。如何指定最外层的标签,为什么第二个赋值没有预期的行为?
package main
import "fmt"
import "encoding/xml"
import "log"
var data string = `
<people>
<person>
<id>46</id>
<name>John Smith</name>
</person>
<person>
<id>3007</id>
<name>Joe Smith</name>
</person>
</people>
`
type Person struct {
Id int `xml:"id"`
Name string `xml:"name"`
}
type People struct {
PersonList []Person `xml:"person"`
}
type Response struct {
PeopleItem People `xml:"people"`
}
func main() {
// 解析People
// 无法指定最外层标签<people></people>
var people People
err := xml.Unmarshal([]byte(data), &people)
if err != nil {
log.Fatal(err)
}
fmt.Println(people)
// 输出"{[{46 John Smith} {3007 Joe Smith}]}"
// 这是合理的
// 尝试解析整个响应,得到的是一个空切片的结构体的结构体
var response Response
err = xml.Unmarshal([]byte(data), &response)
if err != nil {
log.Fatal(err)
}
// response是一个空数组的结构体的结构体
// 为什么会这样?
fmt.Println(response)
// 为什么会输出"{{[]}}"?
}
以上是你提供的代码的翻译。
英文:
So I am trying to Unmarshal or Decode some xml into a type (I am still not entirely clear on what the difference is), and I don't seem to be able to specify the outermost type (in this case <people>
). When I try to specify this tag, instead of getting an error, the Marshalled value does not contain any of the content I am expecting. How do you specify the outermost tag and why doesn't the second assignment have the expected behavior?
package main
import "fmt"
import "encoding/xml"
import "log"
var data string = `
<people>
<person>
<id>46</id>
<name>John Smith</name>
</person>
<person>
<id>3007</id>
<name>Joe Smith</name>
</person>
</people>
`
type Person struct {
Id int `xml:"id"`
Name string `xml:"name"`
}
type People struct {
PersonList []Person `xml:"person"`
}
type Response struct {
PeopleItem People `xml:"people"`
}
func main() {
// parsing People
// cannot specify outermost tag <people></people>
var people People
err := xml.Unmarshal([]byte(data), &people)
if err != nil {
log.Fatal(err)
}
fmt.Println(people)
// prints "{[{46 John Smith} {3007 Joe Smith}]}"
// which is reasonable
// attempting to parse entire response, yields struct of struct of empty slice
var response Response
err = xml.Unmarshal([]byte(data), &response)
if err != nil {
log.Fatal(err)
}
// response is struct of struct of empty array
// why does this happen?
fmt.Println(response)
// why does this print "{{[]}}" ?
}
答案1
得分: 2
你可以在不修改传入数据的情况下完成这个操作,你可以使用特殊的XMLName xml.Name
字段来设置外部标签,然后使用xml:",chardata"
来访问其内容。
以下是一个示例:在Go Playground上试一试
package main
import (
"encoding/xml"
"fmt"
)
type simpleInt struct {
XMLName xml.Name `xml:"integer"`
Int int `xml:",chardata"`
}
type simpleString struct {
XMLName xml.Name `xml:"stringtag"`
String string `xml:",chardata"`
}
type simpleBoolean struct {
XMLName xml.Name `xml:"boolean"`
Boolean bool `xml:",chardata"`
}
func main() {
bint := []byte("<integer>1138</integer>")
bstring := []byte("<stringtag>Caimeo</stringtag>")
btrue := []byte("<boolean>true</boolean>")
bfalse := []byte("<boolean>false</boolean>")
i := simpleInt{}
xml.Unmarshal(bint, &i)
fmt.Println(i, i.Int)
s := simpleString{}
xml.Unmarshal(bstring, &s)
fmt.Println(s, s.String)
m := simpleBoolean{}
xml.Unmarshal(btrue, &m)
fmt.Println(m, m.Boolean)
xml.Unmarshal(bfalse, &m)
fmt.Println(m, m.Boolean)
}
英文:
You can do this without hacking the incoming data, you use the special XMLName xml.Name
field to set the outside tag and then use xml:",chardata"
to access it's contents.
Here is an example: Try it on the go playground
package main
import (
"encoding/xml"
"fmt"
)
type simpleInt struct {
XMLName xml.Name `xml:"integer"`
Int int `xml:",chardata"`
}
type simpleString struct {
XMLName xml.Name `xml:"stringtag"`
String string `xml:",chardata"`
}
type simpleBoolean struct {
XMLName xml.Name `xml:"boolean"`
Boolean bool `xml:",chardata"`
}
func main() {
bint := []byte("<integer>1138</integer>")
bstring := []byte("<stringtag>Caimeo</stringtag>")
btrue := []byte("<boolean>true</boolean>")
bfalse := []byte("<boolean>false</boolean>")
i := simpleInt{}
xml.Unmarshal(bint, &i)
fmt.Println(i, i.Int)
s := simpleString{}
xml.Unmarshal(bstring, &s)
fmt.Println(s, s.String)
m := simpleBoolean{}
xml.Unmarshal(btrue, &m)
fmt.Println(m, m.Boolean)
xml.Unmarshal(bfalse, &m)
fmt.Println(m, m.Boolean)
}
答案2
得分: 1
这里有一个简单的解决方案:添加一个新的独特的顶级元素:
var response Response
err = xml.Unmarshal([]byte("<foo>"+data+"</foo>"), &response)
英文:
Here's a lazy solution: add a new, unique top level element:
var response Response
err = xml.Unmarshal([]byte("<foo>"+data+"</foo>"), &response)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论