воскресенье, 28 июня 2020 г.

Пакет xml в Golang - интерфейс Unmarshaler

Unmarshaler - это интерфейс, реализуемый объектами, которые могут демаршалировать описание своего XML элемента.

type Unmarshaler interface {
    UnmarshalXML(d *Decoder, start StartElement) error
}

UnmarshalXML декодирует один элемент XML, начиная с данного start элемента. Если он возвращает ошибку, внешний вызов Unmarshal останавливается и возвращает эту ошибку. UnmarshalXML должен использовать ровно один элемент XML. Одна из распространенных стратегий внедрения состоит в том, чтобы демаршалировать в отдельное значение с макетом, соответствующим ожидаемому XML используя d.DecodeElement, а затем копировать данные из этого значения в приемник. Другая распространенная стратегия - использовать d.Token для обработки XML объекта по одному токену за раз. UnmarshalXML не может использовать d.RawToken.

С помощью реализации интерфейса Unmarshaler можно задавать пользовательские способы демаршалинга XML объектов.

Пример реализации интерфейса Unmarshaler

 package main

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

type Animal int

const (
    Unknown Animal = iota
    Gopher
    Zebra
)

func (a *Animal) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    var s string
    if err := d.DecodeElement(&s, &start); err != nil {
        return err
    }
    switch strings.ToLower(s) {
    default:
        *a = Unknown
    case "gopher":
        *a = Gopher
    case "zebra":
        *a = Zebra
    }

    return nil
}

func main() {
    blob := `
    
        gopher
        armadillo
        zebra
        unknown
        gopher
        bee
        gopher
        zebra
    `
    var zoo struct {
        Animals []Animal `xml:"animal"`
    }
    if err := xml.Unmarshal([]byte(blob), &zoo); err != nil {
        log.Fatal(err)
    }

    census := make(map[Animal]int)
    for _, animal := range zoo.Animals {
        census[animal] += 1
    }

    fmt.Printf("Перепись зоопарка:\n* Суслики:     %d\n* Зебры:       %d\n* Неизвестные: %d\n",
        census[Gopher], census[Zebra], census[Unknown])

}

Вывод:

Перепись зоопарка:
* Суслики:     3
* Зебры:       2
* Неизвестные: 3


Читайте также:


Комментариев нет:

Отправить комментарий