Метод xml.Decoder.Decode
Метод xml.Decoder.Decode считывает следующий XML-элемент из потока
и декодирует его в переданную структуру или другой тип данных.
В первый параметр метод принимает указатель на переменную,
в которую будет записан результат декодирования.
Метод возвращает ошибку error, которая будет равна io.EOF
при достижении конца данных или другой ошибке при разборе XML.
Синтаксис
err := decoder.Decode(&v)
где decoder - это указатель на xml.Decoder,
а v - переменная для хранения результата.
Пример
Давайте декодируем простой XML-документ в структуру:
package 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)
}
Результат выполнения кода:
{XMLName:{Space: Local:person} Name:John Age:30}
В этом примере мы создали структуру Person с тегами xml,
которые сопоставляют поля с элементами XML.
Метод Decode автоматически заполнил структуру данными из XML.
Пример
Рассмотрим декодирование XML с атрибутами:
package 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)
}
Результат выполнения кода:
{XMLName:{Space: Local:user} ID:42 Name:Alice Active:true}
Атрибуты XML автоматически сопоставляются с полями структуры,
если указать ,attr в теге.
Пример
Давайте обработаем XML с вложенными элементами:
package 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)
}
Результат выполнения кода:
Name: Bob
Age: 28
City: New York
Street: 5th Ave
Zip: 10001
Вложенные XML-элементы декодируются в соответствующие вложенные структуры, что делает код чистым и организованным.
Пример
Рассмотрим обработку ошибок при декодировании некорректного XML:
package 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)
}
Результат выполнения кода:
Error: 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