使用包含切片的结构时xml恶作剧?

时间:2014-04-25 10:59:57

标签: xml go

我尝试了以下代码,以便了解为什么我在golang中遇到xml问题。

据我所知,我应该能够编组一个结构,然后将结果数据解组成一个相同类型的结构?

结果我期望的是一个包含一片子节点的父结构,而不是子切片是nil?

playground link

package main

import (
    "encoding/xml"
    "fmt"
)

type Parent struct {
    XMLName  xml.Name `xml:"parent"`
    Children []Child  `xml:"children"`
}

type Child struct {
    XMLName xml.Name `xml:"child"`
    ID      int      `xml:"ID"`
}

func main() {
    children := make([]Child, 3)

    for i := range children {
        children[i] = Child{ID: i}
    }

    p1 := Parent{Children: children}

    data, err := xml.Marshal(p1)

    if err != nil {
        fmt.Printf("Error during marshal: %v\n", err)
    }

    fmt.Printf("Raw XML: %v\n", string(data))

    p2 := Parent{}

    err = xml.Unmarshal(data, &p2)

    if err != nil {
        fmt.Printf("Error during unmarshal: %v\n", err)
    }

    fmt.Printf("Unmarshalled struct: %v\n", p2)
}

1 个答案:

答案 0 :(得分:1)

它的工作原理不是这样的:结构和XML之间没有临时双射。

E.g。您生成以下XML

<parent><child><ID>0</ID></child><child><ID>1</ID></child></parent>

因为您的Child类型的字段XMLName xml.Name带有xml标记&#34; child&#34;。 这就是Marshaling的工作方式。来自http://tip.golang.org/pkg/encoding/xml/#Marshal

  

XML元素的名称取自优先顺序:

     
      
  • XMLName字段上的标记,如果数据是结构
  •   
  • xml.Name
  • 类型的XMLName字段的值   
  • 用于获取数据的struct字段的标记
  •   
  • 用于获取数据的struct字段的名称
  •   
  • 编组类型的名称
  •   

现在看看如果您尝试解组它会发生什么: 您的Parent类型将其字段Children []Child标记为&#34; children&#34; 但是您的XML内部没有<children>标记,只有<child>

如果您使用

type Parent struct {
    XMLName  xml.Name `xml:"parent"`
    Children []Child  `xml:"child"`  // "child", not "children"
}

它的工作方式与您的意图相同。