РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
1156 of 1593 menu

Интерфейс xml.Marshaler

Интерфейс xml.Marshaler из пакета encoding/xml позволяет типам данных управлять своим преобразованием в XML. Он содержит единственный метод MarshalXML, который принимает указатель на xml.Encoder и начальный элемент xml.StartElement, а возвращает ошибку. Реализация этого метода дает полный контроль над тем, как структура будет представлена в XML-формате.

Синтаксис

type Marshaler interface { MarshalXML(e *Encoder, start StartElement) error }

Базовый пример

Рассмотрим простую структуру, реализующую интерфейс xml.Marshaler. В этом примере мы вручную конструируем XML-элемент с атрибутами:

package main import ( "encoding/xml" "fmt" "os" ) type User struct { ID int Name string } func (u User) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name = xml.Name{Local: "user"} start.Attr = []xml.Attr{ {Name: xml.Name{Local: "id"}, Value: fmt.Sprintf("%d", u.ID)}, } err := e.EncodeToken(start) if err != nil { return err } err = e.EncodeElement(u.Name, xml.StartElement{Name: xml.Name{Local: "name"}}) if err != nil { return err } return e.EncodeToken(start.End()) } func main() { user := User{ID: 1, Name: "Alice"} output, err := xml.MarshalIndent(user, "", " ") if err != nil { fmt.Println("Error:", err) return } fmt.Println(string(output)) }

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

<user id="1"> <name>Alice</name> </user>

Пример со вложенными элементами

В этом примере мы создаем более сложную XML-структуру с несколькими уровнями вложенности, используя методы EncodeToken и EncodeElement для построения иерархии:

package main import ( "encoding/xml" "fmt" "os" ) type Address struct { City string Country string } type Person struct { FullName string Location Address } func (p Person) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name = xml.Name{Local: "person"} err := e.EncodeToken(start) if err != nil { return err } err = e.EncodeElement(p.FullName, xml.StartElement{Name: xml.Name{Local: "full_name"}}) if err != nil { return err } err = e.EncodeElement(p.Location, xml.StartElement{Name: xml.Name{Local: "address"}}) if err != nil { return err } return e.EncodeToken(start.End()) } func main() { person := Person{ FullName: "John Doe", Location: Address{City: "New York", Country: "USA"}, } output, err := xml.MarshalIndent(person, "", " ") if err != nil { fmt.Println("Error:", err) return } fmt.Println(string(output)) }

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

<person> <full_name>John Doe</full_name> <address> <City>New York</City> <Country>USA</Country> </address> </person>

Пример с изменением имен полей

Реализация интерфейса позволяет изменить имена полей в XML, используя пользовательские теги или динамическое формирование имен:

package main import ( "encoding/xml" "fmt" "os" ) type Product struct { ID int Title string Price float64 InStock bool } func (p Product) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name = xml.Name{Local: "product"} err := e.EncodeToken(start) if err != nil { return err } err = e.EncodeElement(p.ID, xml.StartElement{Name: xml.Name{Local: "product_id"}}) if err != nil { return err } err = e.EncodeElement(p.Title, xml.StartElement{Name: xml.Name{Local: "product_title"}}) if err != nil { return err } err = e.EncodeElement(p.Price, xml.StartElement{Name: xml.Name{Local: "product_price"}}) if err != nil { return err } stockStatus := "no" if p.InStock { stockStatus = "yes" } err = e.EncodeElement(stockStatus, xml.StartElement{Name: xml.Name{Local: "in_stock"}}) if err != nil { return err } return e.EncodeToken(start.End()) } func main() { product := Product{ID: 101, Title: "Laptop", Price: 999.99, InStock: true} output, err := xml.MarshalIndent(product, "", " ") if err != nil { fmt.Println("Error:", err) return } fmt.Println(string(output)) }

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

<product> <product_id>101</product_id> <product_title>Laptop</product_title> <product_price>999.99</product_price> <in_stock>yes</in_stock> </product>

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

  • интерфейс xml.Unmarshaler,
    который позволяет управлять парсингом XML
  • интерфейс json.Marshaler,
    который аналогичен для JSON
  • функцию xml.Marshal,
    которая преобразует данные в XML без отступов
  • функцию xml.MarshalIndent,
    которая создает XML с форматированием
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить