douqian4411 2015-10-29 00:05
浏览 219
已采纳

Golang在xml结构中指定顶级标签

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 "{{[]}}" ?
}
  • 写回答

2条回答 默认 最新

  • dqfsbvd43312 2017-09-07 19:24
    关注

    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)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 Python时间序列如何拟合疏系数模型
  • ¥15 求学软件的前人们指明方向🥺
  • ¥50 如何增强飞上天的树莓派的热点信号强度,以使得笔记本可以在地面实现远程桌面连接
  • ¥20 双层网络上信息-疾病传播
  • ¥50 paddlepaddle pinn
  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services