Вложенные теги структуры XML / JSON, как правильно определить структуры? - PullRequest
0 голосов
/ 17 июня 2019

Немногие из тегов 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"`
}

Тестовый шагstruct:

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?

Ответы [ 2 ]

0 голосов
/ 17 июня 2019

Нет необходимости создавать разные структуры для каждого тега. Вы можете встроить их все в одно. Для разбора 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>
0 голосов
/ 17 июня 2019

Вы можете использовать > в тегах.

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

Если элемент XML содержит подэлемент, имя которого совпадает с префиксом тега, отформатированного как"a" или "a> b> c", unmarshal спустится в структуру 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...