Home | History | Annotate | Download | only in xml
      1 // Copyright 2011 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 
      5 package xml
      6 
      7 import (
      8 	"bytes"
      9 	"errors"
     10 	"fmt"
     11 	"io"
     12 	"reflect"
     13 	"strconv"
     14 	"strings"
     15 	"sync"
     16 	"testing"
     17 	"time"
     18 )
     19 
     20 type DriveType int
     21 
     22 const (
     23 	HyperDrive DriveType = iota
     24 	ImprobabilityDrive
     25 )
     26 
     27 type Passenger struct {
     28 	Name   []string `xml:"name"`
     29 	Weight float32  `xml:"weight"`
     30 }
     31 
     32 type Ship struct {
     33 	XMLName struct{} `xml:"spaceship"`
     34 
     35 	Name      string       `xml:"name,attr"`
     36 	Pilot     string       `xml:"pilot,attr"`
     37 	Drive     DriveType    `xml:"drive"`
     38 	Age       uint         `xml:"age"`
     39 	Passenger []*Passenger `xml:"passenger"`
     40 	secret    string
     41 }
     42 
     43 type NamedType string
     44 
     45 type Port struct {
     46 	XMLName struct{} `xml:"port"`
     47 	Type    string   `xml:"type,attr,omitempty"`
     48 	Comment string   `xml:",comment"`
     49 	Number  string   `xml:",chardata"`
     50 }
     51 
     52 type Domain struct {
     53 	XMLName struct{} `xml:"domain"`
     54 	Country string   `xml:",attr,omitempty"`
     55 	Name    []byte   `xml:",chardata"`
     56 	Comment []byte   `xml:",comment"`
     57 }
     58 
     59 type Book struct {
     60 	XMLName struct{} `xml:"book"`
     61 	Title   string   `xml:",chardata"`
     62 }
     63 
     64 type Event struct {
     65 	XMLName struct{} `xml:"event"`
     66 	Year    int      `xml:",chardata"`
     67 }
     68 
     69 type Movie struct {
     70 	XMLName struct{} `xml:"movie"`
     71 	Length  uint     `xml:",chardata"`
     72 }
     73 
     74 type Pi struct {
     75 	XMLName       struct{} `xml:"pi"`
     76 	Approximation float32  `xml:",chardata"`
     77 }
     78 
     79 type Universe struct {
     80 	XMLName struct{} `xml:"universe"`
     81 	Visible float64  `xml:",chardata"`
     82 }
     83 
     84 type Particle struct {
     85 	XMLName struct{} `xml:"particle"`
     86 	HasMass bool     `xml:",chardata"`
     87 }
     88 
     89 type Departure struct {
     90 	XMLName struct{}  `xml:"departure"`
     91 	When    time.Time `xml:",chardata"`
     92 }
     93 
     94 type SecretAgent struct {
     95 	XMLName   struct{} `xml:"agent"`
     96 	Handle    string   `xml:"handle,attr"`
     97 	Identity  string
     98 	Obfuscate string `xml:",innerxml"`
     99 }
    100 
    101 type NestedItems struct {
    102 	XMLName struct{} `xml:"result"`
    103 	Items   []string `xml:">item"`
    104 	Item1   []string `xml:"Items>item1"`
    105 }
    106 
    107 type NestedOrder struct {
    108 	XMLName struct{} `xml:"result"`
    109 	Field1  string   `xml:"parent>c"`
    110 	Field2  string   `xml:"parent>b"`
    111 	Field3  string   `xml:"parent>a"`
    112 }
    113 
    114 type MixedNested struct {
    115 	XMLName struct{} `xml:"result"`
    116 	A       string   `xml:"parent1>a"`
    117 	B       string   `xml:"b"`
    118 	C       string   `xml:"parent1>parent2>c"`
    119 	D       string   `xml:"parent1>d"`
    120 }
    121 
    122 type NilTest struct {
    123 	A interface{} `xml:"parent1>parent2>a"`
    124 	B interface{} `xml:"parent1>b"`
    125 	C interface{} `xml:"parent1>parent2>c"`
    126 }
    127 
    128 type Service struct {
    129 	XMLName struct{} `xml:"service"`
    130 	Domain  *Domain  `xml:"host>domain"`
    131 	Port    *Port    `xml:"host>port"`
    132 	Extra1  interface{}
    133 	Extra2  interface{} `xml:"host>extra2"`
    134 }
    135 
    136 var nilStruct *Ship
    137 
    138 type EmbedA struct {
    139 	EmbedC
    140 	EmbedB EmbedB
    141 	FieldA string
    142 	embedD
    143 }
    144 
    145 type EmbedB struct {
    146 	FieldB string
    147 	*EmbedC
    148 }
    149 
    150 type EmbedC struct {
    151 	FieldA1 string `xml:"FieldA>A1"`
    152 	FieldA2 string `xml:"FieldA>A2"`
    153 	FieldB  string
    154 	FieldC  string
    155 }
    156 
    157 type embedD struct {
    158 	fieldD string
    159 	FieldE string // Promoted and visible when embedD is embedded.
    160 }
    161 
    162 type NameCasing struct {
    163 	XMLName struct{} `xml:"casing"`
    164 	Xy      string
    165 	XY      string
    166 	XyA     string `xml:"Xy,attr"`
    167 	XYA     string `xml:"XY,attr"`
    168 }
    169 
    170 type NamePrecedence struct {
    171 	XMLName     Name              `xml:"Parent"`
    172 	FromTag     XMLNameWithoutTag `xml:"InTag"`
    173 	FromNameVal XMLNameWithoutTag
    174 	FromNameTag XMLNameWithTag
    175 	InFieldName string
    176 }
    177 
    178 type XMLNameWithTag struct {
    179 	XMLName Name   `xml:"InXMLNameTag"`
    180 	Value   string `xml:",chardata"`
    181 }
    182 
    183 type XMLNameWithoutTag struct {
    184 	XMLName Name
    185 	Value   string `xml:",chardata"`
    186 }
    187 
    188 type NameInField struct {
    189 	Foo Name `xml:"ns foo"`
    190 }
    191 
    192 type AttrTest struct {
    193 	Int   int     `xml:",attr"`
    194 	Named int     `xml:"int,attr"`
    195 	Float float64 `xml:",attr"`
    196 	Uint8 uint8   `xml:",attr"`
    197 	Bool  bool    `xml:",attr"`
    198 	Str   string  `xml:",attr"`
    199 	Bytes []byte  `xml:",attr"`
    200 }
    201 
    202 type AttrsTest struct {
    203 	Attrs []Attr  `xml:",any,attr"`
    204 	Int   int     `xml:",attr"`
    205 	Named int     `xml:"int,attr"`
    206 	Float float64 `xml:",attr"`
    207 	Uint8 uint8   `xml:",attr"`
    208 	Bool  bool    `xml:",attr"`
    209 	Str   string  `xml:",attr"`
    210 	Bytes []byte  `xml:",attr"`
    211 }
    212 
    213 type OmitAttrTest struct {
    214 	Int   int     `xml:",attr,omitempty"`
    215 	Named int     `xml:"int,attr,omitempty"`
    216 	Float float64 `xml:",attr,omitempty"`
    217 	Uint8 uint8   `xml:",attr,omitempty"`
    218 	Bool  bool    `xml:",attr,omitempty"`
    219 	Str   string  `xml:",attr,omitempty"`
    220 	Bytes []byte  `xml:",attr,omitempty"`
    221 	PStr  *string `xml:",attr,omitempty"`
    222 }
    223 
    224 type OmitFieldTest struct {
    225 	Int   int           `xml:",omitempty"`
    226 	Named int           `xml:"int,omitempty"`
    227 	Float float64       `xml:",omitempty"`
    228 	Uint8 uint8         `xml:",omitempty"`
    229 	Bool  bool          `xml:",omitempty"`
    230 	Str   string        `xml:",omitempty"`
    231 	Bytes []byte        `xml:",omitempty"`
    232 	PStr  *string       `xml:",omitempty"`
    233 	Ptr   *PresenceTest `xml:",omitempty"`
    234 }
    235 
    236 type AnyTest struct {
    237 	XMLName  struct{}  `xml:"a"`
    238 	Nested   string    `xml:"nested>value"`
    239 	AnyField AnyHolder `xml:",any"`
    240 }
    241 
    242 type AnyOmitTest struct {
    243 	XMLName  struct{}   `xml:"a"`
    244 	Nested   string     `xml:"nested>value"`
    245 	AnyField *AnyHolder `xml:",any,omitempty"`
    246 }
    247 
    248 type AnySliceTest struct {
    249 	XMLName  struct{}    `xml:"a"`
    250 	Nested   string      `xml:"nested>value"`
    251 	AnyField []AnyHolder `xml:",any"`
    252 }
    253 
    254 type AnyHolder struct {
    255 	XMLName Name
    256 	XML     string `xml:",innerxml"`
    257 }
    258 
    259 type RecurseA struct {
    260 	A string
    261 	B *RecurseB
    262 }
    263 
    264 type RecurseB struct {
    265 	A *RecurseA
    266 	B string
    267 }
    268 
    269 type PresenceTest struct {
    270 	Exists *struct{}
    271 }
    272 
    273 type IgnoreTest struct {
    274 	PublicSecret string `xml:"-"`
    275 }
    276 
    277 type MyBytes []byte
    278 
    279 type Data struct {
    280 	Bytes  []byte
    281 	Attr   []byte `xml:",attr"`
    282 	Custom MyBytes
    283 }
    284 
    285 type Plain struct {
    286 	V interface{}
    287 }
    288 
    289 type MyInt int
    290 
    291 type EmbedInt struct {
    292 	MyInt
    293 }
    294 
    295 type Strings struct {
    296 	X []string `xml:"A>B,omitempty"`
    297 }
    298 
    299 type PointerFieldsTest struct {
    300 	XMLName  Name    `xml:"dummy"`
    301 	Name     *string `xml:"name,attr"`
    302 	Age      *uint   `xml:"age,attr"`
    303 	Empty    *string `xml:"empty,attr"`
    304 	Contents *string `xml:",chardata"`
    305 }
    306 
    307 type ChardataEmptyTest struct {
    308 	XMLName  Name    `xml:"test"`
    309 	Contents *string `xml:",chardata"`
    310 }
    311 
    312 type MyMarshalerTest struct {
    313 }
    314 
    315 var _ Marshaler = (*MyMarshalerTest)(nil)
    316 
    317 func (m *MyMarshalerTest) MarshalXML(e *Encoder, start StartElement) error {
    318 	e.EncodeToken(start)
    319 	e.EncodeToken(CharData([]byte("hello world")))
    320 	e.EncodeToken(EndElement{start.Name})
    321 	return nil
    322 }
    323 
    324 type MyMarshalerAttrTest struct {
    325 }
    326 
    327 var _ MarshalerAttr = (*MyMarshalerAttrTest)(nil)
    328 
    329 func (m *MyMarshalerAttrTest) MarshalXMLAttr(name Name) (Attr, error) {
    330 	return Attr{name, "hello world"}, nil
    331 }
    332 
    333 func (m *MyMarshalerAttrTest) UnmarshalXMLAttr(attr Attr) error {
    334 	return nil
    335 }
    336 
    337 type MarshalerStruct struct {
    338 	Foo MyMarshalerAttrTest `xml:",attr"`
    339 }
    340 
    341 type InnerStruct struct {
    342 	XMLName Name `xml:"testns outer"`
    343 }
    344 
    345 type OuterStruct struct {
    346 	InnerStruct
    347 	IntAttr int `xml:"int,attr"`
    348 }
    349 
    350 type OuterNamedStruct struct {
    351 	InnerStruct
    352 	XMLName Name `xml:"outerns test"`
    353 	IntAttr int  `xml:"int,attr"`
    354 }
    355 
    356 type OuterNamedOrderedStruct struct {
    357 	XMLName Name `xml:"outerns test"`
    358 	InnerStruct
    359 	IntAttr int `xml:"int,attr"`
    360 }
    361 
    362 type OuterOuterStruct struct {
    363 	OuterStruct
    364 }
    365 
    366 type NestedAndChardata struct {
    367 	AB       []string `xml:"A>B"`
    368 	Chardata string   `xml:",chardata"`
    369 }
    370 
    371 type NestedAndComment struct {
    372 	AB      []string `xml:"A>B"`
    373 	Comment string   `xml:",comment"`
    374 }
    375 
    376 type CDataTest struct {
    377 	Chardata string `xml:",cdata"`
    378 }
    379 
    380 type NestedAndCData struct {
    381 	AB    []string `xml:"A>B"`
    382 	CDATA string   `xml:",cdata"`
    383 }
    384 
    385 func ifaceptr(x interface{}) interface{} {
    386 	return &x
    387 }
    388 
    389 func stringptr(x string) *string {
    390 	return &x
    391 }
    392 
    393 type T1 struct{}
    394 type T2 struct{}
    395 type T3 struct{}
    396 
    397 type IndirComment struct {
    398 	T1      T1
    399 	Comment *string `xml:",comment"`
    400 	T2      T2
    401 }
    402 
    403 type DirectComment struct {
    404 	T1      T1
    405 	Comment string `xml:",comment"`
    406 	T2      T2
    407 }
    408 
    409 type IfaceComment struct {
    410 	T1      T1
    411 	Comment interface{} `xml:",comment"`
    412 	T2      T2
    413 }
    414 
    415 type IndirChardata struct {
    416 	T1       T1
    417 	Chardata *string `xml:",chardata"`
    418 	T2       T2
    419 }
    420 
    421 type DirectChardata struct {
    422 	T1       T1
    423 	Chardata string `xml:",chardata"`
    424 	T2       T2
    425 }
    426 
    427 type IfaceChardata struct {
    428 	T1       T1
    429 	Chardata interface{} `xml:",chardata"`
    430 	T2       T2
    431 }
    432 
    433 type IndirCDATA struct {
    434 	T1    T1
    435 	CDATA *string `xml:",cdata"`
    436 	T2    T2
    437 }
    438 
    439 type DirectCDATA struct {
    440 	T1    T1
    441 	CDATA string `xml:",cdata"`
    442 	T2    T2
    443 }
    444 
    445 type IfaceCDATA struct {
    446 	T1    T1
    447 	CDATA interface{} `xml:",cdata"`
    448 	T2    T2
    449 }
    450 
    451 type IndirInnerXML struct {
    452 	T1       T1
    453 	InnerXML *string `xml:",innerxml"`
    454 	T2       T2
    455 }
    456 
    457 type DirectInnerXML struct {
    458 	T1       T1
    459 	InnerXML string `xml:",innerxml"`
    460 	T2       T2
    461 }
    462 
    463 type IfaceInnerXML struct {
    464 	T1       T1
    465 	InnerXML interface{} `xml:",innerxml"`
    466 	T2       T2
    467 }
    468 
    469 type IndirElement struct {
    470 	T1      T1
    471 	Element *string
    472 	T2      T2
    473 }
    474 
    475 type DirectElement struct {
    476 	T1      T1
    477 	Element string
    478 	T2      T2
    479 }
    480 
    481 type IfaceElement struct {
    482 	T1      T1
    483 	Element interface{}
    484 	T2      T2
    485 }
    486 
    487 type IndirOmitEmpty struct {
    488 	T1        T1
    489 	OmitEmpty *string `xml:",omitempty"`
    490 	T2        T2
    491 }
    492 
    493 type DirectOmitEmpty struct {
    494 	T1        T1
    495 	OmitEmpty string `xml:",omitempty"`
    496 	T2        T2
    497 }
    498 
    499 type IfaceOmitEmpty struct {
    500 	T1        T1
    501 	OmitEmpty interface{} `xml:",omitempty"`
    502 	T2        T2
    503 }
    504 
    505 type IndirAny struct {
    506 	T1  T1
    507 	Any *string `xml:",any"`
    508 	T2  T2
    509 }
    510 
    511 type DirectAny struct {
    512 	T1  T1
    513 	Any string `xml:",any"`
    514 	T2  T2
    515 }
    516 
    517 type IfaceAny struct {
    518 	T1  T1
    519 	Any interface{} `xml:",any"`
    520 	T2  T2
    521 }
    522 
    523 var (
    524 	nameAttr     = "Sarah"
    525 	ageAttr      = uint(12)
    526 	contentsAttr = "lorem ipsum"
    527 	empty        = ""
    528 )
    529 
    530 // Unless explicitly stated as such (or *Plain), all of the
    531 // tests below are two-way tests. When introducing new tests,
    532 // please try to make them two-way as well to ensure that
    533 // marshaling and unmarshaling are as symmetrical as feasible.
    534 var marshalTests = []struct {
    535 	Value          interface{}
    536 	ExpectXML      string
    537 	MarshalOnly    bool
    538 	MarshalError   string
    539 	UnmarshalOnly  bool
    540 	UnmarshalError string
    541 }{
    542 	// Test nil marshals to nothing
    543 	{Value: nil, ExpectXML: ``, MarshalOnly: true},
    544 	{Value: nilStruct, ExpectXML: ``, MarshalOnly: true},
    545 
    546 	// Test value types
    547 	{Value: &Plain{true}, ExpectXML: `<Plain><V>true</V></Plain>`},
    548 	{Value: &Plain{false}, ExpectXML: `<Plain><V>false</V></Plain>`},
    549 	{Value: &Plain{int(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},
    550 	{Value: &Plain{int8(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},
    551 	{Value: &Plain{int16(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},
    552 	{Value: &Plain{int32(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},
    553 	{Value: &Plain{uint(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},
    554 	{Value: &Plain{uint8(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},
    555 	{Value: &Plain{uint16(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},
    556 	{Value: &Plain{uint32(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},
    557 	{Value: &Plain{float32(1.25)}, ExpectXML: `<Plain><V>1.25</V></Plain>`},
    558 	{Value: &Plain{float64(1.25)}, ExpectXML: `<Plain><V>1.25</V></Plain>`},
    559 	{Value: &Plain{uintptr(0xFFDD)}, ExpectXML: `<Plain><V>65501</V></Plain>`},
    560 	{Value: &Plain{"gopher"}, ExpectXML: `<Plain><V>gopher</V></Plain>`},
    561 	{Value: &Plain{[]byte("gopher")}, ExpectXML: `<Plain><V>gopher</V></Plain>`},
    562 	{Value: &Plain{"</>"}, ExpectXML: `<Plain><V>&lt;/&gt;</V></Plain>`},
    563 	{Value: &Plain{[]byte("</>")}, ExpectXML: `<Plain><V>&lt;/&gt;</V></Plain>`},
    564 	{Value: &Plain{[3]byte{'<', '/', '>'}}, ExpectXML: `<Plain><V>&lt;/&gt;</V></Plain>`},
    565 	{Value: &Plain{NamedType("potato")}, ExpectXML: `<Plain><V>potato</V></Plain>`},
    566 	{Value: &Plain{[]int{1, 2, 3}}, ExpectXML: `<Plain><V>1</V><V>2</V><V>3</V></Plain>`},
    567 	{Value: &Plain{[3]int{1, 2, 3}}, ExpectXML: `<Plain><V>1</V><V>2</V><V>3</V></Plain>`},
    568 	{Value: ifaceptr(true), MarshalOnly: true, ExpectXML: `<bool>true</bool>`},
    569 
    570 	// Test time.
    571 	{
    572 		Value:     &Plain{time.Unix(1e9, 123456789).UTC()},
    573 		ExpectXML: `<Plain><V>2001-09-09T01:46:40.123456789Z</V></Plain>`,
    574 	},
    575 
    576 	// A pointer to struct{} may be used to test for an element's presence.
    577 	{
    578 		Value:     &PresenceTest{new(struct{})},
    579 		ExpectXML: `<PresenceTest><Exists></Exists></PresenceTest>`,
    580 	},
    581 	{
    582 		Value:     &PresenceTest{},
    583 		ExpectXML: `<PresenceTest></PresenceTest>`,
    584 	},
    585 
    586 	// A []byte field is only nil if the element was not found.
    587 	{
    588 		Value:         &Data{},
    589 		ExpectXML:     `<Data></Data>`,
    590 		UnmarshalOnly: true,
    591 	},
    592 	{
    593 		Value:         &Data{Bytes: []byte{}, Custom: MyBytes{}, Attr: []byte{}},
    594 		ExpectXML:     `<Data Attr=""><Bytes></Bytes><Custom></Custom></Data>`,
    595 		UnmarshalOnly: true,
    596 	},
    597 
    598 	// Check that []byte works, including named []byte types.
    599 	{
    600 		Value:     &Data{Bytes: []byte("ab"), Custom: MyBytes("cd"), Attr: []byte{'v'}},
    601 		ExpectXML: `<Data Attr="v"><Bytes>ab</Bytes><Custom>cd</Custom></Data>`,
    602 	},
    603 
    604 	// Test innerxml
    605 	{
    606 		Value: &SecretAgent{
    607 			Handle:    "007",
    608 			Identity:  "James Bond",
    609 			Obfuscate: "<redacted/>",
    610 		},
    611 		ExpectXML:   `<agent handle="007"><Identity>James Bond</Identity><redacted/></agent>`,
    612 		MarshalOnly: true,
    613 	},
    614 	{
    615 		Value: &SecretAgent{
    616 			Handle:    "007",
    617 			Identity:  "James Bond",
    618 			Obfuscate: "<Identity>James Bond</Identity><redacted/>",
    619 		},
    620 		ExpectXML:     `<agent handle="007"><Identity>James Bond</Identity><redacted/></agent>`,
    621 		UnmarshalOnly: true,
    622 	},
    623 
    624 	// Test structs
    625 	{Value: &Port{Type: "ssl", Number: "443"}, ExpectXML: `<port type="ssl">443</port>`},
    626 	{Value: &Port{Number: "443"}, ExpectXML: `<port>443</port>`},
    627 	{Value: &Port{Type: "<unix>"}, ExpectXML: `<port type="&lt;unix&gt;"></port>`},
    628 	{Value: &Port{Number: "443", Comment: "https"}, ExpectXML: `<port><!--https-->443</port>`},
    629 	{Value: &Port{Number: "443", Comment: "add space-"}, ExpectXML: `<port><!--add space- -->443</port>`, MarshalOnly: true},
    630 	{Value: &Domain{Name: []byte("google.com&friends")}, ExpectXML: `<domain>google.com&amp;friends</domain>`},
    631 	{Value: &Domain{Name: []byte("google.com"), Comment: []byte(" &friends ")}, ExpectXML: `<domain>google.com<!-- &friends --></domain>`},
    632 	{Value: &Book{Title: "Pride & Prejudice"}, ExpectXML: `<book>Pride &amp; Prejudice</book>`},
    633 	{Value: &Event{Year: -3114}, ExpectXML: `<event>-3114</event>`},
    634 	{Value: &Movie{Length: 13440}, ExpectXML: `<movie>13440</movie>`},
    635 	{Value: &Pi{Approximation: 3.14159265}, ExpectXML: `<pi>3.1415927</pi>`},
    636 	{Value: &Universe{Visible: 9.3e13}, ExpectXML: `<universe>9.3e+13</universe>`},
    637 	{Value: &Particle{HasMass: true}, ExpectXML: `<particle>true</particle>`},
    638 	{Value: &Departure{When: ParseTime("2013-01-09T00:15:00-09:00")}, ExpectXML: `<departure>2013-01-09T00:15:00-09:00</departure>`},
    639 	{Value: atomValue, ExpectXML: atomXML},
    640 	{
    641 		Value: &Ship{
    642 			Name:  "Heart of Gold",
    643 			Pilot: "Computer",
    644 			Age:   1,
    645 			Drive: ImprobabilityDrive,
    646 			Passenger: []*Passenger{
    647 				{
    648 					Name:   []string{"Zaphod", "Beeblebrox"},
    649 					Weight: 7.25,
    650 				},
    651 				{
    652 					Name:   []string{"Trisha", "McMillen"},
    653 					Weight: 5.5,
    654 				},
    655 				{
    656 					Name:   []string{"Ford", "Prefect"},
    657 					Weight: 7,
    658 				},
    659 				{
    660 					Name:   []string{"Arthur", "Dent"},
    661 					Weight: 6.75,
    662 				},
    663 			},
    664 		},
    665 		ExpectXML: `<spaceship name="Heart of Gold" pilot="Computer">` +
    666 			`<drive>` + strconv.Itoa(int(ImprobabilityDrive)) + `</drive>` +
    667 			`<age>1</age>` +
    668 			`<passenger>` +
    669 			`<name>Zaphod</name>` +
    670 			`<name>Beeblebrox</name>` +
    671 			`<weight>7.25</weight>` +
    672 			`</passenger>` +
    673 			`<passenger>` +
    674 			`<name>Trisha</name>` +
    675 			`<name>McMillen</name>` +
    676 			`<weight>5.5</weight>` +
    677 			`</passenger>` +
    678 			`<passenger>` +
    679 			`<name>Ford</name>` +
    680 			`<name>Prefect</name>` +
    681 			`<weight>7</weight>` +
    682 			`</passenger>` +
    683 			`<passenger>` +
    684 			`<name>Arthur</name>` +
    685 			`<name>Dent</name>` +
    686 			`<weight>6.75</weight>` +
    687 			`</passenger>` +
    688 			`</spaceship>`,
    689 	},
    690 
    691 	// Test a>b
    692 	{
    693 		Value: &NestedItems{Items: nil, Item1: nil},
    694 		ExpectXML: `<result>` +
    695 			`<Items>` +
    696 			`</Items>` +
    697 			`</result>`,
    698 	},
    699 	{
    700 		Value: &NestedItems{Items: []string{}, Item1: []string{}},
    701 		ExpectXML: `<result>` +
    702 			`<Items>` +
    703 			`</Items>` +
    704 			`</result>`,
    705 		MarshalOnly: true,
    706 	},
    707 	{
    708 		Value: &NestedItems{Items: nil, Item1: []string{"A"}},
    709 		ExpectXML: `<result>` +
    710 			`<Items>` +
    711 			`<item1>A</item1>` +
    712 			`</Items>` +
    713 			`</result>`,
    714 	},
    715 	{
    716 		Value: &NestedItems{Items: []string{"A", "B"}, Item1: nil},
    717 		ExpectXML: `<result>` +
    718 			`<Items>` +
    719 			`<item>A</item>` +
    720 			`<item>B</item>` +
    721 			`</Items>` +
    722 			`</result>`,
    723 	},
    724 	{
    725 		Value: &NestedItems{Items: []string{"A", "B"}, Item1: []string{"C"}},
    726 		ExpectXML: `<result>` +
    727 			`<Items>` +
    728 			`<item>A</item>` +
    729 			`<item>B</item>` +
    730 			`<item1>C</item1>` +
    731 			`</Items>` +
    732 			`</result>`,
    733 	},
    734 	{
    735 		Value: &NestedOrder{Field1: "C", Field2: "B", Field3: "A"},
    736 		ExpectXML: `<result>` +
    737 			`<parent>` +
    738 			`<c>C</c>` +
    739 			`<b>B</b>` +
    740 			`<a>A</a>` +
    741 			`</parent>` +
    742 			`</result>`,
    743 	},
    744 	{
    745 		Value: &NilTest{A: "A", B: nil, C: "C"},
    746 		ExpectXML: `<NilTest>` +
    747 			`<parent1>` +
    748 			`<parent2><a>A</a></parent2>` +
    749 			`<parent2><c>C</c></parent2>` +
    750 			`</parent1>` +
    751 			`</NilTest>`,
    752 		MarshalOnly: true, // Uses interface{}
    753 	},
    754 	{
    755 		Value: &MixedNested{A: "A", B: "B", C: "C", D: "D"},
    756 		ExpectXML: `<result>` +
    757 			`<parent1><a>A</a></parent1>` +
    758 			`<b>B</b>` +
    759 			`<parent1>` +
    760 			`<parent2><c>C</c></parent2>` +
    761 			`<d>D</d>` +
    762 			`</parent1>` +
    763 			`</result>`,
    764 	},
    765 	{
    766 		Value:     &Service{Port: &Port{Number: "80"}},
    767 		ExpectXML: `<service><host><port>80</port></host></service>`,
    768 	},
    769 	{
    770 		Value:     &Service{},
    771 		ExpectXML: `<service></service>`,
    772 	},
    773 	{
    774 		Value: &Service{Port: &Port{Number: "80"}, Extra1: "A", Extra2: "B"},
    775 		ExpectXML: `<service>` +
    776 			`<host><port>80</port></host>` +
    777 			`<Extra1>A</Extra1>` +
    778 			`<host><extra2>B</extra2></host>` +
    779 			`</service>`,
    780 		MarshalOnly: true,
    781 	},
    782 	{
    783 		Value: &Service{Port: &Port{Number: "80"}, Extra2: "example"},
    784 		ExpectXML: `<service>` +
    785 			`<host><port>80</port></host>` +
    786 			`<host><extra2>example</extra2></host>` +
    787 			`</service>`,
    788 		MarshalOnly: true,
    789 	},
    790 	{
    791 		Value: &struct {
    792 			XMLName struct{} `xml:"space top"`
    793 			A       string   `xml:"x>a"`
    794 			B       string   `xml:"x>b"`
    795 			C       string   `xml:"space x>c"`
    796 			C1      string   `xml:"space1 x>c"`
    797 			D1      string   `xml:"space1 x>d"`
    798 		}{
    799 			A:  "a",
    800 			B:  "b",
    801 			C:  "c",
    802 			C1: "c1",
    803 			D1: "d1",
    804 		},
    805 		ExpectXML: `<top xmlns="space">` +
    806 			`<x><a>a</a><b>b</b><c xmlns="space">c</c>` +
    807 			`<c xmlns="space1">c1</c>` +
    808 			`<d xmlns="space1">d1</d>` +
    809 			`</x>` +
    810 			`</top>`,
    811 	},
    812 	{
    813 		Value: &struct {
    814 			XMLName Name
    815 			A       string `xml:"x>a"`
    816 			B       string `xml:"x>b"`
    817 			C       string `xml:"space x>c"`
    818 			C1      string `xml:"space1 x>c"`
    819 			D1      string `xml:"space1 x>d"`
    820 		}{
    821 			XMLName: Name{
    822 				Space: "space0",
    823 				Local: "top",
    824 			},
    825 			A:  "a",
    826 			B:  "b",
    827 			C:  "c",
    828 			C1: "c1",
    829 			D1: "d1",
    830 		},
    831 		ExpectXML: `<top xmlns="space0">` +
    832 			`<x><a>a</a><b>b</b>` +
    833 			`<c xmlns="space">c</c>` +
    834 			`<c xmlns="space1">c1</c>` +
    835 			`<d xmlns="space1">d1</d>` +
    836 			`</x>` +
    837 			`</top>`,
    838 	},
    839 	{
    840 		Value: &struct {
    841 			XMLName struct{} `xml:"top"`
    842 			B       string   `xml:"space x>b"`
    843 			B1      string   `xml:"space1 x>b"`
    844 		}{
    845 			B:  "b",
    846 			B1: "b1",
    847 		},
    848 		ExpectXML: `<top>` +
    849 			`<x><b xmlns="space">b</b>` +
    850 			`<b xmlns="space1">b1</b></x>` +
    851 			`</top>`,
    852 	},
    853 
    854 	// Test struct embedding
    855 	{
    856 		Value: &EmbedA{
    857 			EmbedC: EmbedC{
    858 				FieldA1: "", // Shadowed by A.A
    859 				FieldA2: "", // Shadowed by A.A
    860 				FieldB:  "A.C.B",
    861 				FieldC:  "A.C.C",
    862 			},
    863 			EmbedB: EmbedB{
    864 				FieldB: "A.B.B",
    865 				EmbedC: &EmbedC{
    866 					FieldA1: "A.B.C.A1",
    867 					FieldA2: "A.B.C.A2",
    868 					FieldB:  "", // Shadowed by A.B.B
    869 					FieldC:  "A.B.C.C",
    870 				},
    871 			},
    872 			FieldA: "A.A",
    873 			embedD: embedD{
    874 				FieldE: "A.D.E",
    875 			},
    876 		},
    877 		ExpectXML: `<EmbedA>` +
    878 			`<FieldB>A.C.B</FieldB>` +
    879 			`<FieldC>A.C.C</FieldC>` +
    880 			`<EmbedB>` +
    881 			`<FieldB>A.B.B</FieldB>` +
    882 			`<FieldA>` +
    883 			`<A1>A.B.C.A1</A1>` +
    884 			`<A2>A.B.C.A2</A2>` +
    885 			`</FieldA>` +
    886 			`<FieldC>A.B.C.C</FieldC>` +
    887 			`</EmbedB>` +
    888 			`<FieldA>A.A</FieldA>` +
    889 			`<FieldE>A.D.E</FieldE>` +
    890 			`</EmbedA>`,
    891 	},
    892 
    893 	// Test that name casing matters
    894 	{
    895 		Value:     &NameCasing{Xy: "mixed", XY: "upper", XyA: "mixedA", XYA: "upperA"},
    896 		ExpectXML: `<casing Xy="mixedA" XY="upperA"><Xy>mixed</Xy><XY>upper</XY></casing>`,
    897 	},
    898 
    899 	// Test the order in which the XML element name is chosen
    900 	{
    901 		Value: &NamePrecedence{
    902 			FromTag:     XMLNameWithoutTag{Value: "A"},
    903 			FromNameVal: XMLNameWithoutTag{XMLName: Name{Local: "InXMLName"}, Value: "B"},
    904 			FromNameTag: XMLNameWithTag{Value: "C"},
    905 			InFieldName: "D",
    906 		},
    907 		ExpectXML: `<Parent>` +
    908 			`<InTag>A</InTag>` +
    909 			`<InXMLName>B</InXMLName>` +
    910 			`<InXMLNameTag>C</InXMLNameTag>` +
    911 			`<InFieldName>D</InFieldName>` +
    912 			`</Parent>`,
    913 		MarshalOnly: true,
    914 	},
    915 	{
    916 		Value: &NamePrecedence{
    917 			XMLName:     Name{Local: "Parent"},
    918 			FromTag:     XMLNameWithoutTag{XMLName: Name{Local: "InTag"}, Value: "A"},
    919 			FromNameVal: XMLNameWithoutTag{XMLName: Name{Local: "FromNameVal"}, Value: "B"},
    920 			FromNameTag: XMLNameWithTag{XMLName: Name{Local: "InXMLNameTag"}, Value: "C"},
    921 			InFieldName: "D",
    922 		},
    923 		ExpectXML: `<Parent>` +
    924 			`<InTag>A</InTag>` +
    925 			`<FromNameVal>B</FromNameVal>` +
    926 			`<InXMLNameTag>C</InXMLNameTag>` +
    927 			`<InFieldName>D</InFieldName>` +
    928 			`</Parent>`,
    929 		UnmarshalOnly: true,
    930 	},
    931 
    932 	// xml.Name works in a plain field as well.
    933 	{
    934 		Value:     &NameInField{Name{Space: "ns", Local: "foo"}},
    935 		ExpectXML: `<NameInField><foo xmlns="ns"></foo></NameInField>`,
    936 	},
    937 	{
    938 		Value:         &NameInField{Name{Space: "ns", Local: "foo"}},
    939 		ExpectXML:     `<NameInField><foo xmlns="ns"><ignore></ignore></foo></NameInField>`,
    940 		UnmarshalOnly: true,
    941 	},
    942 
    943 	// Marshaling zero xml.Name uses the tag or field name.
    944 	{
    945 		Value:       &NameInField{},
    946 		ExpectXML:   `<NameInField><foo xmlns="ns"></foo></NameInField>`,
    947 		MarshalOnly: true,
    948 	},
    949 
    950 	// Test attributes
    951 	{
    952 		Value: &AttrTest{
    953 			Int:   8,
    954 			Named: 9,
    955 			Float: 23.5,
    956 			Uint8: 255,
    957 			Bool:  true,
    958 			Str:   "str",
    959 			Bytes: []byte("byt"),
    960 		},
    961 		ExpectXML: `<AttrTest Int="8" int="9" Float="23.5" Uint8="255"` +
    962 			` Bool="true" Str="str" Bytes="byt"></AttrTest>`,
    963 	},
    964 	{
    965 		Value: &AttrTest{Bytes: []byte{}},
    966 		ExpectXML: `<AttrTest Int="0" int="0" Float="0" Uint8="0"` +
    967 			` Bool="false" Str="" Bytes=""></AttrTest>`,
    968 	},
    969 	{
    970 		Value: &AttrsTest{
    971 			Attrs: []Attr{
    972 				{Name: Name{Local: "Answer"}, Value: "42"},
    973 				{Name: Name{Local: "Int"}, Value: "8"},
    974 				{Name: Name{Local: "int"}, Value: "9"},
    975 				{Name: Name{Local: "Float"}, Value: "23.5"},
    976 				{Name: Name{Local: "Uint8"}, Value: "255"},
    977 				{Name: Name{Local: "Bool"}, Value: "true"},
    978 				{Name: Name{Local: "Str"}, Value: "str"},
    979 				{Name: Name{Local: "Bytes"}, Value: "byt"},
    980 			},
    981 		},
    982 		ExpectXML:   `<AttrsTest Answer="42" Int="8" int="9" Float="23.5" Uint8="255" Bool="true" Str="str" Bytes="byt" Int="0" int="0" Float="0" Uint8="0" Bool="false" Str="" Bytes=""></AttrsTest>`,
    983 		MarshalOnly: true,
    984 	},
    985 	{
    986 		Value: &AttrsTest{
    987 			Attrs: []Attr{
    988 				{Name: Name{Local: "Answer"}, Value: "42"},
    989 			},
    990 			Int:   8,
    991 			Named: 9,
    992 			Float: 23.5,
    993 			Uint8: 255,
    994 			Bool:  true,
    995 			Str:   "str",
    996 			Bytes: []byte("byt"),
    997 		},
    998 		ExpectXML: `<AttrsTest Answer="42" Int="8" int="9" Float="23.5" Uint8="255" Bool="true" Str="str" Bytes="byt"></AttrsTest>`,
    999 	},
   1000 	{
   1001 		Value: &AttrsTest{
   1002 			Attrs: []Attr{
   1003 				{Name: Name{Local: "Int"}, Value: "0"},
   1004 				{Name: Name{Local: "int"}, Value: "0"},
   1005 				{Name: Name{Local: "Float"}, Value: "0"},
   1006 				{Name: Name{Local: "Uint8"}, Value: "0"},
   1007 				{Name: Name{Local: "Bool"}, Value: "false"},
   1008 				{Name: Name{Local: "Str"}},
   1009 				{Name: Name{Local: "Bytes"}},
   1010 			},
   1011 			Bytes: []byte{},
   1012 		},
   1013 		ExpectXML:   `<AttrsTest Int="0" int="0" Float="0" Uint8="0" Bool="false" Str="" Bytes="" Int="0" int="0" Float="0" Uint8="0" Bool="false" Str="" Bytes=""></AttrsTest>`,
   1014 		MarshalOnly: true,
   1015 	},
   1016 	{
   1017 		Value: &OmitAttrTest{
   1018 			Int:   8,
   1019 			Named: 9,
   1020 			Float: 23.5,
   1021 			Uint8: 255,
   1022 			Bool:  true,
   1023 			Str:   "str",
   1024 			Bytes: []byte("byt"),
   1025 			PStr:  &empty,
   1026 		},
   1027 		ExpectXML: `<OmitAttrTest Int="8" int="9" Float="23.5" Uint8="255"` +
   1028 			` Bool="true" Str="str" Bytes="byt" PStr=""></OmitAttrTest>`,
   1029 	},
   1030 	{
   1031 		Value:     &OmitAttrTest{},
   1032 		ExpectXML: `<OmitAttrTest></OmitAttrTest>`,
   1033 	},
   1034 
   1035 	// pointer fields
   1036 	{
   1037 		Value:       &PointerFieldsTest{Name: &nameAttr, Age: &ageAttr, Contents: &contentsAttr},
   1038 		ExpectXML:   `<dummy name="Sarah" age="12">lorem ipsum</dummy>`,
   1039 		MarshalOnly: true,
   1040 	},
   1041 
   1042 	// empty chardata pointer field
   1043 	{
   1044 		Value:       &ChardataEmptyTest{},
   1045 		ExpectXML:   `<test></test>`,
   1046 		MarshalOnly: true,
   1047 	},
   1048 
   1049 	// omitempty on fields
   1050 	{
   1051 		Value: &OmitFieldTest{
   1052 			Int:   8,
   1053 			Named: 9,
   1054 			Float: 23.5,
   1055 			Uint8: 255,
   1056 			Bool:  true,
   1057 			Str:   "str",
   1058 			Bytes: []byte("byt"),
   1059 			PStr:  &empty,
   1060 			Ptr:   &PresenceTest{},
   1061 		},
   1062 		ExpectXML: `<OmitFieldTest>` +
   1063 			`<Int>8</Int>` +
   1064 			`<int>9</int>` +
   1065 			`<Float>23.5</Float>` +
   1066 			`<Uint8>255</Uint8>` +
   1067 			`<Bool>true</Bool>` +
   1068 			`<Str>str</Str>` +
   1069 			`<Bytes>byt</Bytes>` +
   1070 			`<PStr></PStr>` +
   1071 			`<Ptr></Ptr>` +
   1072 			`</OmitFieldTest>`,
   1073 	},
   1074 	{
   1075 		Value:     &OmitFieldTest{},
   1076 		ExpectXML: `<OmitFieldTest></OmitFieldTest>`,
   1077 	},
   1078 
   1079 	// Test ",any"
   1080 	{
   1081 		ExpectXML: `<a><nested><value>known</value></nested><other><sub>unknown</sub></other></a>`,
   1082 		Value: &AnyTest{
   1083 			Nested: "known",
   1084 			AnyField: AnyHolder{
   1085 				XMLName: Name{Local: "other"},
   1086 				XML:     "<sub>unknown</sub>",
   1087 			},
   1088 		},
   1089 	},
   1090 	{
   1091 		Value: &AnyTest{Nested: "known",
   1092 			AnyField: AnyHolder{
   1093 				XML:     "<unknown/>",
   1094 				XMLName: Name{Local: "AnyField"},
   1095 			},
   1096 		},
   1097 		ExpectXML: `<a><nested><value>known</value></nested><AnyField><unknown/></AnyField></a>`,
   1098 	},
   1099 	{
   1100 		ExpectXML: `<a><nested><value>b</value></nested></a>`,
   1101 		Value: &AnyOmitTest{
   1102 			Nested: "b",
   1103 		},
   1104 	},
   1105 	{
   1106 		ExpectXML: `<a><nested><value>b</value></nested><c><d>e</d></c><g xmlns="f"><h>i</h></g></a>`,
   1107 		Value: &AnySliceTest{
   1108 			Nested: "b",
   1109 			AnyField: []AnyHolder{
   1110 				{
   1111 					XMLName: Name{Local: "c"},
   1112 					XML:     "<d>e</d>",
   1113 				},
   1114 				{
   1115 					XMLName: Name{Space: "f", Local: "g"},
   1116 					XML:     "<h>i</h>",
   1117 				},
   1118 			},
   1119 		},
   1120 	},
   1121 	{
   1122 		ExpectXML: `<a><nested><value>b</value></nested></a>`,
   1123 		Value: &AnySliceTest{
   1124 			Nested: "b",
   1125 		},
   1126 	},
   1127 
   1128 	// Test recursive types.
   1129 	{
   1130 		Value: &RecurseA{
   1131 			A: "a1",
   1132 			B: &RecurseB{
   1133 				A: &RecurseA{"a2", nil},
   1134 				B: "b1",
   1135 			},
   1136 		},
   1137 		ExpectXML: `<RecurseA><A>a1</A><B><A><A>a2</A></A><B>b1</B></B></RecurseA>`,
   1138 	},
   1139 
   1140 	// Test ignoring fields via "-" tag
   1141 	{
   1142 		ExpectXML: `<IgnoreTest></IgnoreTest>`,
   1143 		Value:     &IgnoreTest{},
   1144 	},
   1145 	{
   1146 		ExpectXML:   `<IgnoreTest></IgnoreTest>`,
   1147 		Value:       &IgnoreTest{PublicSecret: "can't tell"},
   1148 		MarshalOnly: true,
   1149 	},
   1150 	{
   1151 		ExpectXML:     `<IgnoreTest><PublicSecret>ignore me</PublicSecret></IgnoreTest>`,
   1152 		Value:         &IgnoreTest{},
   1153 		UnmarshalOnly: true,
   1154 	},
   1155 
   1156 	// Test escaping.
   1157 	{
   1158 		ExpectXML: `<a><nested><value>dquote: &#34;; squote: &#39;; ampersand: &amp;; less: &lt;; greater: &gt;;</value></nested><empty></empty></a>`,
   1159 		Value: &AnyTest{
   1160 			Nested:   `dquote: "; squote: '; ampersand: &; less: <; greater: >;`,
   1161 			AnyField: AnyHolder{XMLName: Name{Local: "empty"}},
   1162 		},
   1163 	},
   1164 	{
   1165 		ExpectXML: `<a><nested><value>newline: &#xA;; cr: &#xD;; tab: &#x9;;</value></nested><AnyField></AnyField></a>`,
   1166 		Value: &AnyTest{
   1167 			Nested:   "newline: \n; cr: \r; tab: \t;",
   1168 			AnyField: AnyHolder{XMLName: Name{Local: "AnyField"}},
   1169 		},
   1170 	},
   1171 	{
   1172 		ExpectXML: "<a><nested><value>1\r2\r\n3\n\r4\n5</value></nested></a>",
   1173 		Value: &AnyTest{
   1174 			Nested: "1\n2\n3\n\n4\n5",
   1175 		},
   1176 		UnmarshalOnly: true,
   1177 	},
   1178 	{
   1179 		ExpectXML: `<EmbedInt><MyInt>42</MyInt></EmbedInt>`,
   1180 		Value: &EmbedInt{
   1181 			MyInt: 42,
   1182 		},
   1183 	},
   1184 	// Test outputting CDATA-wrapped text.
   1185 	{
   1186 		ExpectXML: `<CDataTest></CDataTest>`,
   1187 		Value:     &CDataTest{},
   1188 	},
   1189 	{
   1190 		ExpectXML: `<CDataTest><![CDATA[http://example.com/tests/1?foo=1&bar=baz]]></CDataTest>`,
   1191 		Value: &CDataTest{
   1192 			Chardata: "http://example.com/tests/1?foo=1&bar=baz",
   1193 		},
   1194 	},
   1195 	{
   1196 		ExpectXML: `<CDataTest><![CDATA[Literal <![CDATA[Nested]]]]><![CDATA[>!]]></CDataTest>`,
   1197 		Value: &CDataTest{
   1198 			Chardata: "Literal <![CDATA[Nested]]>!",
   1199 		},
   1200 	},
   1201 	{
   1202 		ExpectXML: `<CDataTest><![CDATA[<![CDATA[Nested]]]]><![CDATA[> Literal!]]></CDataTest>`,
   1203 		Value: &CDataTest{
   1204 			Chardata: "<![CDATA[Nested]]> Literal!",
   1205 		},
   1206 	},
   1207 	{
   1208 		ExpectXML: `<CDataTest><![CDATA[<![CDATA[Nested]]]]><![CDATA[> Literal! <![CDATA[Nested]]]]><![CDATA[> Literal!]]></CDataTest>`,
   1209 		Value: &CDataTest{
   1210 			Chardata: "<![CDATA[Nested]]> Literal! <![CDATA[Nested]]> Literal!",
   1211 		},
   1212 	},
   1213 	{
   1214 		ExpectXML: `<CDataTest><![CDATA[<![CDATA[<![CDATA[Nested]]]]><![CDATA[>]]]]><![CDATA[>]]></CDataTest>`,
   1215 		Value: &CDataTest{
   1216 			Chardata: "<![CDATA[<![CDATA[Nested]]>]]>",
   1217 		},
   1218 	},
   1219 
   1220 	// Test omitempty with parent chain; see golang.org/issue/4168.
   1221 	{
   1222 		ExpectXML: `<Strings><A></A></Strings>`,
   1223 		Value:     &Strings{},
   1224 	},
   1225 	// Custom marshalers.
   1226 	{
   1227 		ExpectXML: `<MyMarshalerTest>hello world</MyMarshalerTest>`,
   1228 		Value:     &MyMarshalerTest{},
   1229 	},
   1230 	{
   1231 		ExpectXML: `<MarshalerStruct Foo="hello world"></MarshalerStruct>`,
   1232 		Value:     &MarshalerStruct{},
   1233 	},
   1234 	{
   1235 		ExpectXML: `<outer xmlns="testns" int="10"></outer>`,
   1236 		Value:     &OuterStruct{IntAttr: 10},
   1237 	},
   1238 	{
   1239 		ExpectXML: `<test xmlns="outerns" int="10"></test>`,
   1240 		Value:     &OuterNamedStruct{XMLName: Name{Space: "outerns", Local: "test"}, IntAttr: 10},
   1241 	},
   1242 	{
   1243 		ExpectXML: `<test xmlns="outerns" int="10"></test>`,
   1244 		Value:     &OuterNamedOrderedStruct{XMLName: Name{Space: "outerns", Local: "test"}, IntAttr: 10},
   1245 	},
   1246 	{
   1247 		ExpectXML: `<outer xmlns="testns" int="10"></outer>`,
   1248 		Value:     &OuterOuterStruct{OuterStruct{IntAttr: 10}},
   1249 	},
   1250 	{
   1251 		ExpectXML: `<NestedAndChardata><A><B></B><B></B></A>test</NestedAndChardata>`,
   1252 		Value:     &NestedAndChardata{AB: make([]string, 2), Chardata: "test"},
   1253 	},
   1254 	{
   1255 		ExpectXML: `<NestedAndComment><A><B></B><B></B></A><!--test--></NestedAndComment>`,
   1256 		Value:     &NestedAndComment{AB: make([]string, 2), Comment: "test"},
   1257 	},
   1258 	{
   1259 		ExpectXML: `<NestedAndCData><A><B></B><B></B></A><![CDATA[test]]></NestedAndCData>`,
   1260 		Value:     &NestedAndCData{AB: make([]string, 2), CDATA: "test"},
   1261 	},
   1262 	// Test pointer indirection in various kinds of fields.
   1263 	// https://golang.org/issue/19063
   1264 	{
   1265 		ExpectXML:   `<IndirComment><T1></T1><!--hi--><T2></T2></IndirComment>`,
   1266 		Value:       &IndirComment{Comment: stringptr("hi")},
   1267 		MarshalOnly: true,
   1268 	},
   1269 	{
   1270 		ExpectXML:   `<IndirComment><T1></T1><T2></T2></IndirComment>`,
   1271 		Value:       &IndirComment{Comment: stringptr("")},
   1272 		MarshalOnly: true,
   1273 	},
   1274 	{
   1275 		ExpectXML:    `<IndirComment><T1></T1><T2></T2></IndirComment>`,
   1276 		Value:        &IndirComment{Comment: nil},
   1277 		MarshalError: "xml: bad type for comment field of xml.IndirComment",
   1278 	},
   1279 	{
   1280 		ExpectXML:     `<IndirComment><T1></T1><!--hi--><T2></T2></IndirComment>`,
   1281 		Value:         &IndirComment{Comment: nil},
   1282 		UnmarshalOnly: true,
   1283 	},
   1284 	{
   1285 		ExpectXML:   `<IfaceComment><T1></T1><!--hi--><T2></T2></IfaceComment>`,
   1286 		Value:       &IfaceComment{Comment: "hi"},
   1287 		MarshalOnly: true,
   1288 	},
   1289 	{
   1290 		ExpectXML:     `<IfaceComment><T1></T1><!--hi--><T2></T2></IfaceComment>`,
   1291 		Value:         &IfaceComment{Comment: nil},
   1292 		UnmarshalOnly: true,
   1293 	},
   1294 	{
   1295 		ExpectXML:    `<IfaceComment><T1></T1><T2></T2></IfaceComment>`,
   1296 		Value:        &IfaceComment{Comment: nil},
   1297 		MarshalError: "xml: bad type for comment field of xml.IfaceComment",
   1298 	},
   1299 	{
   1300 		ExpectXML:     `<IfaceComment><T1></T1><T2></T2></IfaceComment>`,
   1301 		Value:         &IfaceComment{Comment: nil},
   1302 		UnmarshalOnly: true,
   1303 	},
   1304 	{
   1305 		ExpectXML: `<DirectComment><T1></T1><!--hi--><T2></T2></DirectComment>`,
   1306 		Value:     &DirectComment{Comment: string("hi")},
   1307 	},
   1308 	{
   1309 		ExpectXML: `<DirectComment><T1></T1><T2></T2></DirectComment>`,
   1310 		Value:     &DirectComment{Comment: string("")},
   1311 	},
   1312 	{
   1313 		ExpectXML: `<IndirChardata><T1></T1>hi<T2></T2></IndirChardata>`,
   1314 		Value:     &IndirChardata{Chardata: stringptr("hi")},
   1315 	},
   1316 	{
   1317 		ExpectXML:     `<IndirChardata><T1></T1><![CDATA[hi]]><T2></T2></IndirChardata>`,
   1318 		Value:         &IndirChardata{Chardata: stringptr("hi")},
   1319 		UnmarshalOnly: true, // marshals without CDATA
   1320 	},
   1321 	{
   1322 		ExpectXML: `<IndirChardata><T1></T1><T2></T2></IndirChardata>`,
   1323 		Value:     &IndirChardata{Chardata: stringptr("")},
   1324 	},
   1325 	{
   1326 		ExpectXML:   `<IndirChardata><T1></T1><T2></T2></IndirChardata>`,
   1327 		Value:       &IndirChardata{Chardata: nil},
   1328 		MarshalOnly: true, // unmarshal leaves Chardata=stringptr("")
   1329 	},
   1330 	{
   1331 		ExpectXML:      `<IfaceChardata><T1></T1>hi<T2></T2></IfaceChardata>`,
   1332 		Value:          &IfaceChardata{Chardata: string("hi")},
   1333 		UnmarshalError: "cannot unmarshal into interface {}",
   1334 	},
   1335 	{
   1336 		ExpectXML:      `<IfaceChardata><T1></T1><![CDATA[hi]]><T2></T2></IfaceChardata>`,
   1337 		Value:          &IfaceChardata{Chardata: string("hi")},
   1338 		UnmarshalOnly:  true, // marshals without CDATA
   1339 		UnmarshalError: "cannot unmarshal into interface {}",
   1340 	},
   1341 	{
   1342 		ExpectXML:      `<IfaceChardata><T1></T1><T2></T2></IfaceChardata>`,
   1343 		Value:          &IfaceChardata{Chardata: string("")},
   1344 		UnmarshalError: "cannot unmarshal into interface {}",
   1345 	},
   1346 	{
   1347 		ExpectXML:      `<IfaceChardata><T1></T1><T2></T2></IfaceChardata>`,
   1348 		Value:          &IfaceChardata{Chardata: nil},
   1349 		UnmarshalError: "cannot unmarshal into interface {}",
   1350 	},
   1351 	{
   1352 		ExpectXML: `<DirectChardata><T1></T1>hi<T2></T2></DirectChardata>`,
   1353 		Value:     &DirectChardata{Chardata: string("hi")},
   1354 	},
   1355 	{
   1356 		ExpectXML:     `<DirectChardata><T1></T1><![CDATA[hi]]><T2></T2></DirectChardata>`,
   1357 		Value:         &DirectChardata{Chardata: string("hi")},
   1358 		UnmarshalOnly: true, // marshals without CDATA
   1359 	},
   1360 	{
   1361 		ExpectXML: `<DirectChardata><T1></T1><T2></T2></DirectChardata>`,
   1362 		Value:     &DirectChardata{Chardata: string("")},
   1363 	},
   1364 	{
   1365 		ExpectXML: `<IndirCDATA><T1></T1><![CDATA[hi]]><T2></T2></IndirCDATA>`,
   1366 		Value:     &IndirCDATA{CDATA: stringptr("hi")},
   1367 	},
   1368 	{
   1369 		ExpectXML:     `<IndirCDATA><T1></T1>hi<T2></T2></IndirCDATA>`,
   1370 		Value:         &IndirCDATA{CDATA: stringptr("hi")},
   1371 		UnmarshalOnly: true, // marshals with CDATA
   1372 	},
   1373 	{
   1374 		ExpectXML: `<IndirCDATA><T1></T1><T2></T2></IndirCDATA>`,
   1375 		Value:     &IndirCDATA{CDATA: stringptr("")},
   1376 	},
   1377 	{
   1378 		ExpectXML:   `<IndirCDATA><T1></T1><T2></T2></IndirCDATA>`,
   1379 		Value:       &IndirCDATA{CDATA: nil},
   1380 		MarshalOnly: true, // unmarshal leaves CDATA=stringptr("")
   1381 	},
   1382 	{
   1383 		ExpectXML:      `<IfaceCDATA><T1></T1><![CDATA[hi]]><T2></T2></IfaceCDATA>`,
   1384 		Value:          &IfaceCDATA{CDATA: string("hi")},
   1385 		UnmarshalError: "cannot unmarshal into interface {}",
   1386 	},
   1387 	{
   1388 		ExpectXML:      `<IfaceCDATA><T1></T1>hi<T2></T2></IfaceCDATA>`,
   1389 		Value:          &IfaceCDATA{CDATA: string("hi")},
   1390 		UnmarshalOnly:  true, // marshals with CDATA
   1391 		UnmarshalError: "cannot unmarshal into interface {}",
   1392 	},
   1393 	{
   1394 		ExpectXML:      `<IfaceCDATA><T1></T1><T2></T2></IfaceCDATA>`,
   1395 		Value:          &IfaceCDATA{CDATA: string("")},
   1396 		UnmarshalError: "cannot unmarshal into interface {}",
   1397 	},
   1398 	{
   1399 		ExpectXML:      `<IfaceCDATA><T1></T1><T2></T2></IfaceCDATA>`,
   1400 		Value:          &IfaceCDATA{CDATA: nil},
   1401 		UnmarshalError: "cannot unmarshal into interface {}",
   1402 	},
   1403 	{
   1404 		ExpectXML: `<DirectCDATA><T1></T1><![CDATA[hi]]><T2></T2></DirectCDATA>`,
   1405 		Value:     &DirectCDATA{CDATA: string("hi")},
   1406 	},
   1407 	{
   1408 		ExpectXML:     `<DirectCDATA><T1></T1>hi<T2></T2></DirectCDATA>`,
   1409 		Value:         &DirectCDATA{CDATA: string("hi")},
   1410 		UnmarshalOnly: true, // marshals with CDATA
   1411 	},
   1412 	{
   1413 		ExpectXML: `<DirectCDATA><T1></T1><T2></T2></DirectCDATA>`,
   1414 		Value:     &DirectCDATA{CDATA: string("")},
   1415 	},
   1416 	{
   1417 		ExpectXML:   `<IndirInnerXML><T1></T1><hi/><T2></T2></IndirInnerXML>`,
   1418 		Value:       &IndirInnerXML{InnerXML: stringptr("<hi/>")},
   1419 		MarshalOnly: true,
   1420 	},
   1421 	{
   1422 		ExpectXML:   `<IndirInnerXML><T1></T1><T2></T2></IndirInnerXML>`,
   1423 		Value:       &IndirInnerXML{InnerXML: stringptr("")},
   1424 		MarshalOnly: true,
   1425 	},
   1426 	{
   1427 		ExpectXML: `<IndirInnerXML><T1></T1><T2></T2></IndirInnerXML>`,
   1428 		Value:     &IndirInnerXML{InnerXML: nil},
   1429 	},
   1430 	{
   1431 		ExpectXML:     `<IndirInnerXML><T1></T1><hi/><T2></T2></IndirInnerXML>`,
   1432 		Value:         &IndirInnerXML{InnerXML: nil},
   1433 		UnmarshalOnly: true,
   1434 	},
   1435 	{
   1436 		ExpectXML:   `<IfaceInnerXML><T1></T1><hi/><T2></T2></IfaceInnerXML>`,
   1437 		Value:       &IfaceInnerXML{InnerXML: "<hi/>"},
   1438 		MarshalOnly: true,
   1439 	},
   1440 	{
   1441 		ExpectXML:     `<IfaceInnerXML><T1></T1><hi/><T2></T2></IfaceInnerXML>`,
   1442 		Value:         &IfaceInnerXML{InnerXML: nil},
   1443 		UnmarshalOnly: true,
   1444 	},
   1445 	{
   1446 		ExpectXML: `<IfaceInnerXML><T1></T1><T2></T2></IfaceInnerXML>`,
   1447 		Value:     &IfaceInnerXML{InnerXML: nil},
   1448 	},
   1449 	{
   1450 		ExpectXML:     `<IfaceInnerXML><T1></T1><T2></T2></IfaceInnerXML>`,
   1451 		Value:         &IfaceInnerXML{InnerXML: nil},
   1452 		UnmarshalOnly: true,
   1453 	},
   1454 	{
   1455 		ExpectXML:   `<DirectInnerXML><T1></T1><hi/><T2></T2></DirectInnerXML>`,
   1456 		Value:       &DirectInnerXML{InnerXML: string("<hi/>")},
   1457 		MarshalOnly: true,
   1458 	},
   1459 	{
   1460 		ExpectXML:     `<DirectInnerXML><T1></T1><hi/><T2></T2></DirectInnerXML>`,
   1461 		Value:         &DirectInnerXML{InnerXML: string("<T1></T1><hi/><T2></T2>")},
   1462 		UnmarshalOnly: true,
   1463 	},
   1464 	{
   1465 		ExpectXML:   `<DirectInnerXML><T1></T1><T2></T2></DirectInnerXML>`,
   1466 		Value:       &DirectInnerXML{InnerXML: string("")},
   1467 		MarshalOnly: true,
   1468 	},
   1469 	{
   1470 		ExpectXML:     `<DirectInnerXML><T1></T1><T2></T2></DirectInnerXML>`,
   1471 		Value:         &DirectInnerXML{InnerXML: string("<T1></T1><T2></T2>")},
   1472 		UnmarshalOnly: true,
   1473 	},
   1474 	{
   1475 		ExpectXML: `<IndirElement><T1></T1><Element>hi</Element><T2></T2></IndirElement>`,
   1476 		Value:     &IndirElement{Element: stringptr("hi")},
   1477 	},
   1478 	{
   1479 		ExpectXML: `<IndirElement><T1></T1><Element></Element><T2></T2></IndirElement>`,
   1480 		Value:     &IndirElement{Element: stringptr("")},
   1481 	},
   1482 	{
   1483 		ExpectXML: `<IndirElement><T1></T1><T2></T2></IndirElement>`,
   1484 		Value:     &IndirElement{Element: nil},
   1485 	},
   1486 	{
   1487 		ExpectXML:   `<IfaceElement><T1></T1><Element>hi</Element><T2></T2></IfaceElement>`,
   1488 		Value:       &IfaceElement{Element: "hi"},
   1489 		MarshalOnly: true,
   1490 	},
   1491 	{
   1492 		ExpectXML:     `<IfaceElement><T1></T1><Element>hi</Element><T2></T2></IfaceElement>`,
   1493 		Value:         &IfaceElement{Element: nil},
   1494 		UnmarshalOnly: true,
   1495 	},
   1496 	{
   1497 		ExpectXML: `<IfaceElement><T1></T1><T2></T2></IfaceElement>`,
   1498 		Value:     &IfaceElement{Element: nil},
   1499 	},
   1500 	{
   1501 		ExpectXML:     `<IfaceElement><T1></T1><T2></T2></IfaceElement>`,
   1502 		Value:         &IfaceElement{Element: nil},
   1503 		UnmarshalOnly: true,
   1504 	},
   1505 	{
   1506 		ExpectXML: `<DirectElement><T1></T1><Element>hi</Element><T2></T2></DirectElement>`,
   1507 		Value:     &DirectElement{Element: string("hi")},
   1508 	},
   1509 	{
   1510 		ExpectXML: `<DirectElement><T1></T1><Element></Element><T2></T2></DirectElement>`,
   1511 		Value:     &DirectElement{Element: string("")},
   1512 	},
   1513 	{
   1514 		ExpectXML: `<IndirOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></IndirOmitEmpty>`,
   1515 		Value:     &IndirOmitEmpty{OmitEmpty: stringptr("hi")},
   1516 	},
   1517 	{
   1518 		// Note: Changed in Go 1.8 to include <OmitEmpty> element (because x.OmitEmpty != nil).
   1519 		ExpectXML:   `<IndirOmitEmpty><T1></T1><OmitEmpty></OmitEmpty><T2></T2></IndirOmitEmpty>`,
   1520 		Value:       &IndirOmitEmpty{OmitEmpty: stringptr("")},
   1521 		MarshalOnly: true,
   1522 	},
   1523 	{
   1524 		ExpectXML:     `<IndirOmitEmpty><T1></T1><OmitEmpty></OmitEmpty><T2></T2></IndirOmitEmpty>`,
   1525 		Value:         &IndirOmitEmpty{OmitEmpty: stringptr("")},
   1526 		UnmarshalOnly: true,
   1527 	},
   1528 	{
   1529 		ExpectXML: `<IndirOmitEmpty><T1></T1><T2></T2></IndirOmitEmpty>`,
   1530 		Value:     &IndirOmitEmpty{OmitEmpty: nil},
   1531 	},
   1532 	{
   1533 		ExpectXML:   `<IfaceOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></IfaceOmitEmpty>`,
   1534 		Value:       &IfaceOmitEmpty{OmitEmpty: "hi"},
   1535 		MarshalOnly: true,
   1536 	},
   1537 	{
   1538 		ExpectXML:     `<IfaceOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></IfaceOmitEmpty>`,
   1539 		Value:         &IfaceOmitEmpty{OmitEmpty: nil},
   1540 		UnmarshalOnly: true,
   1541 	},
   1542 	{
   1543 		ExpectXML: `<IfaceOmitEmpty><T1></T1><T2></T2></IfaceOmitEmpty>`,
   1544 		Value:     &IfaceOmitEmpty{OmitEmpty: nil},
   1545 	},
   1546 	{
   1547 		ExpectXML:     `<IfaceOmitEmpty><T1></T1><T2></T2></IfaceOmitEmpty>`,
   1548 		Value:         &IfaceOmitEmpty{OmitEmpty: nil},
   1549 		UnmarshalOnly: true,
   1550 	},
   1551 	{
   1552 		ExpectXML: `<DirectOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></DirectOmitEmpty>`,
   1553 		Value:     &DirectOmitEmpty{OmitEmpty: string("hi")},
   1554 	},
   1555 	{
   1556 		ExpectXML: `<DirectOmitEmpty><T1></T1><T2></T2></DirectOmitEmpty>`,
   1557 		Value:     &DirectOmitEmpty{OmitEmpty: string("")},
   1558 	},
   1559 	{
   1560 		ExpectXML: `<IndirAny><T1></T1><Any>hi</Any><T2></T2></IndirAny>`,
   1561 		Value:     &IndirAny{Any: stringptr("hi")},
   1562 	},
   1563 	{
   1564 		ExpectXML: `<IndirAny><T1></T1><Any></Any><T2></T2></IndirAny>`,
   1565 		Value:     &IndirAny{Any: stringptr("")},
   1566 	},
   1567 	{
   1568 		ExpectXML: `<IndirAny><T1></T1><T2></T2></IndirAny>`,
   1569 		Value:     &IndirAny{Any: nil},
   1570 	},
   1571 	{
   1572 		ExpectXML:   `<IfaceAny><T1></T1><Any>hi</Any><T2></T2></IfaceAny>`,
   1573 		Value:       &IfaceAny{Any: "hi"},
   1574 		MarshalOnly: true,
   1575 	},
   1576 	{
   1577 		ExpectXML:     `<IfaceAny><T1></T1><Any>hi</Any><T2></T2></IfaceAny>`,
   1578 		Value:         &IfaceAny{Any: nil},
   1579 		UnmarshalOnly: true,
   1580 	},
   1581 	{
   1582 		ExpectXML: `<IfaceAny><T1></T1><T2></T2></IfaceAny>`,
   1583 		Value:     &IfaceAny{Any: nil},
   1584 	},
   1585 	{
   1586 		ExpectXML:     `<IfaceAny><T1></T1><T2></T2></IfaceAny>`,
   1587 		Value:         &IfaceAny{Any: nil},
   1588 		UnmarshalOnly: true,
   1589 	},
   1590 	{
   1591 		ExpectXML: `<DirectAny><T1></T1><Any>hi</Any><T2></T2></DirectAny>`,
   1592 		Value:     &DirectAny{Any: string("hi")},
   1593 	},
   1594 	{
   1595 		ExpectXML: `<DirectAny><T1></T1><Any></Any><T2></T2></DirectAny>`,
   1596 		Value:     &DirectAny{Any: string("")},
   1597 	},
   1598 	{
   1599 		ExpectXML:     `<IndirFoo><T1></T1><Foo>hi</Foo><T2></T2></IndirFoo>`,
   1600 		Value:         &IndirAny{Any: stringptr("hi")},
   1601 		UnmarshalOnly: true,
   1602 	},
   1603 	{
   1604 		ExpectXML:     `<IndirFoo><T1></T1><Foo></Foo><T2></T2></IndirFoo>`,
   1605 		Value:         &IndirAny{Any: stringptr("")},
   1606 		UnmarshalOnly: true,
   1607 	},
   1608 	{
   1609 		ExpectXML:     `<IndirFoo><T1></T1><T2></T2></IndirFoo>`,
   1610 		Value:         &IndirAny{Any: nil},
   1611 		UnmarshalOnly: true,
   1612 	},
   1613 	{
   1614 		ExpectXML:     `<IfaceFoo><T1></T1><Foo>hi</Foo><T2></T2></IfaceFoo>`,
   1615 		Value:         &IfaceAny{Any: nil},
   1616 		UnmarshalOnly: true,
   1617 	},
   1618 	{
   1619 		ExpectXML:     `<IfaceFoo><T1></T1><T2></T2></IfaceFoo>`,
   1620 		Value:         &IfaceAny{Any: nil},
   1621 		UnmarshalOnly: true,
   1622 	},
   1623 	{
   1624 		ExpectXML:     `<IfaceFoo><T1></T1><T2></T2></IfaceFoo>`,
   1625 		Value:         &IfaceAny{Any: nil},
   1626 		UnmarshalOnly: true,
   1627 	},
   1628 	{
   1629 		ExpectXML:     `<DirectFoo><T1></T1><Foo>hi</Foo><T2></T2></DirectFoo>`,
   1630 		Value:         &DirectAny{Any: string("hi")},
   1631 		UnmarshalOnly: true,
   1632 	},
   1633 	{
   1634 		ExpectXML:     `<DirectFoo><T1></T1><Foo></Foo><T2></T2></DirectFoo>`,
   1635 		Value:         &DirectAny{Any: string("")},
   1636 		UnmarshalOnly: true,
   1637 	},
   1638 }
   1639 
   1640 func TestMarshal(t *testing.T) {
   1641 	for idx, test := range marshalTests {
   1642 		if test.UnmarshalOnly {
   1643 			continue
   1644 		}
   1645 
   1646 		t.Run(fmt.Sprintf("%d", idx), func(t *testing.T) {
   1647 			data, err := Marshal(test.Value)
   1648 			if err != nil {
   1649 				if test.MarshalError == "" {
   1650 					t.Errorf("marshal(%#v): %s", test.Value, err)
   1651 					return
   1652 				}
   1653 				if !strings.Contains(err.Error(), test.MarshalError) {
   1654 					t.Errorf("marshal(%#v): %s, want %q", test.Value, err, test.MarshalError)
   1655 				}
   1656 				return
   1657 			}
   1658 			if test.MarshalError != "" {
   1659 				t.Errorf("Marshal succeeded, want error %q", test.MarshalError)
   1660 				return
   1661 			}
   1662 			if got, want := string(data), test.ExpectXML; got != want {
   1663 				if strings.Contains(want, "\n") {
   1664 					t.Errorf("marshal(%#v):\nHAVE:\n%s\nWANT:\n%s", test.Value, got, want)
   1665 				} else {
   1666 					t.Errorf("marshal(%#v):\nhave %#q\nwant %#q", test.Value, got, want)
   1667 				}
   1668 			}
   1669 		})
   1670 	}
   1671 }
   1672 
   1673 type AttrParent struct {
   1674 	X string `xml:"X>Y,attr"`
   1675 }
   1676 
   1677 type BadAttr struct {
   1678 	Name map[string]string `xml:"name,attr"`
   1679 }
   1680 
   1681 var marshalErrorTests = []struct {
   1682 	Value interface{}
   1683 	Err   string
   1684 	Kind  reflect.Kind
   1685 }{
   1686 	{
   1687 		Value: make(chan bool),
   1688 		Err:   "xml: unsupported type: chan bool",
   1689 		Kind:  reflect.Chan,
   1690 	},
   1691 	{
   1692 		Value: map[string]string{
   1693 			"question": "What do you get when you multiply six by nine?",
   1694 			"answer":   "42",
   1695 		},
   1696 		Err:  "xml: unsupported type: map[string]string",
   1697 		Kind: reflect.Map,
   1698 	},
   1699 	{
   1700 		Value: map[*Ship]bool{nil: false},
   1701 		Err:   "xml: unsupported type: map[*xml.Ship]bool",
   1702 		Kind:  reflect.Map,
   1703 	},
   1704 	{
   1705 		Value: &Domain{Comment: []byte("f--bar")},
   1706 		Err:   `xml: comments must not contain "--"`,
   1707 	},
   1708 	// Reject parent chain with attr, never worked; see golang.org/issue/5033.
   1709 	{
   1710 		Value: &AttrParent{},
   1711 		Err:   `xml: X>Y chain not valid with attr flag`,
   1712 	},
   1713 	{
   1714 		Value: BadAttr{map[string]string{"X": "Y"}},
   1715 		Err:   `xml: unsupported type: map[string]string`,
   1716 	},
   1717 }
   1718 
   1719 var marshalIndentTests = []struct {
   1720 	Value     interface{}
   1721 	Prefix    string
   1722 	Indent    string
   1723 	ExpectXML string
   1724 }{
   1725 	{
   1726 		Value: &SecretAgent{
   1727 			Handle:    "007",
   1728 			Identity:  "James Bond",
   1729 			Obfuscate: "<redacted/>",
   1730 		},
   1731 		Prefix:    "",
   1732 		Indent:    "\t",
   1733 		ExpectXML: fmt.Sprintf("<agent handle=\"007\">\n\t<Identity>James Bond</Identity><redacted/>\n</agent>"),
   1734 	},
   1735 }
   1736 
   1737 func TestMarshalErrors(t *testing.T) {
   1738 	for idx, test := range marshalErrorTests {
   1739 		data, err := Marshal(test.Value)
   1740 		if err == nil {
   1741 			t.Errorf("#%d: marshal(%#v) = [success] %q, want error %v", idx, test.Value, data, test.Err)
   1742 			continue
   1743 		}
   1744 		if err.Error() != test.Err {
   1745 			t.Errorf("#%d: marshal(%#v) = [error] %v, want %v", idx, test.Value, err, test.Err)
   1746 		}
   1747 		if test.Kind != reflect.Invalid {
   1748 			if kind := err.(*UnsupportedTypeError).Type.Kind(); kind != test.Kind {
   1749 				t.Errorf("#%d: marshal(%#v) = [error kind] %s, want %s", idx, test.Value, kind, test.Kind)
   1750 			}
   1751 		}
   1752 	}
   1753 }
   1754 
   1755 // Do invertibility testing on the various structures that we test
   1756 func TestUnmarshal(t *testing.T) {
   1757 	for i, test := range marshalTests {
   1758 		if test.MarshalOnly {
   1759 			continue
   1760 		}
   1761 		if _, ok := test.Value.(*Plain); ok {
   1762 			continue
   1763 		}
   1764 		if test.ExpectXML == `<top>`+
   1765 			`<x><b xmlns="space">b</b>`+
   1766 			`<b xmlns="space1">b1</b></x>`+
   1767 			`</top>` {
   1768 			// TODO(rogpeppe): re-enable this test in
   1769 			// https://go-review.googlesource.com/#/c/5910/
   1770 			continue
   1771 		}
   1772 
   1773 		vt := reflect.TypeOf(test.Value)
   1774 		dest := reflect.New(vt.Elem()).Interface()
   1775 		err := Unmarshal([]byte(test.ExpectXML), dest)
   1776 
   1777 		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
   1778 			switch fix := dest.(type) {
   1779 			case *Feed:
   1780 				fix.Author.InnerXML = ""
   1781 				for i := range fix.Entry {
   1782 					fix.Entry[i].Author.InnerXML = ""
   1783 				}
   1784 			}
   1785 
   1786 			if err != nil {
   1787 				if test.UnmarshalError == "" {
   1788 					t.Errorf("unmarshal(%#v): %s", test.ExpectXML, err)
   1789 					return
   1790 				}
   1791 				if !strings.Contains(err.Error(), test.UnmarshalError) {
   1792 					t.Errorf("unmarshal(%#v): %s, want %q", test.ExpectXML, err, test.UnmarshalError)
   1793 				}
   1794 				return
   1795 			}
   1796 			if got, want := dest, test.Value; !reflect.DeepEqual(got, want) {
   1797 				t.Errorf("unmarshal(%q):\nhave %#v\nwant %#v", test.ExpectXML, got, want)
   1798 			}
   1799 		})
   1800 	}
   1801 }
   1802 
   1803 func TestMarshalIndent(t *testing.T) {
   1804 	for i, test := range marshalIndentTests {
   1805 		data, err := MarshalIndent(test.Value, test.Prefix, test.Indent)
   1806 		if err != nil {
   1807 			t.Errorf("#%d: Error: %s", i, err)
   1808 			continue
   1809 		}
   1810 		if got, want := string(data), test.ExpectXML; got != want {
   1811 			t.Errorf("#%d: MarshalIndent:\nGot:%s\nWant:\n%s", i, got, want)
   1812 		}
   1813 	}
   1814 }
   1815 
   1816 type limitedBytesWriter struct {
   1817 	w      io.Writer
   1818 	remain int // until writes fail
   1819 }
   1820 
   1821 func (lw *limitedBytesWriter) Write(p []byte) (n int, err error) {
   1822 	if lw.remain <= 0 {
   1823 		println("error")
   1824 		return 0, errors.New("write limit hit")
   1825 	}
   1826 	if len(p) > lw.remain {
   1827 		p = p[:lw.remain]
   1828 		n, _ = lw.w.Write(p)
   1829 		lw.remain = 0
   1830 		return n, errors.New("write limit hit")
   1831 	}
   1832 	n, err = lw.w.Write(p)
   1833 	lw.remain -= n
   1834 	return n, err
   1835 }
   1836 
   1837 func TestMarshalWriteErrors(t *testing.T) {
   1838 	var buf bytes.Buffer
   1839 	const writeCap = 1024
   1840 	w := &limitedBytesWriter{&buf, writeCap}
   1841 	enc := NewEncoder(w)
   1842 	var err error
   1843 	var i int
   1844 	const n = 4000
   1845 	for i = 1; i <= n; i++ {
   1846 		err = enc.Encode(&Passenger{
   1847 			Name:   []string{"Alice", "Bob"},
   1848 			Weight: 5,
   1849 		})
   1850 		if err != nil {
   1851 			break
   1852 		}
   1853 	}
   1854 	if err == nil {
   1855 		t.Error("expected an error")
   1856 	}
   1857 	if i == n {
   1858 		t.Errorf("expected to fail before the end")
   1859 	}
   1860 	if buf.Len() != writeCap {
   1861 		t.Errorf("buf.Len() = %d; want %d", buf.Len(), writeCap)
   1862 	}
   1863 }
   1864 
   1865 func TestMarshalWriteIOErrors(t *testing.T) {
   1866 	enc := NewEncoder(errWriter{})
   1867 
   1868 	expectErr := "unwritable"
   1869 	err := enc.Encode(&Passenger{})
   1870 	if err == nil || err.Error() != expectErr {
   1871 		t.Errorf("EscapeTest = [error] %v, want %v", err, expectErr)
   1872 	}
   1873 }
   1874 
   1875 func TestMarshalFlush(t *testing.T) {
   1876 	var buf bytes.Buffer
   1877 	enc := NewEncoder(&buf)
   1878 	if err := enc.EncodeToken(CharData("hello world")); err != nil {
   1879 		t.Fatalf("enc.EncodeToken: %v", err)
   1880 	}
   1881 	if buf.Len() > 0 {
   1882 		t.Fatalf("enc.EncodeToken caused actual write: %q", buf.Bytes())
   1883 	}
   1884 	if err := enc.Flush(); err != nil {
   1885 		t.Fatalf("enc.Flush: %v", err)
   1886 	}
   1887 	if buf.String() != "hello world" {
   1888 		t.Fatalf("after enc.Flush, buf.String() = %q, want %q", buf.String(), "hello world")
   1889 	}
   1890 }
   1891 
   1892 func BenchmarkMarshal(b *testing.B) {
   1893 	b.ReportAllocs()
   1894 	b.RunParallel(func(pb *testing.PB) {
   1895 		for pb.Next() {
   1896 			Marshal(atomValue)
   1897 		}
   1898 	})
   1899 }
   1900 
   1901 func BenchmarkUnmarshal(b *testing.B) {
   1902 	b.ReportAllocs()
   1903 	xml := []byte(atomXML)
   1904 	b.RunParallel(func(pb *testing.PB) {
   1905 		for pb.Next() {
   1906 			Unmarshal(xml, &Feed{})
   1907 		}
   1908 	})
   1909 }
   1910 
   1911 // golang.org/issue/6556
   1912 func TestStructPointerMarshal(t *testing.T) {
   1913 	type A struct {
   1914 		XMLName string `xml:"a"`
   1915 		B       []interface{}
   1916 	}
   1917 	type C struct {
   1918 		XMLName Name
   1919 		Value   string `xml:"value"`
   1920 	}
   1921 
   1922 	a := new(A)
   1923 	a.B = append(a.B, &C{
   1924 		XMLName: Name{Local: "c"},
   1925 		Value:   "x",
   1926 	})
   1927 
   1928 	b, err := Marshal(a)
   1929 	if err != nil {
   1930 		t.Fatal(err)
   1931 	}
   1932 	if x := string(b); x != "<a><c><value>x</value></c></a>" {
   1933 		t.Fatal(x)
   1934 	}
   1935 	var v A
   1936 	err = Unmarshal(b, &v)
   1937 	if err != nil {
   1938 		t.Fatal(err)
   1939 	}
   1940 }
   1941 
   1942 var encodeTokenTests = []struct {
   1943 	desc string
   1944 	toks []Token
   1945 	want string
   1946 	err  string
   1947 }{{
   1948 	desc: "start element with name space",
   1949 	toks: []Token{
   1950 		StartElement{Name{"space", "local"}, nil},
   1951 	},
   1952 	want: `<local xmlns="space">`,
   1953 }, {
   1954 	desc: "start element with no name",
   1955 	toks: []Token{
   1956 		StartElement{Name{"space", ""}, nil},
   1957 	},
   1958 	err: "xml: start tag with no name",
   1959 }, {
   1960 	desc: "end element with no name",
   1961 	toks: []Token{
   1962 		EndElement{Name{"space", ""}},
   1963 	},
   1964 	err: "xml: end tag with no name",
   1965 }, {
   1966 	desc: "char data",
   1967 	toks: []Token{
   1968 		CharData("foo"),
   1969 	},
   1970 	want: `foo`,
   1971 }, {
   1972 	desc: "char data with escaped chars",
   1973 	toks: []Token{
   1974 		CharData(" \t\n"),
   1975 	},
   1976 	want: " &#x9;\n",
   1977 }, {
   1978 	desc: "comment",
   1979 	toks: []Token{
   1980 		Comment("foo"),
   1981 	},
   1982 	want: `<!--foo-->`,
   1983 }, {
   1984 	desc: "comment with invalid content",
   1985 	toks: []Token{
   1986 		Comment("foo-->"),
   1987 	},
   1988 	err: "xml: EncodeToken of Comment containing --> marker",
   1989 }, {
   1990 	desc: "proc instruction",
   1991 	toks: []Token{
   1992 		ProcInst{"Target", []byte("Instruction")},
   1993 	},
   1994 	want: `<?Target Instruction?>`,
   1995 }, {
   1996 	desc: "proc instruction with empty target",
   1997 	toks: []Token{
   1998 		ProcInst{"", []byte("Instruction")},
   1999 	},
   2000 	err: "xml: EncodeToken of ProcInst with invalid Target",
   2001 }, {
   2002 	desc: "proc instruction with bad content",
   2003 	toks: []Token{
   2004 		ProcInst{"", []byte("Instruction?>")},
   2005 	},
   2006 	err: "xml: EncodeToken of ProcInst with invalid Target",
   2007 }, {
   2008 	desc: "directive",
   2009 	toks: []Token{
   2010 		Directive("foo"),
   2011 	},
   2012 	want: `<!foo>`,
   2013 }, {
   2014 	desc: "more complex directive",
   2015 	toks: []Token{
   2016 		Directive("DOCTYPE doc [ <!ELEMENT doc '>'> <!-- com>ment --> ]"),
   2017 	},
   2018 	want: `<!DOCTYPE doc [ <!ELEMENT doc '>'> <!-- com>ment --> ]>`,
   2019 }, {
   2020 	desc: "directive instruction with bad name",
   2021 	toks: []Token{
   2022 		Directive("foo>"),
   2023 	},
   2024 	err: "xml: EncodeToken of Directive containing wrong < or > markers",
   2025 }, {
   2026 	desc: "end tag without start tag",
   2027 	toks: []Token{
   2028 		EndElement{Name{"foo", "bar"}},
   2029 	},
   2030 	err: "xml: end tag </bar> without start tag",
   2031 }, {
   2032 	desc: "mismatching end tag local name",
   2033 	toks: []Token{
   2034 		StartElement{Name{"", "foo"}, nil},
   2035 		EndElement{Name{"", "bar"}},
   2036 	},
   2037 	err:  "xml: end tag </bar> does not match start tag <foo>",
   2038 	want: `<foo>`,
   2039 }, {
   2040 	desc: "mismatching end tag namespace",
   2041 	toks: []Token{
   2042 		StartElement{Name{"space", "foo"}, nil},
   2043 		EndElement{Name{"another", "foo"}},
   2044 	},
   2045 	err:  "xml: end tag </foo> in namespace another does not match start tag <foo> in namespace space",
   2046 	want: `<foo xmlns="space">`,
   2047 }, {
   2048 	desc: "start element with explicit namespace",
   2049 	toks: []Token{
   2050 		StartElement{Name{"space", "local"}, []Attr{
   2051 			{Name{"xmlns", "x"}, "space"},
   2052 			{Name{"space", "foo"}, "value"},
   2053 		}},
   2054 	},
   2055 	want: `<local xmlns="space" xmlns:_xmlns="xmlns" _xmlns:x="space" xmlns:space="space" space:foo="value">`,
   2056 }, {
   2057 	desc: "start element with explicit namespace and colliding prefix",
   2058 	toks: []Token{
   2059 		StartElement{Name{"space", "local"}, []Attr{
   2060 			{Name{"xmlns", "x"}, "space"},
   2061 			{Name{"space", "foo"}, "value"},
   2062 			{Name{"x", "bar"}, "other"},
   2063 		}},
   2064 	},
   2065 	want: `<local xmlns="space" xmlns:_xmlns="xmlns" _xmlns:x="space" xmlns:space="space" space:foo="value" xmlns:x="x" x:bar="other">`,
   2066 }, {
   2067 	desc: "start element using previously defined namespace",
   2068 	toks: []Token{
   2069 		StartElement{Name{"", "local"}, []Attr{
   2070 			{Name{"xmlns", "x"}, "space"},
   2071 		}},
   2072 		StartElement{Name{"space", "foo"}, []Attr{
   2073 			{Name{"space", "x"}, "y"},
   2074 		}},
   2075 	},
   2076 	want: `<local xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" xmlns:space="space" space:x="y">`,
   2077 }, {
   2078 	desc: "nested name space with same prefix",
   2079 	toks: []Token{
   2080 		StartElement{Name{"", "foo"}, []Attr{
   2081 			{Name{"xmlns", "x"}, "space1"},
   2082 		}},
   2083 		StartElement{Name{"", "foo"}, []Attr{
   2084 			{Name{"xmlns", "x"}, "space2"},
   2085 		}},
   2086 		StartElement{Name{"", "foo"}, []Attr{
   2087 			{Name{"space1", "a"}, "space1 value"},
   2088 			{Name{"space2", "b"}, "space2 value"},
   2089 		}},
   2090 		EndElement{Name{"", "foo"}},
   2091 		EndElement{Name{"", "foo"}},
   2092 		StartElement{Name{"", "foo"}, []Attr{
   2093 			{Name{"space1", "a"}, "space1 value"},
   2094 			{Name{"space2", "b"}, "space2 value"},
   2095 		}},
   2096 	},
   2097 	want: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space1"><foo _xmlns:x="space2"><foo xmlns:space1="space1" space1:a="space1 value" xmlns:space2="space2" space2:b="space2 value"></foo></foo><foo xmlns:space1="space1" space1:a="space1 value" xmlns:space2="space2" space2:b="space2 value">`,
   2098 }, {
   2099 	desc: "start element defining several prefixes for the same name space",
   2100 	toks: []Token{
   2101 		StartElement{Name{"space", "foo"}, []Attr{
   2102 			{Name{"xmlns", "a"}, "space"},
   2103 			{Name{"xmlns", "b"}, "space"},
   2104 			{Name{"space", "x"}, "value"},
   2105 		}},
   2106 	},
   2107 	want: `<foo xmlns="space" xmlns:_xmlns="xmlns" _xmlns:a="space" _xmlns:b="space" xmlns:space="space" space:x="value">`,
   2108 }, {
   2109 	desc: "nested element redefines name space",
   2110 	toks: []Token{
   2111 		StartElement{Name{"", "foo"}, []Attr{
   2112 			{Name{"xmlns", "x"}, "space"},
   2113 		}},
   2114 		StartElement{Name{"space", "foo"}, []Attr{
   2115 			{Name{"xmlns", "y"}, "space"},
   2116 			{Name{"space", "a"}, "value"},
   2117 		}},
   2118 	},
   2119 	want: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" _xmlns:y="space" xmlns:space="space" space:a="value">`,
   2120 }, {
   2121 	desc: "nested element creates alias for default name space",
   2122 	toks: []Token{
   2123 		StartElement{Name{"space", "foo"}, []Attr{
   2124 			{Name{"", "xmlns"}, "space"},
   2125 		}},
   2126 		StartElement{Name{"space", "foo"}, []Attr{
   2127 			{Name{"xmlns", "y"}, "space"},
   2128 			{Name{"space", "a"}, "value"},
   2129 		}},
   2130 	},
   2131 	want: `<foo xmlns="space" xmlns="space"><foo xmlns="space" xmlns:_xmlns="xmlns" _xmlns:y="space" xmlns:space="space" space:a="value">`,
   2132 }, {
   2133 	desc: "nested element defines default name space with existing prefix",
   2134 	toks: []Token{
   2135 		StartElement{Name{"", "foo"}, []Attr{
   2136 			{Name{"xmlns", "x"}, "space"},
   2137 		}},
   2138 		StartElement{Name{"space", "foo"}, []Attr{
   2139 			{Name{"", "xmlns"}, "space"},
   2140 			{Name{"space", "a"}, "value"},
   2141 		}},
   2142 	},
   2143 	want: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" xmlns="space" xmlns:space="space" space:a="value">`,
   2144 }, {
   2145 	desc: "nested element uses empty attribute name space when default ns defined",
   2146 	toks: []Token{
   2147 		StartElement{Name{"space", "foo"}, []Attr{
   2148 			{Name{"", "xmlns"}, "space"},
   2149 		}},
   2150 		StartElement{Name{"space", "foo"}, []Attr{
   2151 			{Name{"", "attr"}, "value"},
   2152 		}},
   2153 	},
   2154 	want: `<foo xmlns="space" xmlns="space"><foo xmlns="space" attr="value">`,
   2155 }, {
   2156 	desc: "redefine xmlns",
   2157 	toks: []Token{
   2158 		StartElement{Name{"", "foo"}, []Attr{
   2159 			{Name{"foo", "xmlns"}, "space"},
   2160 		}},
   2161 	},
   2162 	want: `<foo xmlns:foo="foo" foo:xmlns="space">`,
   2163 }, {
   2164 	desc: "xmlns with explicit name space #1",
   2165 	toks: []Token{
   2166 		StartElement{Name{"space", "foo"}, []Attr{
   2167 			{Name{"xml", "xmlns"}, "space"},
   2168 		}},
   2169 	},
   2170 	want: `<foo xmlns="space" xmlns:_xml="xml" _xml:xmlns="space">`,
   2171 }, {
   2172 	desc: "xmlns with explicit name space #2",
   2173 	toks: []Token{
   2174 		StartElement{Name{"space", "foo"}, []Attr{
   2175 			{Name{xmlURL, "xmlns"}, "space"},
   2176 		}},
   2177 	},
   2178 	want: `<foo xmlns="space" xml:xmlns="space">`,
   2179 }, {
   2180 	desc: "empty name space declaration is ignored",
   2181 	toks: []Token{
   2182 		StartElement{Name{"", "foo"}, []Attr{
   2183 			{Name{"xmlns", "foo"}, ""},
   2184 		}},
   2185 	},
   2186 	want: `<foo xmlns:_xmlns="xmlns" _xmlns:foo="">`,
   2187 }, {
   2188 	desc: "attribute with no name is ignored",
   2189 	toks: []Token{
   2190 		StartElement{Name{"", "foo"}, []Attr{
   2191 			{Name{"", ""}, "value"},
   2192 		}},
   2193 	},
   2194 	want: `<foo>`,
   2195 }, {
   2196 	desc: "namespace URL with non-valid name",
   2197 	toks: []Token{
   2198 		StartElement{Name{"/34", "foo"}, []Attr{
   2199 			{Name{"/34", "x"}, "value"},
   2200 		}},
   2201 	},
   2202 	want: `<foo xmlns="/34" xmlns:_="/34" _:x="value">`,
   2203 }, {
   2204 	desc: "nested element resets default namespace to empty",
   2205 	toks: []Token{
   2206 		StartElement{Name{"space", "foo"}, []Attr{
   2207 			{Name{"", "xmlns"}, "space"},
   2208 		}},
   2209 		StartElement{Name{"", "foo"}, []Attr{
   2210 			{Name{"", "xmlns"}, ""},
   2211 			{Name{"", "x"}, "value"},
   2212 			{Name{"space", "x"}, "value"},
   2213 		}},
   2214 	},
   2215 	want: `<foo xmlns="space" xmlns="space"><foo xmlns="" x="value" xmlns:space="space" space:x="value">`,
   2216 }, {
   2217 	desc: "nested element requires empty default name space",
   2218 	toks: []Token{
   2219 		StartElement{Name{"space", "foo"}, []Attr{
   2220 			{Name{"", "xmlns"}, "space"},
   2221 		}},
   2222 		StartElement{Name{"", "foo"}, nil},
   2223 	},
   2224 	want: `<foo xmlns="space" xmlns="space"><foo>`,
   2225 }, {
   2226 	desc: "attribute uses name space from xmlns",
   2227 	toks: []Token{
   2228 		StartElement{Name{"some/space", "foo"}, []Attr{
   2229 			{Name{"", "attr"}, "value"},
   2230 			{Name{"some/space", "other"}, "other value"},
   2231 		}},
   2232 	},
   2233 	want: `<foo xmlns="some/space" attr="value" xmlns:space="some/space" space:other="other value">`,
   2234 }, {
   2235 	desc: "default name space should not be used by attributes",
   2236 	toks: []Token{
   2237 		StartElement{Name{"space", "foo"}, []Attr{
   2238 			{Name{"", "xmlns"}, "space"},
   2239 			{Name{"xmlns", "bar"}, "space"},
   2240 			{Name{"space", "baz"}, "foo"},
   2241 		}},
   2242 		StartElement{Name{"space", "baz"}, nil},
   2243 		EndElement{Name{"space", "baz"}},
   2244 		EndElement{Name{"space", "foo"}},
   2245 	},
   2246 	want: `<foo xmlns="space" xmlns="space" xmlns:_xmlns="xmlns" _xmlns:bar="space" xmlns:space="space" space:baz="foo"><baz xmlns="space"></baz></foo>`,
   2247 }, {
   2248 	desc: "default name space not used by attributes, not explicitly defined",
   2249 	toks: []Token{
   2250 		StartElement{Name{"space", "foo"}, []Attr{
   2251 			{Name{"", "xmlns"}, "space"},
   2252 			{Name{"space", "baz"}, "foo"},
   2253 		}},
   2254 		StartElement{Name{"space", "baz"}, nil},
   2255 		EndElement{Name{"space", "baz"}},
   2256 		EndElement{Name{"space", "foo"}},
   2257 	},
   2258 	want: `<foo xmlns="space" xmlns="space" xmlns:space="space" space:baz="foo"><baz xmlns="space"></baz></foo>`,
   2259 }, {
   2260 	desc: "impossible xmlns declaration",
   2261 	toks: []Token{
   2262 		StartElement{Name{"", "foo"}, []Attr{
   2263 			{Name{"", "xmlns"}, "space"},
   2264 		}},
   2265 		StartElement{Name{"space", "bar"}, []Attr{
   2266 			{Name{"space", "attr"}, "value"},
   2267 		}},
   2268 	},
   2269 	want: `<foo xmlns="space"><bar xmlns="space" xmlns:space="space" space:attr="value">`,
   2270 }}
   2271 
   2272 func TestEncodeToken(t *testing.T) {
   2273 loop:
   2274 	for i, tt := range encodeTokenTests {
   2275 		var buf bytes.Buffer
   2276 		enc := NewEncoder(&buf)
   2277 		var err error
   2278 		for j, tok := range tt.toks {
   2279 			err = enc.EncodeToken(tok)
   2280 			if err != nil && j < len(tt.toks)-1 {
   2281 				t.Errorf("#%d %s token #%d: %v", i, tt.desc, j, err)
   2282 				continue loop
   2283 			}
   2284 		}
   2285 		errorf := func(f string, a ...interface{}) {
   2286 			t.Errorf("#%d %s token #%d:%s", i, tt.desc, len(tt.toks)-1, fmt.Sprintf(f, a...))
   2287 		}
   2288 		switch {
   2289 		case tt.err != "" && err == nil:
   2290 			errorf(" expected error; got none")
   2291 			continue
   2292 		case tt.err == "" && err != nil:
   2293 			errorf(" got error: %v", err)
   2294 			continue
   2295 		case tt.err != "" && err != nil && tt.err != err.Error():
   2296 			errorf(" error mismatch; got %v, want %v", err, tt.err)
   2297 			continue
   2298 		}
   2299 		if err := enc.Flush(); err != nil {
   2300 			errorf(" %v", err)
   2301 			continue
   2302 		}
   2303 		if got := buf.String(); got != tt.want {
   2304 			errorf("\ngot  %v\nwant %v", got, tt.want)
   2305 			continue
   2306 		}
   2307 	}
   2308 }
   2309 
   2310 func TestProcInstEncodeToken(t *testing.T) {
   2311 	var buf bytes.Buffer
   2312 	enc := NewEncoder(&buf)
   2313 
   2314 	if err := enc.EncodeToken(ProcInst{"xml", []byte("Instruction")}); err != nil {
   2315 		t.Fatalf("enc.EncodeToken: expected to be able to encode xml target ProcInst as first token, %s", err)
   2316 	}
   2317 
   2318 	if err := enc.EncodeToken(ProcInst{"Target", []byte("Instruction")}); err != nil {
   2319 		t.Fatalf("enc.EncodeToken: expected to be able to add non-xml target ProcInst")
   2320 	}
   2321 
   2322 	if err := enc.EncodeToken(ProcInst{"xml", []byte("Instruction")}); err == nil {
   2323 		t.Fatalf("enc.EncodeToken: expected to not be allowed to encode xml target ProcInst when not first token")
   2324 	}
   2325 }
   2326 
   2327 func TestDecodeEncode(t *testing.T) {
   2328 	var in, out bytes.Buffer
   2329 	in.WriteString(`<?xml version="1.0" encoding="UTF-8"?>
   2330 <?Target Instruction?>
   2331 <root>
   2332 </root>
   2333 `)
   2334 	dec := NewDecoder(&in)
   2335 	enc := NewEncoder(&out)
   2336 	for tok, err := dec.Token(); err == nil; tok, err = dec.Token() {
   2337 		err = enc.EncodeToken(tok)
   2338 		if err != nil {
   2339 			t.Fatalf("enc.EncodeToken: Unable to encode token (%#v), %v", tok, err)
   2340 		}
   2341 	}
   2342 }
   2343 
   2344 // Issue 9796. Used to fail with GORACE="halt_on_error=1" -race.
   2345 func TestRace9796(t *testing.T) {
   2346 	type A struct{}
   2347 	type B struct {
   2348 		C []A `xml:"X>Y"`
   2349 	}
   2350 	var wg sync.WaitGroup
   2351 	for i := 0; i < 2; i++ {
   2352 		wg.Add(1)
   2353 		go func() {
   2354 			Marshal(B{[]A{{}}})
   2355 			wg.Done()
   2356 		}()
   2357 	}
   2358 	wg.Wait()
   2359 }
   2360 
   2361 func TestIsValidDirective(t *testing.T) {
   2362 	testOK := []string{
   2363 		"<>",
   2364 		"< < > >",
   2365 		"<!DOCTYPE '<' '>' '>' <!--nothing-->>",
   2366 		"<!DOCTYPE doc [ <!ELEMENT doc ANY> <!ELEMENT doc ANY> ]>",
   2367 		"<!DOCTYPE doc [ <!ELEMENT doc \"ANY> '<' <!E\" LEMENT '>' doc ANY> ]>",
   2368 		"<!DOCTYPE doc <!-- just>>>> a < comment --> [ <!ITEM anything> ] >",
   2369 	}
   2370 	testKO := []string{
   2371 		"<",
   2372 		">",
   2373 		"<!--",
   2374 		"-->",
   2375 		"< > > < < >",
   2376 		"<!dummy <!-- > -->",
   2377 		"<!DOCTYPE doc '>",
   2378 		"<!DOCTYPE doc '>'",
   2379 		"<!DOCTYPE doc <!--comment>",
   2380 	}
   2381 	for _, s := range testOK {
   2382 		if !isValidDirective(Directive(s)) {
   2383 			t.Errorf("Directive %q is expected to be valid", s)
   2384 		}
   2385 	}
   2386 	for _, s := range testKO {
   2387 		if isValidDirective(Directive(s)) {
   2388 			t.Errorf("Directive %q is expected to be invalid", s)
   2389 		}
   2390 	}
   2391 }
   2392 
   2393 // Issue 11719. EncodeToken used to silently eat tokens with an invalid type.
   2394 func TestSimpleUseOfEncodeToken(t *testing.T) {
   2395 	var buf bytes.Buffer
   2396 	enc := NewEncoder(&buf)
   2397 	if err := enc.EncodeToken(&StartElement{Name: Name{"", "object1"}}); err == nil {
   2398 		t.Errorf("enc.EncodeToken: pointer type should be rejected")
   2399 	}
   2400 	if err := enc.EncodeToken(&EndElement{Name: Name{"", "object1"}}); err == nil {
   2401 		t.Errorf("enc.EncodeToken: pointer type should be rejected")
   2402 	}
   2403 	if err := enc.EncodeToken(StartElement{Name: Name{"", "object2"}}); err != nil {
   2404 		t.Errorf("enc.EncodeToken: StartElement %s", err)
   2405 	}
   2406 	if err := enc.EncodeToken(EndElement{Name: Name{"", "object2"}}); err != nil {
   2407 		t.Errorf("enc.EncodeToken: EndElement %s", err)
   2408 	}
   2409 	if err := enc.EncodeToken(Universe{}); err == nil {
   2410 		t.Errorf("enc.EncodeToken: invalid type not caught")
   2411 	}
   2412 	if err := enc.Flush(); err != nil {
   2413 		t.Errorf("enc.Flush: %s", err)
   2414 	}
   2415 	if buf.Len() == 0 {
   2416 		t.Errorf("enc.EncodeToken: empty buffer")
   2417 	}
   2418 	want := "<object2></object2>"
   2419 	if buf.String() != want {
   2420 		t.Errorf("enc.EncodeToken: expected %q; got %q", want, buf.String())
   2421 	}
   2422 }
   2423 
   2424 // Issue 16158. Decoder.unmarshalAttr ignores the return value of copyValue.
   2425 func TestIssue16158(t *testing.T) {
   2426 	const data = `<foo b="HELLOWORLD"></foo>`
   2427 	err := Unmarshal([]byte(data), &struct {
   2428 		B byte `xml:"b,attr,omitempty"`
   2429 	}{})
   2430 	if err == nil {
   2431 		t.Errorf("Unmarshal: expected error, got nil")
   2432 	}
   2433 }
   2434 
   2435 // Issue 20953. Crash on invalid XMLName attribute.
   2436 
   2437 type InvalidXMLName struct {
   2438 	XMLName Name `xml:"error"`
   2439 	Type    struct {
   2440 		XMLName Name `xml:"type,attr"`
   2441 	}
   2442 }
   2443 
   2444 func TestInvalidXMLName(t *testing.T) {
   2445 	var buf bytes.Buffer
   2446 	enc := NewEncoder(&buf)
   2447 	if err := enc.Encode(InvalidXMLName{}); err == nil {
   2448 		t.Error("unexpected success")
   2449 	} else if want := "invalid tag"; !strings.Contains(err.Error(), want) {
   2450 		t.Errorf("error %q does not contain %q", err, want)
   2451 	}
   2452 }
   2453