嵌套的XML / JSON结构标签,定义结构的正确方法是什么?

时间:2019-06-17 18:42:03

标签: xml go struct xmlhttprequest

在读取请求正文时,很少有XML标记未得到解码

我已经使用json和xml标签定义了嵌套结构,因为我想在json和xml中使用相同的架构进行请求和响应。

var dataNewTestplans DataTestplan
err := xml.NewDecoder(r.Body).Decode(&dataNewTestplans)
xmlData, _ := xml.Marshal(dataNewTestplans)
fmt.Printf(string(xmlData))

DataTestplan结构:

type DataTestplan struct {
    Data []Testplan `json:"data" xml:"data"`
}

Testplan结构:

type Testplan struct {
    Group      string      `json:"group" xml:"group"`
    Name       string      `json:"name" xml:"name"`
    Parameters []Parameter `json:"parameters,omitempty" xml:"parameters,omitempty"`
    Released   bool        `json:"released" xml:"released"`
    Teststeps  []Teststep  `json:"teststeps,omitempty" xml:"teststeps,omitempty"`
    Version    int32       `json:"version" xml:"version"`
}

参数结构:

type Parameter struct {
    XMLName     xml.Name `xml:"parameters"`
    Comment     string   `json:"comment" xml:"comment"`
    Description string   `json:"description,omitempty" xml:"description,omitempty"`
}

Teststep结构:

type Teststep struct {
    XMLName xml.Name `xml:"teststeps"`
    AslID   string   `json:"aslId,omitempty" xml:"aslID"`
    Bin     int32    `json:"bin,omitempty" xml:"bin"`
}

发送的XML:

<root>
  <data>
    <element>
     <group>TEST</group>
     <name>TEST</name>
     <parameters>
        <element>
           <comment>test</comment>
           <description>test</description>
        </element>
        <element>
           <comment>test1</comment>
        </element>
     </parameters>
     <released>true</released>
     <teststeps>
        <element>
           <bin>32</bin>
        </element>
      </teststeps>
     <version>1</version>
    </element>
  </data>
</root>

XML解码:

<DataTestplan>
  <data>
    <group></group>
    <name></name>
    <released>false</released>
    <version>0</version>
    </data>
</DataTestplan>

我了解丢失的标签很可能是由于struct定义中的xml缺少标签,但是我不确定为什么解码后的信息缺少标签的值? XML和JSON编码的窍门是什么?

2 个答案:

答案 0 :(得分:0)

您可以在标签中使用>

https://golang.org/pkg/encoding/xml/#Unmarshal

  

如果XML元素包含名称与   标记格式为“ a”或“ a> b> c”的前缀,解组将下降   进入XML结构,以查找具有给定名称的元素,并且   将最里面的元素映射到该结构域。标签开始   以“>”开头的等价于以字段名开头的   “>”。

https://golang.org/pkg/encoding/xml/#Marshal

  

如果字段使用标签“ a> b> c”,则元素c将被嵌套   在父元素a和b中。彼此相邻出现的字段   该名称相同的父对象将包含在一个XML元素中。

例如:

type DataTestplan struct {
    Data []Testplan `json:"data" xml:"data>element"`
}

https://play.golang.com/p/RX3IDI3zubo

答案 1 :(得分:0)

无需为每个标签创建不同的结构。您可以将它们全部嵌入一个。对于xml解析,您缺少一些标签。您可以通过使用xml标记中的>来避免某些代码复制。当您迭代两个元素时,这将有效地“合并”两个元素。这是一个更简洁的实现示例:

type Root struct {
    XMLName xml.Name `xml:"root"`
    Data    []struct {
        Group      string `json:"group" xml:"group"`
        Name       string `json:"name" xml:"name"`
        Parameters []struct {
            Comment     string `json:"comment" xml:"comment,omitempty"`
            Description string `json:"description" xml:"description,omitempty"`
        } `json:"parameters" xml:"parameters>element"`
        Released  bool `json:"released" xml:"released"`
        Teststeps []struct {
            Bin int32 `json:"bin" xml:"bin"`
        } `xml:"teststeps>element,omitempty"`
        Version int32 `json:"version" xml:"version"`
    } `json:"data" xml:"data>element"`
}

通过运行:

var dataNewTestplans DataTestplan
err := xml.NewDecoder(r.Body).Decode(&dataNewTestplans)
xmlData, _ := xml.Marshal(dataNewTestplans)
fmt.Printf(string(xmlData))

您得到:

<root><data><element><group>TEST</group><name>TEST</name><parameters><element><comment>test</comment><description>test</description></element><element><comment>test1</comment></element></parameters><released>true</released><teststeps><element><bin>32</bin></element></teststeps><version>1</version></element></data></root>