doutuan4361
2019-06-17 18:42
浏览 137

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

Few of the XML tags are not getting decoded while reading the request body

I have defined my nested struct with both json and xml tags, as I want to use the same schema for request and response in both json and xml.

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

DataTestplan struct:

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

Testplan struct:

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

Parameter struct:

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

Teststep struct:

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

XML sent :

<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 decoded:

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

I understand missing tags are most probably because of miss tagging of xml in the struct definition but I am not sure why the decoded information is missing value for tags ? What's the trick with XML and JSON encoding ?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • dqzuo0327 2019-06-17 20:04
    已采纳

    You can use > in the tags.

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

    If the XML element contains a sub-element whose name matches the prefix of a tag formatted as "a" or "a>b>c", unmarshal will descend into the XML structure looking for elements with the given names, and will map the innermost elements to that struct field. A tag starting with ">" is equivalent to one starting with the field name followed by ">".

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

    If a field uses a tag "a>b>c", then the element c will be nested inside parent elements a and b. Fields that appear next to each other that name the same parent will be enclosed in one XML element.

    For example:

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

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

    点赞 打赏 评论
  • doyou62860 2019-06-17 20:24

    There is no need to create a different struct for each tag. You can embed them all in one. For the xml parsing you are missing a few tags. You can avoid some code replication by using the > in the xml tag. This will effectively "merge" two elements when you iterate them. Here is an example on a more concise implementation:

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

    By running:

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

    you get:

    <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>
    
    点赞 打赏 评论

相关推荐 更多相似问题