【问题标题】:Nested XML/JSON struct tags, what's the correct way to define structs?嵌套的 XML/JSON 结构标签,定义结构的正确方法是什么?
【发布时间】:2019-06-18 04:24:55
【问题描述】:

在读取请求正文时,很少有 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"`
}

测试计划结构:

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"`
}

测试步结构:

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>

我知道缺少标签很可能是因为结构定义中缺少 xml 标记,但我不确定为什么解码后的信息缺少标签值? XML 和 JSON 编码有什么技巧?

【问题讨论】:

  • 只需根据您的定义检查您的 XML,或者在 Go 中完整填写一个结构并将其导出为 XML,然后将其与您的输入进行比较。我马上就看到了一些事情;您的根元素是root,而不是DataTestPlan,因此需要添加XMLName,并且XML 中出现element 元素的多个位置根本没有映射到您的结构中(结构定义只是忽略它并尝试映射其子项,就好像它不存在一样)。
  • 它是否“不是结构”并不重要,它需要在您的映射中处理。你不能假装它不存在。例如。 Parameters 不应该是一个切片,因为只有一个 parameters 元素。 parameters 包含一部分element元素。

标签: xml go struct xmlhttprequest


【解决方案1】:

您可以在标签中使用&gt;

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

如果 XML 元素包含名称与 格式为“a”或“a>b>c”的标签的前缀,unmarshal 将下降 到 XML 结构中查找具有给定名称的元素,以及 将最里面的元素映射到该结构字段。一个标签开始 with ">" 等价于以字段名开头后跟 ">"。

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

【讨论】:

  • 谢谢!我不知道“>”。这是一件小事:)
【解决方案2】:

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

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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-04
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    • 2022-09-27
    相关资源
    最近更新 更多