Тип xml.Encoder
Тип xml.Encoder предоставляет возможность кодировать данные в XML-формат.
Он принимает объект, реализующий интерфейс io.Writer, куда будет
выполняться запись закодированных данных. Основной метод типа -
Encode, который преобразует переданную Go-структуру или другой тип
в XML и записывает результат в указанный Writer.
Создание Encoder
Для создания нового кодировщика используется функция
xml.NewEncoder. Она принимает один параметр -
объект, реализующий интерфейс io.Writer, и возвращает
указатель на xml.Encoder.
Метод Encode
Основной метод типа xml.Encoder - это метод Encode.
Он принимает один параметр - данные для кодирования (обычно
структуру или слайс структур) и возвращает ошибку, если
в процессе кодирования что-то пошло не так.
Пример
Давайте создадим структуру и закодируем ее в XML:
package main
import (
"encoding/xml"
"fmt"
"strings"
)
type Person struct {
XMLName xml.Name `xml:"person"`
Name string `xml:"name"`
Age int `xml:"age"`
City string `xml:"city"`
}
func main() {
p := Person{
Name: "Alice",
Age: 30,
City: "New York",
}
var builder strings.Builder
encoder := xml.NewEncoder(&builder)
encoder.Indent("", " ")
err := encoder.Encode(p)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(builder.String())
}
Результат выполнения кода:
<person>
<name>Alice</name>
<age>30</age>
<city>New York</city>
</person>
В этом примере мы создали структуру Person с тегами XML,
указывающими имена элементов. Затем мы создали кодировщик,
использующий strings.Builder для накопления результата,
и вызвали метод Encode, который записал XML в билдер.
Пример
Давайте закодируем слайс структур в XML-документ:
package main
import (
"encoding/xml"
"fmt"
"strings"
)
type Person struct {
XMLName xml.Name `xml:"person"`
Name string `xml:"name"`
Age int `xml:"age"`
}
type People struct {
XMLName xml.Name `xml:"people"`
Persons []Person `xml:"person"`
}
func main() {
people := People{
Persons: []Person{
{Name: "Alice", Age: 30},
{Name: "Bob", Age: 25},
{Name: "Charlie", Age: 35},
},
}
var builder strings.Builder
encoder := xml.NewEncoder(&builder)
encoder.Indent("", " ")
err := encoder.Encode(people)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(builder.String())
}
Результат выполнения кода:
<people>
<person>
<name>Alice</name>
<age>30</age>
</person>
<person>
<name>Bob</name>
<age>25</age>
</person>
<person>
<name>Charlie</name>
<age>35</age>
</person>
</people>
Здесь мы создали структуру People, содержащую слайс
структур Person. При кодировании каждый элемент слайса
становится отдельным элементом person внутри корневого
элемента people.
Метод EncodeElement
Метод EncodeElement позволяет закодировать значение с
указанием конкретного XML-элемента в качестве корневого.
Он принимает два параметра: данные для кодирования и
структуру xml.StartElement, определяющую корневой элемент.
Пример
Давайте закодируем структуру с использованием EncodeElement:
package main
import (
"encoding/xml"
"fmt"
"strings"
)
type Person struct {
Name string `xml:"name"`
Age int `xml:"age"`
}
func main() {
p := Person{
Name: "David",
Age: 40,
}
var builder strings.Builder
encoder := xml.NewEncoder(&builder)
encoder.Indent("", " ")
start := xml.StartElement{
Name: xml.Name{Local: "employee"},
}
err := encoder.EncodeElement(p, start)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(builder.String())
}
Результат выполнения кода:
<employee>
<name>David</name>
<age>40</age>
</employee>
В этом примере мы использовали EncodeElement, чтобы
задать корневой элемент employee вместо person,
который был бы использован по умолчанию из тегов структуры.
Метод Indent
Метод Indent позволяет задать отступы для
форматирования выводимого XML. Он принимает два параметра:
префикс (обычно пустая строка) и строку отступа (например,
два пробела или табуляция). Это делает 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() {
p := Person{
Name: "Eve",
Age: 28,
}
var builder1 strings.Builder
encoder1 := xml.NewEncoder(&builder1)
encoder1.Encode(p)
fmt.Println("Without indent:")
fmt.Println(builder1.String())
var builder2 strings.Builder
encoder2 := xml.NewEncoder(&builder2)
encoder2.Indent("", " ")
encoder2.Encode(p)
fmt.Println("With indent:")
fmt.Println(builder2.String())
}
Результат выполнения кода:
Without indent:
<person><name>Eve</name><age>28</age></person>
With indent:
<person>
<name>Eve</name>
<age>28</age>
</person>
Как видно из примера, использование Indent делает
вывод структурированным и удобным для чтения, в то время
как без отступов весь XML записывается в одну строку.
Смотрите также
-
функцию
xml.Marshal,
которая кодирует данные в XML и возвращает срез байт -
тип
xml.Decoder,
который выполняет декодирование XML в Go-структуры -
функцию
xml.NewDecoder,
которая создает новый декодер XML -
тип
xml.Name,
представляющий имя XML-элемента