1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package xml_test
6
7import (
8	"encoding/xml"
9	"fmt"
10	"log"
11	"strings"
12)
13
14type Animal int
15
16const (
17	Unknown Animal = iota
18	Gopher
19	Zebra
20)
21
22func (a *Animal) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
23	var s string
24	if err := d.DecodeElement(&s, &start); err != nil {
25		return err
26	}
27	switch strings.ToLower(s) {
28	default:
29		*a = Unknown
30	case "gopher":
31		*a = Gopher
32	case "zebra":
33		*a = Zebra
34	}
35
36	return nil
37}
38
39func (a Animal) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
40	var s string
41	switch a {
42	default:
43		s = "unknown"
44	case Gopher:
45		s = "gopher"
46	case Zebra:
47		s = "zebra"
48	}
49	return e.EncodeElement(s, start)
50}
51
52func Example_customMarshalXML() {
53	blob := `
54	<animals>
55		<animal>gopher</animal>
56		<animal>armadillo</animal>
57		<animal>zebra</animal>
58		<animal>unknown</animal>
59		<animal>gopher</animal>
60		<animal>bee</animal>
61		<animal>gopher</animal>
62		<animal>zebra</animal>
63	</animals>`
64	var zoo struct {
65		Animals []Animal `xml:"animal"`
66	}
67	if err := xml.Unmarshal([]byte(blob), &zoo); err != nil {
68		log.Fatal(err)
69	}
70
71	census := make(map[Animal]int)
72	for _, animal := range zoo.Animals {
73		census[animal] += 1
74	}
75
76	fmt.Printf("Zoo Census:\n* Gophers: %d\n* Zebras:  %d\n* Unknown: %d\n",
77		census[Gopher], census[Zebra], census[Unknown])
78
79	// Output:
80	// Zoo Census:
81	// * Gophers: 3
82	// * Zebras:  2
83	// * Unknown: 3
84}
85