Метод xml.Decoder.Decode

Метод xml.Decoder.Decode считывает следующий XML-элемент из потока и декодирует его в переданную структуру или другой тип данных. В первый параметр метод принимает указатель на переменную, в которую будет записан результат декодирования. Метод возвращает ошибку error, которая будет равна io.EOF при достижении конца данных или другой ошибке при разборе XML.

Синтаксис

goerr := decoder.Decode(&v)

где decoder - это указатель на xml.Decoder, а v - переменная для хранения результата.

Пример

Давайте декодируем простой XML-документ в структуру:

gopackage main

import (
  "encoding/xml"
  "fmt"
  "strings"
)

type Person struct {
  XMLName xml.Name `xml:"person"`
  Name  string   `xml:"name"`
  Age   int    `xml:"age"`
}

func main() {
  data := `<person><name>John</name><age>30</age></person>`
  reader := strings.NewReader(data)
  decoder := xml.NewDecoder(reader)

  var person Person
  err := decoder.Decode(&person)
  if err != nil {
    fmt.Println(err)
    return
  }

  fmt.Printf("%+v\n", person)
}

Результат выполнения кода:

go{XMLName:{Space: Local:person} Name:John Age:30}

В этом примере мы создали структуру Person с тегами xml, которые сопоставляют поля с элементами XML. Метод Decode автоматически заполнил структуру данными из XML.

Пример

Рассмотрим декодирование XML с атрибутами:

gopackage main

import (
  "encoding/xml"
  "fmt"
  "strings"
)

type User struct {
  XMLName xml.Name `xml:"user"`
  ID    int    `xml:"id,attr"`
  Name  string   `xml:"name"`
  Active  bool   `xml:"active,attr"`
}

func main() {
  data := `<user id="42" active="true"><name>Alice</name></user>`
  reader := strings.NewReader(data)
  decoder := xml.NewDecoder(reader)

  var user User
  err := decoder.Decode(&user)
  if err != nil {
    fmt.Println(err)
    return
  }

  fmt.Printf("%+v\n", user)
}

Результат выполнения кода:

go{XMLName:{Space: Local:user} ID:42 Name:Alice Active:true}

Атрибуты XML автоматически сопоставляются с полями структуры, если указать ,attr в теге.

Пример

Давайте обработаем XML с вложенными элементами:

gopackage main

import (
  "encoding/xml"
  "fmt"
  "strings"
)

type Address struct {
  City  string `xml:"city"`
  Street  string `xml:"street"`
  ZipCode string `xml:"zip"`
}

type Employee struct {
  XMLName xml.Name `xml:"employee"`
  Name  string   `xml:"name"`
  Age   int    `xml:"age"`
  Address Address  `xml:"address"`
}

func main() {
  data := `<employee>
    <name>Bob</name>
    <age>28</age>
    <address>
      <city>New York</city>
      <street>5th Ave</street>
      <zip>10001</zip>
    </address>
  </employee>`

  reader := strings.NewReader(data)
  decoder := xml.NewDecoder(reader)

  var employee Employee
  err := decoder.Decode(&employee)
  if err != nil {
    fmt.Println(err)
    return
  }

  fmt.Printf("Name: %s\n", employee.Name)
  fmt.Printf("Age: %d\n", employee.Age)
  fmt.Printf("City: %s\n", employee.Address.City)
  fmt.Printf("Street: %s\n", employee.Address.Street)
  fmt.Printf("Zip: %s\n", employee.Address.ZipCode)
}

Результат выполнения кода:

goName: Bob
Age: 28
City: New York
Street: 5th Ave
Zip: 10001

Вложенные XML-элементы декодируются в соответствующие вложенные структуры, что делает код чистым и организованным.

Пример

Рассмотрим обработку ошибок при декодировании некорректного XML:

gopackage main

import (
  "encoding/xml"
  "fmt"
  "strings"
)

type Product struct {
  XMLName xml.Name `xml:"product"`
  Name  string   `xml:"name"`
  Price   float64  `xml:"price"`
}

func main() {
  // Некорректный XML с незакрытым тегом
  data := `<product><name>Laptop<price>999.99</product>`
  reader := strings.NewReader(data)
  decoder := xml.NewDecoder(reader)

  var product Product
  err := decoder.Decode(&product)
  if err != nil {
    fmt.Printf("Error: %v\n", err)
    return
  }

  fmt.Printf("%+v\n", product)
}

Результат выполнения кода:

goError: XML syntax error on line 1: unexpected EOF

Метод возвращает понятную ошибку синтаксического анализа, что помогает отлаживать проблемы с входными данными.

Смотрите также

  • метод xml.NewDecoder,
    который создает новый декодер XML из io.Reader
  • функцию xml.Unmarshal,
    которая декодирует XML из среза байтов
  • метод xml.Encoder.Encode,
    который кодирует Go-значение в XML
  • функции xml.Marshal,
    которая преобразует Go-значение в XML