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 pointer to struct{} may be used to test for an element's presence.
    587 	{
    588 		Value:     &PresenceTest{new(struct{})},
    589 		ExpectXML: `<PresenceTest><Exists></Exists></PresenceTest>`,
    590 	},
    591 	{
    592 		Value:     &PresenceTest{},
    593 		ExpectXML: `<PresenceTest></PresenceTest>`,
    594 	},
    595 
    596 	// A []byte field is only nil if the element was not found.
    597 	{
    598 		Value:         &Data{},
    599 		ExpectXML:     `<Data></Data>`,
    600 		UnmarshalOnly: true,
    601 	},
    602 	{
    603 		Value:         &Data{Bytes: []byte{}, Custom: MyBytes{}, Attr: []byte{}},
    604 		ExpectXML:     `<Data Attr=""><Bytes></Bytes><Custom></Custom></Data>`,
    605 		UnmarshalOnly: true,
    606 	},
    607 
    608 	// Check that []byte works, including named []byte types.
    609 	{
    610 		Value:     &Data{Bytes: []byte("ab"), Custom: MyBytes("cd"), Attr: []byte{'v'}},
    611 		ExpectXML: `<Data Attr="v"><Bytes>ab</Bytes><Custom>cd</Custom></Data>`,
    612 	},
    613 
    614 	// Test innerxml
    615 	{
    616 		Value: &SecretAgent{
    617 			Handle:    "007",
    618 			Identity:  "James Bond",
    619 			Obfuscate: "<redacted/>",
    620 		},
    621 		ExpectXML:   `<agent handle="007"><Identity>James Bond</Identity><redacted/></agent>`,
    622 		MarshalOnly: true,
    623 	},
    624 	{
    625 		Value: &SecretAgent{
    626 			Handle:    "007",
    627 			Identity:  "James Bond",
    628 			Obfuscate: "<Identity>James Bond</Identity><redacted/>",
    629 		},
    630 		ExpectXML:     `<agent handle="007"><Identity>James Bond</Identity><redacted/></agent>`,
    631 		UnmarshalOnly: true,
    632 	},
    633 
    634 	// Test structs
    635 	{Value: &Port{Type: "ssl", Number: "443"}, ExpectXML: `<port type="ssl">443</port>`},
    636 	{Value: &Port{Number: "443"}, ExpectXML: `<port>443</port>`},
    637 	{Value: &Port{Type: "<unix>"}, ExpectXML: `<port type="&lt;unix&gt;"></port>`},
    638 	{Value: &Port{Number: "443", Comment: "https"}, ExpectXML: `<port><!--https-->443</port>`},
    639 	{Value: &Port{Number: "443", Comment: "add space-"}, ExpectXML: `<port><!--add space- -->443</port>`, MarshalOnly: true},
    640 	{Value: &Domain{Name: []byte("google.com&friends")}, ExpectXML: `<domain>google.com&amp;friends</domain>`},
    641 	{Value: &Domain{Name: []byte("google.com"), Comment: []byte(" &friends ")}, ExpectXML: `<domain>google.com<!-- &friends --></domain>`},
    642 	{Value: &Book{Title: "Pride & Prejudice"}, ExpectXML: `<book>Pride &amp; Prejudice</book>`},
    643 	{Value: &Event{Year: -3114}, ExpectXML: `<event>-3114</event>`},
    644 	{Value: &Movie{Length: 13440}, ExpectXML: `<movie>13440</movie>`},
    645 	{Value: &Pi{Approximation: 3.14159265}, ExpectXML: `<pi>3.1415927</pi>`},
    646 	{Value: &Universe{Visible: 9.3e13}, ExpectXML: `<universe>9.3e+13</universe>`},
    647 	{Value: &Particle{HasMass: true}, ExpectXML: `<particle>true</particle>`},
    648 	{Value: &Departure{When: ParseTime("2013-01-09T00:15:00-09:00")}, ExpectXML: `<departure>2013-01-09T00:15:00-09:00</departure>`},
    649 	{Value: atomValue, ExpectXML: atomXml},
    650 	{
    651 		Value: &Ship{
    652 			Name:  "Heart of Gold",
    653 			Pilot: "Computer",
    654 			Age:   1,
    655 			Drive: ImprobabilityDrive,
    656 			Passenger: []*Passenger{
    657 				{
    658 					Name:   []string{"Zaphod", "Beeblebrox"},
    659 					Weight: 7.25,
    660 				},
    661 				{
    662 					Name:   []string{"Trisha", "McMillen"},
    663 					Weight: 5.5,
    664 				},
    665 				{
    666 					Name:   []string{"Ford", "Prefect"},
    667 					Weight: 7,
    668 				},
    669 				{
    670 					Name:   []string{"Arthur", "Dent"},
    671 					Weight: 6.75,
    672 				},
    673 			},
    674 		},
    675 		ExpectXML: `<spaceship name="Heart of Gold" pilot="Computer">` +
    676 			`<drive>` + strconv.Itoa(int(ImprobabilityDrive)) + `</drive>` +
    677 			`<age>1</age>` +
    678 			`<passenger>` +
    679 			`<name>Zaphod</name>` +
    680 			`<name>Beeblebrox</name>` +
    681 			`<weight>7.25</weight>` +
    682 			`</passenger>` +
    683 			`<passenger>` +
    684 			`<name>Trisha</name>` +
    685 			`<name>McMillen</name>` +
    686 			`<weight>5.5</weight>` +
    687 			`</passenger>` +
    688 			`<passenger>` +
    689 			`<name>Ford</name>` +
    690 			`<name>Prefect</name>` +
    691 			`<weight>7</weight>` +
    692 			`</passenger>` +
    693 			`<passenger>` +
    694 			`<name>Arthur</name>` +
    695 			`<name>Dent</name>` +
    696 			`<weight>6.75</weight>` +
    697 			`</passenger>` +
    698 			`</spaceship>`,
    699 	},
    700 
    701 	// Test a>b
    702 	{
    703 		Value: &NestedItems{Items: nil, Item1: nil},
    704 		ExpectXML: `<result>` +
    705 			`<Items>` +
    706 			`</Items>` +
    707 			`</result>`,
    708 	},
    709 	{
    710 		Value: &NestedItems{Items: []string{}, Item1: []string{}},
    711 		ExpectXML: `<result>` +
    712 			`<Items>` +
    713 			`</Items>` +
    714 			`</result>`,
    715 		MarshalOnly: true,
    716 	},
    717 	{
    718 		Value: &NestedItems{Items: nil, Item1: []string{"A"}},
    719 		ExpectXML: `<result>` +
    720 			`<Items>` +
    721 			`<item1>A</item1>` +
    722 			`</Items>` +
    723 			`</result>`,
    724 	},
    725 	{
    726 		Value: &NestedItems{Items: []string{"A", "B"}, Item1: nil},
    727 		ExpectXML: `<result>` +
    728 			`<Items>` +
    729 			`<item>A</item>` +
    730 			`<item>B</item>` +
    731 			`</Items>` +
    732 			`</result>`,
    733 	},
    734 	{
    735 		Value: &NestedItems{Items: []string{"A", "B"}, Item1: []string{"C"}},
    736 		ExpectXML: `<result>` +
    737 			`<Items>` +
    738 			`<item>A</item>` +
    739 			`<item>B</item>` +
    740 			`<item1>C</item1>` +
    741 			`</Items>` +
    742 			`</result>`,
    743 	},
    744 	{
    745 		Value: &NestedOrder{Field1: "C", Field2: "B", Field3: "A"},
    746 		ExpectXML: `<result>` +
    747 			`<parent>` +
    748 			`<c>C</c>` +
    749 			`<b>B</b>` +
    750 			`<a>A</a>` +
    751 			`</parent>` +
    752 			`</result>`,
    753 	},
    754 	{
    755 		Value: &NilTest{A: "A", B: nil, C: "C"},
    756 		ExpectXML: `<NilTest>` +
    757 			`<parent1>` +
    758 			`<parent2><a>A</a></parent2>` +
    759 			`<parent2><c>C</c></parent2>` +
    760 			`</parent1>` +
    761 			`</NilTest>`,
    762 		MarshalOnly: true, // Uses interface{}
    763 	},
    764 	{
    765 		Value: &MixedNested{A: "A", B: "B", C: "C", D: "D"},
    766 		ExpectXML: `<result>` +
    767 			`<parent1><a>A</a></parent1>` +
    768 			`<b>B</b>` +
    769 			`<parent1>` +
    770 			`<parent2><c>C</c></parent2>` +
    771 			`<d>D</d>` +
    772 			`</parent1>` +
    773 			`</result>`,
    774 	},
    775 	{
    776 		Value:     &Service{Port: &Port{Number: "80"}},
    777 		ExpectXML: `<service><host><port>80</port></host></service>`,
    778 	},
    779 	{
    780 		Value:     &Service{},
    781 		ExpectXML: `<service></service>`,
    782 	},
    783 	{
    784 		Value: &Service{Port: &Port{Number: "80"}, Extra1: "A", Extra2: "B"},
    785 		ExpectXML: `<service>` +
    786 			`<host><port>80</port></host>` +
    787 			`<Extra1>A</Extra1>` +
    788 			`<host><extra2>B</extra2></host>` +
    789 			`</service>`,
    790 		MarshalOnly: true,
    791 	},
    792 	{
    793 		Value: &Service{Port: &Port{Number: "80"}, Extra2: "example"},
    794 		ExpectXML: `<service>` +
    795 			`<host><port>80</port></host>` +
    796 			`<host><extra2>example</extra2></host>` +
    797 			`</service>`,
    798 		MarshalOnly: true,
    799 	},
    800 	{
    801 		Value: &struct {
    802 			XMLName struct{} `xml:"space top"`
    803 			A       string   `xml:"x>a"`
    804 			B       string   `xml:"x>b"`
    805 			C       string   `xml:"space x>c"`
    806 			C1      string   `xml:"space1 x>c"`
    807 			D1      string   `xml:"space1 x>d"`
    808 		}{
    809 			A:  "a",
    810 			B:  "b",
    811 			C:  "c",
    812 			C1: "c1",
    813 			D1: "d1",
    814 		},
    815 		ExpectXML: `<top xmlns="space">` +
    816 			`<x><a>a</a><b>b</b><c xmlns="space">c</c>` +
    817 			`<c xmlns="space1">c1</c>` +
    818 			`<d xmlns="space1">d1</d>` +
    819 			`</x>` +
    820 			`</top>`,
    821 	},
    822 	{
    823 		Value: &struct {
    824 			XMLName Name
    825 			A       string `xml:"x>a"`
    826 			B       string `xml:"x>b"`
    827 			C       string `xml:"space x>c"`
    828 			C1      string `xml:"space1 x>c"`
    829 			D1      string `xml:"space1 x>d"`
    830 		}{
    831 			XMLName: Name{
    832 				Space: "space0",
    833 				Local: "top",
    834 			},
    835 			A:  "a",
    836 			B:  "b",
    837 			C:  "c",
    838 			C1: "c1",
    839 			D1: "d1",
    840 		},
    841 		ExpectXML: `<top xmlns="space0">` +
    842 			`<x><a>a</a><b>b</b>` +
    843 			`<c xmlns="space">c</c>` +
    844 			`<c xmlns="space1">c1</c>` +
    845 			`<d xmlns="space1">d1</d>` +
    846 			`</x>` +
    847 			`</top>`,
    848 	},
    849 	{
    850 		Value: &struct {
    851 			XMLName struct{} `xml:"top"`
    852 			B       string   `xml:"space x>b"`
    853 			B1      string   `xml:"space1 x>b"`
    854 		}{
    855 			B:  "b",
    856 			B1: "b1",
    857 		},
    858 		ExpectXML: `<top>` +
    859 			`<x><b xmlns="space">b</b>` +
    860 			`<b xmlns="space1">b1</b></x>` +
    861 			`</top>`,
    862 	},
    863 
    864 	// Test struct embedding
    865 	{
    866 		Value: &EmbedA{
    867 			EmbedC: EmbedC{
    868 				FieldA1: "", // Shadowed by A.A
    869 				FieldA2: "", // Shadowed by A.A
    870 				FieldB:  "A.C.B",
    871 				FieldC:  "A.C.C",
    872 			},
    873 			EmbedB: EmbedB{
    874 				FieldB: "A.B.B",
    875 				EmbedC: &EmbedC{
    876 					FieldA1: "A.B.C.A1",
    877 					FieldA2: "A.B.C.A2",
    878 					FieldB:  "", // Shadowed by A.B.B
    879 					FieldC:  "A.B.C.C",
    880 				},
    881 			},
    882 			FieldA: "A.A",
    883 			embedD: embedD{
    884 				FieldE: "A.D.E",
    885 			},
    886 		},
    887 		ExpectXML: `<EmbedA>` +
    888 			`<FieldB>A.C.B</FieldB>` +
    889 			`<FieldC>A.C.C</FieldC>` +
    890 			`<EmbedB>` +
    891 			`<FieldB>A.B.B</FieldB>` +
    892 			`<FieldA>` +
    893 			`<A1>A.B.C.A1</A1>` +
    894 			`<A2>A.B.C.A2</A2>` +
    895 			`</FieldA>` +
    896 			`<FieldC>A.B.C.C</FieldC>` +
    897 			`</EmbedB>` +
    898 			`<FieldA>A.A</FieldA>` +
    899 			`<FieldE>A.D.E</FieldE>` +
    900 			`</EmbedA>`,
    901 	},
    902 
    903 	// Test that name casing matters
    904 	{
    905 		Value:     &NameCasing{Xy: "mixed", XY: "upper", XyA: "mixedA", XYA: "upperA"},
    906 		ExpectXML: `<casing Xy="mixedA" XY="upperA"><Xy>mixed</Xy><XY>upper</XY></casing>`,
    907 	},
    908 
    909 	// Test the order in which the XML element name is chosen
    910 	{
    911 		Value: &NamePrecedence{
    912 			FromTag:     XMLNameWithoutTag{Value: "A"},
    913 			FromNameVal: XMLNameWithoutTag{XMLName: Name{Local: "InXMLName"}, Value: "B"},
    914 			FromNameTag: XMLNameWithTag{Value: "C"},
    915 			InFieldName: "D",
    916 		},
    917 		ExpectXML: `<Parent>` +
    918 			`<InTag>A</InTag>` +
    919 			`<InXMLName>B</InXMLName>` +
    920 			`<InXMLNameTag>C</InXMLNameTag>` +
    921 			`<InFieldName>D</InFieldName>` +
    922 			`</Parent>`,
    923 		MarshalOnly: true,
    924 	},
    925 	{
    926 		Value: &NamePrecedence{
    927 			XMLName:     Name{Local: "Parent"},
    928 			FromTag:     XMLNameWithoutTag{XMLName: Name{Local: "InTag"}, Value: "A"},
    929 			FromNameVal: XMLNameWithoutTag{XMLName: Name{Local: "FromNameVal"}, Value: "B"},
    930 			FromNameTag: XMLNameWithTag{XMLName: Name{Local: "InXMLNameTag"}, Value: "C"},
    931 			InFieldName: "D",
    932 		},
    933 		ExpectXML: `<Parent>` +
    934 			`<InTag>A</InTag>` +
    935 			`<FromNameVal>B</FromNameVal>` +
    936 			`<InXMLNameTag>C</InXMLNameTag>` +
    937 			`<InFieldName>D</InFieldName>` +
    938 			`</Parent>`,
    939 		UnmarshalOnly: true,
    940 	},
    941 
    942 	// xml.Name works in a plain field as well.
    943 	{
    944 		Value:     &NameInField{Name{Space: "ns", Local: "foo"}},
    945 		ExpectXML: `<NameInField><foo xmlns="ns"></foo></NameInField>`,
    946 	},
    947 	{
    948 		Value:         &NameInField{Name{Space: "ns", Local: "foo"}},
    949 		ExpectXML:     `<NameInField><foo xmlns="ns"><ignore></ignore></foo></NameInField>`,
    950 		UnmarshalOnly: true,
    951 	},
    952 
    953 	// Marshaling zero xml.Name uses the tag or field name.
    954 	{
    955 		Value:       &NameInField{},
    956 		ExpectXML:   `<NameInField><foo xmlns="ns"></foo></NameInField>`,
    957 		MarshalOnly: true,
    958 	},
    959 
    960 	// Test attributes
    961 	{
    962 		Value: &AttrTest{
    963 			Int:   8,
    964 			Named: 9,
    965 			Float: 23.5,
    966 			Uint8: 255,
    967 			Bool:  true,
    968 			Str:   "str",
    969 			Bytes: []byte("byt"),
    970 		},
    971 		ExpectXML: `<AttrTest Int="8" int="9" Float="23.5" Uint8="255"` +
    972 			` Bool="true" Str="str" Bytes="byt"></AttrTest>`,
    973 	},
    974 	{
    975 		Value: &AttrTest{Bytes: []byte{}},
    976 		ExpectXML: `<AttrTest Int="0" int="0" Float="0" Uint8="0"` +
    977 			` Bool="false" Str="" Bytes=""></AttrTest>`,
    978 	},
    979 	{
    980 		Value: &AttrsTest{
    981 			Attrs: []Attr{
    982 				{Name: Name{Local: "Answer"}, Value: "42"},
    983 				{Name: Name{Local: "Int"}, Value: "8"},
    984 				{Name: Name{Local: "int"}, Value: "9"},
    985 				{Name: Name{Local: "Float"}, Value: "23.5"},
    986 				{Name: Name{Local: "Uint8"}, Value: "255"},
    987 				{Name: Name{Local: "Bool"}, Value: "true"},
    988 				{Name: Name{Local: "Str"}, Value: "str"},
    989 				{Name: Name{Local: "Bytes"}, Value: "byt"},
    990 			},
    991 		},
    992 		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>`,
    993 		MarshalOnly: true,
    994 	},
    995 	{
    996 		Value: &AttrsTest{
    997 			Attrs: []Attr{
    998 				{Name: Name{Local: "Answer"}, Value: "42"},
    999 			},
   1000 			Int:   8,
   1001 			Named: 9,
   1002 			Float: 23.5,
   1003 			Uint8: 255,
   1004 			Bool:  true,
   1005 			Str:   "str",
   1006 			Bytes: []byte("byt"),
   1007 		},
   1008 		ExpectXML: `<AttrsTest Answer="42" Int="8" int="9" Float="23.5" Uint8="255" Bool="true" Str="str" Bytes="byt"></AttrsTest>`,
   1009 	},
   1010 	{
   1011 		Value: &AttrsTest{
   1012 			Attrs: []Attr{
   1013 				{Name: Name{Local: "Int"}, Value: "0"},
   1014 				{Name: Name{Local: "int"}, Value: "0"},
   1015 				{Name: Name{Local: "Float"}, Value: "0"},
   1016 				{Name: Name{Local: "Uint8"}, Value: "0"},
   1017 				{Name: Name{Local: "Bool"}, Value: "false"},
   1018 				{Name: Name{Local: "Str"}},
   1019 				{Name: Name{Local: "Bytes"}},
   1020 			},
   1021 			Bytes: []byte{},
   1022 		},
   1023 		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>`,
   1024 		MarshalOnly: true,
   1025 	},
   1026 	{
   1027 		Value: &OmitAttrTest{
   1028 			Int:   8,
   1029 			Named: 9,
   1030 			Float: 23.5,
   1031 			Uint8: 255,
   1032 			Bool:  true,
   1033 			Str:   "str",
   1034 			Bytes: []byte("byt"),
   1035 			PStr:  &empty,
   1036 		},
   1037 		ExpectXML: `<OmitAttrTest Int="8" int="9" Float="23.5" Uint8="255"` +
   1038 			` Bool="true" Str="str" Bytes="byt" PStr=""></OmitAttrTest>`,
   1039 	},
   1040 	{
   1041 		Value:     &OmitAttrTest{},
   1042 		ExpectXML: `<OmitAttrTest></OmitAttrTest>`,
   1043 	},
   1044 
   1045 	// pointer fields
   1046 	{
   1047 		Value:       &PointerFieldsTest{Name: &nameAttr, Age: &ageAttr, Contents: &contentsAttr},
   1048 		ExpectXML:   `<dummy name="Sarah" age="12">lorem ipsum</dummy>`,
   1049 		MarshalOnly: true,
   1050 	},
   1051 
   1052 	// empty chardata pointer field
   1053 	{
   1054 		Value:       &ChardataEmptyTest{},
   1055 		ExpectXML:   `<test></test>`,
   1056 		MarshalOnly: true,
   1057 	},
   1058 
   1059 	// omitempty on fields
   1060 	{
   1061 		Value: &OmitFieldTest{
   1062 			Int:   8,
   1063 			Named: 9,
   1064 			Float: 23.5,
   1065 			Uint8: 255,
   1066 			Bool:  true,
   1067 			Str:   "str",
   1068 			Bytes: []byte("byt"),
   1069 			PStr:  &empty,
   1070 			Ptr:   &PresenceTest{},
   1071 		},
   1072 		ExpectXML: `<OmitFieldTest>` +
   1073 			`<Int>8</Int>` +
   1074 			`<int>9</int>` +
   1075 			`<Float>23.5</Float>` +
   1076 			`<Uint8>255</Uint8>` +
   1077 			`<Bool>true</Bool>` +
   1078 			`<Str>str</Str>` +
   1079 			`<Bytes>byt</Bytes>` +
   1080 			`<PStr></PStr>` +
   1081 			`<Ptr></Ptr>` +
   1082 			`</OmitFieldTest>`,
   1083 	},
   1084 	{
   1085 		Value:     &OmitFieldTest{},
   1086 		ExpectXML: `<OmitFieldTest></OmitFieldTest>`,
   1087 	},
   1088 
   1089 	// Test ",any"
   1090 	{
   1091 		ExpectXML: `<a><nested><value>known</value></nested><other><sub>unknown</sub></other></a>`,
   1092 		Value: &AnyTest{
   1093 			Nested: "known",
   1094 			AnyField: AnyHolder{
   1095 				XMLName: Name{Local: "other"},
   1096 				XML:     "<sub>unknown</sub>",
   1097 			},
   1098 		},
   1099 	},
   1100 	{
   1101 		Value: &AnyTest{Nested: "known",
   1102 			AnyField: AnyHolder{
   1103 				XML:     "<unknown/>",
   1104 				XMLName: Name{Local: "AnyField"},
   1105 			},
   1106 		},
   1107 		ExpectXML: `<a><nested><value>known</value></nested><AnyField><unknown/></AnyField></a>`,
   1108 	},
   1109 	{
   1110 		ExpectXML: `<a><nested><value>b</value></nested></a>`,
   1111 		Value: &AnyOmitTest{
   1112 			Nested: "b",
   1113 		},
   1114 	},
   1115 	{
   1116 		ExpectXML: `<a><nested><value>b</value></nested><c><d>e</d></c><g xmlns="f"><h>i</h></g></a>`,
   1117 		Value: &AnySliceTest{
   1118 			Nested: "b",
   1119 			AnyField: []AnyHolder{
   1120 				{
   1121 					XMLName: Name{Local: "c"},
   1122 					XML:     "<d>e</d>",
   1123 				},
   1124 				{
   1125 					XMLName: Name{Space: "f", Local: "g"},
   1126 					XML:     "<h>i</h>",
   1127 				},
   1128 			},
   1129 		},
   1130 	},
   1131 	{
   1132 		ExpectXML: `<a><nested><value>b</value></nested></a>`,
   1133 		Value: &AnySliceTest{
   1134 			Nested: "b",
   1135 		},
   1136 	},
   1137 
   1138 	// Test recursive types.
   1139 	{
   1140 		Value: &RecurseA{
   1141 			A: "a1",
   1142 			B: &RecurseB{
   1143 				A: &RecurseA{"a2", nil},
   1144 				B: "b1",
   1145 			},
   1146 		},
   1147 		ExpectXML: `<RecurseA><A>a1</A><B><A><A>a2</A></A><B>b1</B></B></RecurseA>`,
   1148 	},
   1149 
   1150 	// Test ignoring fields via "-" tag
   1151 	{
   1152 		ExpectXML: `<IgnoreTest></IgnoreTest>`,
   1153 		Value:     &IgnoreTest{},
   1154 	},
   1155 	{
   1156 		ExpectXML:   `<IgnoreTest></IgnoreTest>`,
   1157 		Value:       &IgnoreTest{PublicSecret: "can't tell"},
   1158 		MarshalOnly: true,
   1159 	},
   1160 	{
   1161 		ExpectXML:     `<IgnoreTest><PublicSecret>ignore me</PublicSecret></IgnoreTest>`,
   1162 		Value:         &IgnoreTest{},
   1163 		UnmarshalOnly: true,
   1164 	},
   1165 
   1166 	// Test escaping.
   1167 	{
   1168 		ExpectXML: `<a><nested><value>dquote: &#34;; squote: &#39;; ampersand: &amp;; less: &lt;; greater: &gt;;</value></nested><empty></empty></a>`,
   1169 		Value: &AnyTest{
   1170 			Nested:   `dquote: "; squote: '; ampersand: &; less: <; greater: >;`,
   1171 			AnyField: AnyHolder{XMLName: Name{Local: "empty"}},
   1172 		},
   1173 	},
   1174 	{
   1175 		ExpectXML: `<a><nested><value>newline: &#xA;; cr: &#xD;; tab: &#x9;;</value></nested><AnyField></AnyField></a>`,
   1176 		Value: &AnyTest{
   1177 			Nested:   "newline: \n; cr: \r; tab: \t;",
   1178 			AnyField: AnyHolder{XMLName: Name{Local: "AnyField"}},
   1179 		},
   1180 	},
   1181 	{
   1182 		ExpectXML: "<a><nested><value>1\r2\r\n3\n\r4\n5</value></nested></a>",
   1183 		Value: &AnyTest{
   1184 			Nested: "1\n2\n3\n\n4\n5",
   1185 		},
   1186 		UnmarshalOnly: true,
   1187 	},
   1188 	{
   1189 		ExpectXML: `<EmbedInt><MyInt>42</MyInt></EmbedInt>`,
   1190 		Value: &EmbedInt{
   1191 			MyInt: 42,
   1192 		},
   1193 	},
   1194 	// Test outputting CDATA-wrapped text.
   1195 	{
   1196 		ExpectXML: `<CDataTest></CDataTest>`,
   1197 		Value:     &CDataTest{},
   1198 	},
   1199 	{
   1200 		ExpectXML: `<CDataTest><![CDATA[http://example.com/tests/1?foo=1&bar=baz]]></CDataTest>`,
   1201 		Value: &CDataTest{
   1202 			Chardata: "http://example.com/tests/1?foo=1&bar=baz",
   1203 		},
   1204 	},
   1205 	{
   1206 		ExpectXML: `<CDataTest><![CDATA[Literal <![CDATA[Nested]]]]><![CDATA[>!]]></CDataTest>`,
   1207 		Value: &CDataTest{
   1208 			Chardata: "Literal <![CDATA[Nested]]>!",
   1209 		},
   1210 	},
   1211 	{
   1212 		ExpectXML: `<CDataTest><![CDATA[<![CDATA[Nested]]]]><![CDATA[> Literal!]]></CDataTest>`,
   1213 		Value: &CDataTest{
   1214 			Chardata: "<![CDATA[Nested]]> Literal!",
   1215 		},
   1216 	},
   1217 	{
   1218 		ExpectXML: `<CDataTest><![CDATA[<![CDATA[Nested]]]]><![CDATA[> Literal! <![CDATA[Nested]]]]><![CDATA[> Literal!]]></CDataTest>`,
   1219 		Value: &CDataTest{
   1220 			Chardata: "<![CDATA[Nested]]> Literal! <![CDATA[Nested]]> Literal!",
   1221 		},
   1222 	},
   1223 	{
   1224 		ExpectXML: `<CDataTest><![CDATA[<![CDATA[<![CDATA[Nested]]]]><![CDATA[>]]]]><![CDATA[>]]></CDataTest>`,
   1225 		Value: &CDataTest{
   1226 			Chardata: "<![CDATA[<![CDATA[Nested]]>]]>",
   1227 		},
   1228 	},
   1229 
   1230 	// Test omitempty with parent chain; see golang.org/issue/4168.
   1231 	{
   1232 		ExpectXML: `<Strings><A></A></Strings>`,
   1233 		Value:     &Strings{},
   1234 	},
   1235 	// Custom marshalers.
   1236 	{
   1237 		ExpectXML: `<MyMarshalerTest>hello world</MyMarshalerTest>`,
   1238 		Value:     &MyMarshalerTest{},
   1239 	},
   1240 	{
   1241 		ExpectXML: `<MarshalerStruct Foo="hello world"></MarshalerStruct>`,
   1242 		Value:     &MarshalerStruct{},
   1243 	},
   1244 	{
   1245 		ExpectXML: `<outer xmlns="testns" int="10"></outer>`,
   1246 		Value:     &OuterStruct{IntAttr: 10},
   1247 	},
   1248 	{
   1249 		ExpectXML: `<test xmlns="outerns" int="10"></test>`,
   1250 		Value:     &OuterNamedStruct{XMLName: Name{Space: "outerns", Local: "test"}, IntAttr: 10},
   1251 	},
   1252 	{
   1253 		ExpectXML: `<test xmlns="outerns" int="10"></test>`,
   1254 		Value:     &OuterNamedOrderedStruct{XMLName: Name{Space: "outerns", Local: "test"}, IntAttr: 10},
   1255 	},
   1256 	{
   1257 		ExpectXML: `<outer xmlns="testns" int="10"></outer>`,
   1258 		Value:     &OuterOuterStruct{OuterStruct{IntAttr: 10}},
   1259 	},
   1260 	{
   1261 		ExpectXML: `<NestedAndChardata><A><B></B><B></B></A>test</NestedAndChardata>`,
   1262 		Value:     &NestedAndChardata{AB: make([]string, 2), Chardata: "test"},
   1263 	},
   1264 	{
   1265 		ExpectXML: `<NestedAndComment><A><B></B><B></B></A><!--test--></NestedAndComment>`,
   1266 		Value:     &NestedAndComment{AB: make([]string, 2), Comment: "test"},
   1267 	},
   1268 	{
   1269 		ExpectXML: `<NestedAndCData><A><B></B><B></B></A><![CDATA[test]]></NestedAndCData>`,
   1270 		Value:     &NestedAndCData{AB: make([]string, 2), CDATA: "test"},
   1271 	},
   1272 	// Test pointer indirection in various kinds of fields.
   1273 	// https://golang.org/issue/19063
   1274 	{
   1275 		ExpectXML:   `<IndirComment><T1></T1><!--hi--><T2></T2></IndirComment>`,
   1276 		Value:       &IndirComment{Comment: stringptr("hi")},
   1277 		MarshalOnly: true,
   1278 	},
   1279 	{
   1280 		ExpectXML:   `<IndirComment><T1></T1><T2></T2></IndirComment>`,
   1281 		Value:       &IndirComment{Comment: stringptr("")},
   1282 		MarshalOnly: true,
   1283 	},
   1284 	{
   1285 		ExpectXML:    `<IndirComment><T1></T1><T2></T2></IndirComment>`,
   1286 		Value:        &IndirComment{Comment: nil},
   1287 		MarshalError: "xml: bad type for comment field of xml.IndirComment",
   1288 	},
   1289 	{
   1290 		ExpectXML:     `<IndirComment><T1></T1><!--hi--><T2></T2></IndirComment>`,
   1291 		Value:         &IndirComment{Comment: nil},
   1292 		UnmarshalOnly: true,
   1293 	},
   1294 	{
   1295 		ExpectXML:   `<IfaceComment><T1></T1><!--hi--><T2></T2></IfaceComment>`,
   1296 		Value:       &IfaceComment{Comment: "hi"},
   1297 		MarshalOnly: true,
   1298 	},
   1299 	{
   1300 		ExpectXML:     `<IfaceComment><T1></T1><!--hi--><T2></T2></IfaceComment>`,
   1301 		Value:         &IfaceComment{Comment: nil},
   1302 		UnmarshalOnly: true,
   1303 	},
   1304 	{
   1305 		ExpectXML:    `<IfaceComment><T1></T1><T2></T2></IfaceComment>`,
   1306 		Value:        &IfaceComment{Comment: nil},
   1307 		MarshalError: "xml: bad type for comment field of xml.IfaceComment",
   1308 	},
   1309 	{
   1310 		ExpectXML:     `<IfaceComment><T1></T1><T2></T2></IfaceComment>`,
   1311 		Value:         &IfaceComment{Comment: nil},
   1312 		UnmarshalOnly: true,
   1313 	},
   1314 	{
   1315 		ExpectXML: `<DirectComment><T1></T1><!--hi--><T2></T2></DirectComment>`,
   1316 		Value:     &DirectComment{Comment: string("hi")},
   1317 	},
   1318 	{
   1319 		ExpectXML: `<DirectComment><T1></T1><T2></T2></DirectComment>`,
   1320 		Value:     &DirectComment{Comment: string("")},
   1321 	},
   1322 	{
   1323 		ExpectXML: `<IndirChardata><T1></T1>hi<T2></T2></IndirChardata>`,
   1324 		Value:     &IndirChardata{Chardata: stringptr("hi")},
   1325 	},
   1326 	{
   1327 		ExpectXML:     `<IndirChardata><T1></T1><![CDATA[hi]]><T2></T2></IndirChardata>`,
   1328 		Value:         &IndirChardata{Chardata: stringptr("hi")},
   1329 		UnmarshalOnly: true, // marshals without CDATA
   1330 	},
   1331 	{
   1332 		ExpectXML: `<IndirChardata><T1></T1><T2></T2></IndirChardata>`,
   1333 		Value:     &IndirChardata{Chardata: stringptr("")},
   1334 	},
   1335 	{
   1336 		ExpectXML:   `<IndirChardata><T1></T1><T2></T2></IndirChardata>`,
   1337 		Value:       &IndirChardata{Chardata: nil},
   1338 		MarshalOnly: true, // unmarshal leaves Chardata=stringptr("")
   1339 	},
   1340 	{
   1341 		ExpectXML:      `<IfaceChardata><T1></T1>hi<T2></T2></IfaceChardata>`,
   1342 		Value:          &IfaceChardata{Chardata: string("hi")},
   1343 		UnmarshalError: "cannot unmarshal into interface {}",
   1344 	},
   1345 	{
   1346 		ExpectXML:      `<IfaceChardata><T1></T1><![CDATA[hi]]><T2></T2></IfaceChardata>`,
   1347 		Value:          &IfaceChardata{Chardata: string("hi")},
   1348 		UnmarshalOnly:  true, // marshals without CDATA
   1349 		UnmarshalError: "cannot unmarshal into interface {}",
   1350 	},
   1351 	{
   1352 		ExpectXML:      `<IfaceChardata><T1></T1><T2></T2></IfaceChardata>`,
   1353 		Value:          &IfaceChardata{Chardata: string("")},
   1354 		UnmarshalError: "cannot unmarshal into interface {}",
   1355 	},
   1356 	{
   1357 		ExpectXML:      `<IfaceChardata><T1></T1><T2></T2></IfaceChardata>`,
   1358 		Value:          &IfaceChardata{Chardata: nil},
   1359 		UnmarshalError: "cannot unmarshal into interface {}",
   1360 	},
   1361 	{
   1362 		ExpectXML: `<DirectChardata><T1></T1>hi<T2></T2></DirectChardata>`,
   1363 		Value:     &DirectChardata{Chardata: string("hi")},
   1364 	},
   1365 	{
   1366 		ExpectXML:     `<DirectChardata><T1></T1><![CDATA[hi]]><T2></T2></DirectChardata>`,
   1367 		Value:         &DirectChardata{Chardata: string("hi")},
   1368 		UnmarshalOnly: true, // marshals without CDATA
   1369 	},
   1370 	{
   1371 		ExpectXML: `<DirectChardata><T1></T1><T2></T2></DirectChardata>`,
   1372 		Value:     &DirectChardata{Chardata: string("")},
   1373 	},
   1374 	{
   1375 		ExpectXML: `<IndirCDATA><T1></T1><![CDATA[hi]]><T2></T2></IndirCDATA>`,
   1376 		Value:     &IndirCDATA{CDATA: stringptr("hi")},
   1377 	},
   1378 	{
   1379 		ExpectXML:     `<IndirCDATA><T1></T1>hi<T2></T2></IndirCDATA>`,
   1380 		Value:         &IndirCDATA{CDATA: stringptr("hi")},
   1381 		UnmarshalOnly: true, // marshals with CDATA
   1382 	},
   1383 	{
   1384 		ExpectXML: `<IndirCDATA><T1></T1><T2></T2></IndirCDATA>`,
   1385 		Value:     &IndirCDATA{CDATA: stringptr("")},
   1386 	},
   1387 	{
   1388 		ExpectXML:   `<IndirCDATA><T1></T1><T2></T2></IndirCDATA>`,
   1389 		Value:       &IndirCDATA{CDATA: nil},
   1390 		MarshalOnly: true, // unmarshal leaves CDATA=stringptr("")
   1391 	},
   1392 	{
   1393 		ExpectXML:      `<IfaceCDATA><T1></T1><![CDATA[hi]]><T2></T2></IfaceCDATA>`,
   1394 		Value:          &IfaceCDATA{CDATA: string("hi")},
   1395 		UnmarshalError: "cannot unmarshal into interface {}",
   1396 	},
   1397 	{
   1398 		ExpectXML:      `<IfaceCDATA><T1></T1>hi<T2></T2></IfaceCDATA>`,
   1399 		Value:          &IfaceCDATA{CDATA: string("hi")},
   1400 		UnmarshalOnly:  true, // marshals with CDATA
   1401 		UnmarshalError: "cannot unmarshal into interface {}",
   1402 	},
   1403 	{
   1404 		ExpectXML:      `<IfaceCDATA><T1></T1><T2></T2></IfaceCDATA>`,
   1405 		Value:          &IfaceCDATA{CDATA: string("")},
   1406 		UnmarshalError: "cannot unmarshal into interface {}",
   1407 	},
   1408 	{
   1409 		ExpectXML:      `<IfaceCDATA><T1></T1><T2></T2></IfaceCDATA>`,
   1410 		Value:          &IfaceCDATA{CDATA: nil},
   1411 		UnmarshalError: "cannot unmarshal into interface {}",
   1412 	},
   1413 	{
   1414 		ExpectXML: `<DirectCDATA><T1></T1><![CDATA[hi]]><T2></T2></DirectCDATA>`,
   1415 		Value:     &DirectCDATA{CDATA: string("hi")},
   1416 	},
   1417 	{
   1418 		ExpectXML:     `<DirectCDATA><T1></T1>hi<T2></T2></DirectCDATA>`,
   1419 		Value:         &DirectCDATA{CDATA: string("hi")},
   1420 		UnmarshalOnly: true, // marshals with CDATA
   1421 	},
   1422 	{
   1423 		ExpectXML: `<DirectCDATA><T1></T1><T2></T2></DirectCDATA>`,
   1424 		Value:     &DirectCDATA{CDATA: string("")},
   1425 	},
   1426 	{
   1427 		ExpectXML:   `<IndirInnerXML><T1></T1><hi/><T2></T2></IndirInnerXML>`,
   1428 		Value:       &IndirInnerXML{InnerXML: stringptr("<hi/>")},
   1429 		MarshalOnly: true,
   1430 	},
   1431 	{
   1432 		ExpectXML:   `<IndirInnerXML><T1></T1><T2></T2></IndirInnerXML>`,
   1433 		Value:       &IndirInnerXML{InnerXML: stringptr("")},
   1434 		MarshalOnly: true,
   1435 	},
   1436 	{
   1437 		ExpectXML: `<IndirInnerXML><T1></T1><T2></T2></IndirInnerXML>`,
   1438 		Value:     &IndirInnerXML{InnerXML: nil},
   1439 	},
   1440 	{
   1441 		ExpectXML:     `<IndirInnerXML><T1></T1><hi/><T2></T2></IndirInnerXML>`,
   1442 		Value:         &IndirInnerXML{InnerXML: nil},
   1443 		UnmarshalOnly: true,
   1444 	},
   1445 	{
   1446 		ExpectXML:   `<IfaceInnerXML><T1></T1><hi/><T2></T2></IfaceInnerXML>`,
   1447 		Value:       &IfaceInnerXML{InnerXML: "<hi/>"},
   1448 		MarshalOnly: true,
   1449 	},
   1450 	{
   1451 		ExpectXML:     `<IfaceInnerXML><T1></T1><hi/><T2></T2></IfaceInnerXML>`,
   1452 		Value:         &IfaceInnerXML{InnerXML: nil},
   1453 		UnmarshalOnly: true,
   1454 	},
   1455 	{
   1456 		ExpectXML: `<IfaceInnerXML><T1></T1><T2></T2></IfaceInnerXML>`,
   1457 		Value:     &IfaceInnerXML{InnerXML: nil},
   1458 	},
   1459 	{
   1460 		ExpectXML:     `<IfaceInnerXML><T1></T1><T2></T2></IfaceInnerXML>`,
   1461 		Value:         &IfaceInnerXML{InnerXML: nil},
   1462 		UnmarshalOnly: true,
   1463 	},
   1464 	{
   1465 		ExpectXML:   `<DirectInnerXML><T1></T1><hi/><T2></T2></DirectInnerXML>`,
   1466 		Value:       &DirectInnerXML{InnerXML: string("<hi/>")},
   1467 		MarshalOnly: true,
   1468 	},
   1469 	{
   1470 		ExpectXML:     `<DirectInnerXML><T1></T1><hi/><T2></T2></DirectInnerXML>`,
   1471 		Value:         &DirectInnerXML{InnerXML: string("<T1></T1><hi/><T2></T2>")},
   1472 		UnmarshalOnly: true,
   1473 	},
   1474 	{
   1475 		ExpectXML:   `<DirectInnerXML><T1></T1><T2></T2></DirectInnerXML>`,
   1476 		Value:       &DirectInnerXML{InnerXML: string("")},
   1477 		MarshalOnly: true,
   1478 	},
   1479 	{
   1480 		ExpectXML:     `<DirectInnerXML><T1></T1><T2></T2></DirectInnerXML>`,
   1481 		Value:         &DirectInnerXML{InnerXML: string("<T1></T1><T2></T2>")},
   1482 		UnmarshalOnly: true,
   1483 	},
   1484 	{
   1485 		ExpectXML: `<IndirElement><T1></T1><Element>hi</Element><T2></T2></IndirElement>`,
   1486 		Value:     &IndirElement{Element: stringptr("hi")},
   1487 	},
   1488 	{
   1489 		ExpectXML: `<IndirElement><T1></T1><Element></Element><T2></T2></IndirElement>`,
   1490 		Value:     &IndirElement{Element: stringptr("")},
   1491 	},
   1492 	{
   1493 		ExpectXML: `<IndirElement><T1></T1><T2></T2></IndirElement>`,
   1494 		Value:     &IndirElement{Element: nil},
   1495 	},
   1496 	{
   1497 		ExpectXML:   `<IfaceElement><T1></T1><Element>hi</Element><T2></T2></IfaceElement>`,
   1498 		Value:       &IfaceElement{Element: "hi"},
   1499 		MarshalOnly: true,
   1500 	},
   1501 	{
   1502 		ExpectXML:     `<IfaceElement><T1></T1><Element>hi</Element><T2></T2></IfaceElement>`,
   1503 		Value:         &IfaceElement{Element: nil},
   1504 		UnmarshalOnly: true,
   1505 	},
   1506 	{
   1507 		ExpectXML: `<IfaceElement><T1></T1><T2></T2></IfaceElement>`,
   1508 		Value:     &IfaceElement{Element: nil},
   1509 	},
   1510 	{
   1511 		ExpectXML:     `<IfaceElement><T1></T1><T2></T2></IfaceElement>`,
   1512 		Value:         &IfaceElement{Element: nil},
   1513 		UnmarshalOnly: true,
   1514 	},
   1515 	{
   1516 		ExpectXML: `<DirectElement><T1></T1><Element>hi</Element><T2></T2></DirectElement>`,
   1517 		Value:     &DirectElement{Element: string("hi")},
   1518 	},
   1519 	{
   1520 		ExpectXML: `<DirectElement><T1></T1><Element></Element><T2></T2></DirectElement>`,
   1521 		Value:     &DirectElement{Element: string("")},
   1522 	},
   1523 	{
   1524 		ExpectXML: `<IndirOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></IndirOmitEmpty>`,
   1525 		Value:     &IndirOmitEmpty{OmitEmpty: stringptr("hi")},
   1526 	},
   1527 	{
   1528 		// Note: Changed in Go 1.8 to include <OmitEmpty> element (because x.OmitEmpty != nil).
   1529 		ExpectXML:   `<IndirOmitEmpty><T1></T1><OmitEmpty></OmitEmpty><T2></T2></IndirOmitEmpty>`,
   1530 		Value:       &IndirOmitEmpty{OmitEmpty: stringptr("")},
   1531 		MarshalOnly: true,
   1532 	},
   1533 	{
   1534 		ExpectXML:     `<IndirOmitEmpty><T1></T1><OmitEmpty></OmitEmpty><T2></T2></IndirOmitEmpty>`,
   1535 		Value:         &IndirOmitEmpty{OmitEmpty: stringptr("")},
   1536 		UnmarshalOnly: true,
   1537 	},
   1538 	{
   1539 		ExpectXML: `<IndirOmitEmpty><T1></T1><T2></T2></IndirOmitEmpty>`,
   1540 		Value:     &IndirOmitEmpty{OmitEmpty: nil},
   1541 	},
   1542 	{
   1543 		ExpectXML:   `<IfaceOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></IfaceOmitEmpty>`,
   1544 		Value:       &IfaceOmitEmpty{OmitEmpty: "hi"},
   1545 		MarshalOnly: true,
   1546 	},
   1547 	{
   1548 		ExpectXML:     `<IfaceOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></IfaceOmitEmpty>`,
   1549 		Value:         &IfaceOmitEmpty{OmitEmpty: nil},
   1550 		UnmarshalOnly: true,
   1551 	},
   1552 	{
   1553 		ExpectXML: `<IfaceOmitEmpty><T1></T1><T2></T2></IfaceOmitEmpty>`,
   1554 		Value:     &IfaceOmitEmpty{OmitEmpty: nil},
   1555 	},
   1556 	{
   1557 		ExpectXML:     `<IfaceOmitEmpty><T1></T1><T2></T2></IfaceOmitEmpty>`,
   1558 		Value:         &IfaceOmitEmpty{OmitEmpty: nil},
   1559 		UnmarshalOnly: true,
   1560 	},
   1561 	{
   1562 		ExpectXML: `<DirectOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></DirectOmitEmpty>`,
   1563 		Value:     &DirectOmitEmpty{OmitEmpty: string("hi")},
   1564 	},
   1565 	{
   1566 		ExpectXML: `<DirectOmitEmpty><T1></T1><T2></T2></DirectOmitEmpty>`,
   1567 		Value:     &DirectOmitEmpty{OmitEmpty: string("")},
   1568 	},
   1569 	{
   1570 		ExpectXML: `<IndirAny><T1></T1><Any>hi</Any><T2></T2></IndirAny>`,
   1571 		Value:     &IndirAny{Any: stringptr("hi")},
   1572 	},
   1573 	{
   1574 		ExpectXML: `<IndirAny><T1></T1><Any></Any><T2></T2></IndirAny>`,
   1575 		Value:     &IndirAny{Any: stringptr("")},
   1576 	},
   1577 	{
   1578 		ExpectXML: `<IndirAny><T1></T1><T2></T2></IndirAny>`,
   1579 		Value:     &IndirAny{Any: nil},
   1580 	},
   1581 	{
   1582 		ExpectXML:   `<IfaceAny><T1></T1><Any>hi</Any><T2></T2></IfaceAny>`,
   1583 		Value:       &IfaceAny{Any: "hi"},
   1584 		MarshalOnly: true,
   1585 	},
   1586 	{
   1587 		ExpectXML:     `<IfaceAny><T1></T1><Any>hi</Any><T2></T2></IfaceAny>`,
   1588 		Value:         &IfaceAny{Any: nil},
   1589 		UnmarshalOnly: true,
   1590 	},
   1591 	{
   1592 		ExpectXML: `<IfaceAny><T1></T1><T2></T2></IfaceAny>`,
   1593 		Value:     &IfaceAny{Any: nil},
   1594 	},
   1595 	{
   1596 		ExpectXML:     `<IfaceAny><T1></T1><T2></T2></IfaceAny>`,
   1597 		Value:         &IfaceAny{Any: nil},
   1598 		UnmarshalOnly: true,
   1599 	},
   1600 	{
   1601 		ExpectXML: `<DirectAny><T1></T1><Any>hi</Any><T2></T2></DirectAny>`,
   1602 		Value:     &DirectAny{Any: string("hi")},
   1603 	},
   1604 	{
   1605 		ExpectXML: `<DirectAny><T1></T1><Any></Any><T2></T2></DirectAny>`,
   1606 		Value:     &DirectAny{Any: string("")},
   1607 	},
   1608 	{
   1609 		ExpectXML:     `<IndirFoo><T1></T1><Foo>hi</Foo><T2></T2></IndirFoo>`,
   1610 		Value:         &IndirAny{Any: stringptr("hi")},
   1611 		UnmarshalOnly: true,
   1612 	},
   1613 	{
   1614 		ExpectXML:     `<IndirFoo><T1></T1><Foo></Foo><T2></T2></IndirFoo>`,
   1615 		Value:         &IndirAny{Any: stringptr("")},
   1616 		UnmarshalOnly: true,
   1617 	},
   1618 	{
   1619 		ExpectXML:     `<IndirFoo><T1></T1><T2></T2></IndirFoo>`,
   1620 		Value:         &IndirAny{Any: nil},
   1621 		UnmarshalOnly: true,
   1622 	},
   1623 	{
   1624 		ExpectXML:     `<IfaceFoo><T1></T1><Foo>hi</Foo><T2></T2></IfaceFoo>`,
   1625 		Value:         &IfaceAny{Any: nil},
   1626 		UnmarshalOnly: true,
   1627 	},
   1628 	{
   1629 		ExpectXML:     `<IfaceFoo><T1></T1><T2></T2></IfaceFoo>`,
   1630 		Value:         &IfaceAny{Any: nil},
   1631 		UnmarshalOnly: true,
   1632 	},
   1633 	{
   1634 		ExpectXML:     `<IfaceFoo><T1></T1><T2></T2></IfaceFoo>`,
   1635 		Value:         &IfaceAny{Any: nil},
   1636 		UnmarshalOnly: true,
   1637 	},
   1638 	{
   1639 		ExpectXML:     `<DirectFoo><T1></T1><Foo>hi</Foo><T2></T2></DirectFoo>`,
   1640 		Value:         &DirectAny{Any: string("hi")},
   1641 		UnmarshalOnly: true,
   1642 	},
   1643 	{
   1644 		ExpectXML:     `<DirectFoo><T1></T1><Foo></Foo><T2></T2></DirectFoo>`,
   1645 		Value:         &DirectAny{Any: string("")},
   1646 		UnmarshalOnly: true,
   1647 	},
   1648 }
   1649 
   1650 func TestMarshal(t *testing.T) {
   1651 	for idx, test := range marshalTests {
   1652 		if test.UnmarshalOnly {
   1653 			continue
   1654 		}
   1655 		data, err := Marshal(test.Value)
   1656 		if err != nil {
   1657 			if test.MarshalError == "" {
   1658 				t.Errorf("#%d: marshal(%#v): %s", idx, test.Value, err)
   1659 				continue
   1660 			}
   1661 			if !strings.Contains(err.Error(), test.MarshalError) {
   1662 				t.Errorf("#%d: marshal(%#v): %s, want %q", idx, test.Value, err, test.MarshalError)
   1663 			}
   1664 			continue
   1665 		}
   1666 		if test.MarshalError != "" {
   1667 			t.Errorf("#%d: Marshal succeeded, want error %q", idx, test.MarshalError)
   1668 			continue
   1669 		}
   1670 		if got, want := string(data), test.ExpectXML; got != want {
   1671 			if strings.Contains(want, "\n") {
   1672 				t.Errorf("#%d: marshal(%#v):\nHAVE:\n%s\nWANT:\n%s", idx, test.Value, got, want)
   1673 			} else {
   1674 				t.Errorf("#%d: marshal(%#v):\nhave %#q\nwant %#q", idx, test.Value, got, want)
   1675 			}
   1676 		}
   1677 	}
   1678 }
   1679 
   1680 type AttrParent struct {
   1681 	X string `xml:"X>Y,attr"`
   1682 }
   1683 
   1684 type BadAttr struct {
   1685 	Name map[string]string `xml:"name,attr"`
   1686 }
   1687 
   1688 var marshalErrorTests = []struct {
   1689 	Value interface{}
   1690 	Err   string
   1691 	Kind  reflect.Kind
   1692 }{
   1693 	{
   1694 		Value: make(chan bool),
   1695 		Err:   "xml: unsupported type: chan bool",
   1696 		Kind:  reflect.Chan,
   1697 	},
   1698 	{
   1699 		Value: map[string]string{
   1700 			"question": "What do you get when you multiply six by nine?",
   1701 			"answer":   "42",
   1702 		},
   1703 		Err:  "xml: unsupported type: map[string]string",
   1704 		Kind: reflect.Map,
   1705 	},
   1706 	{
   1707 		Value: map[*Ship]bool{nil: false},
   1708 		Err:   "xml: unsupported type: map[*xml.Ship]bool",
   1709 		Kind:  reflect.Map,
   1710 	},
   1711 	{
   1712 		Value: &Domain{Comment: []byte("f--bar")},
   1713 		Err:   `xml: comments must not contain "--"`,
   1714 	},
   1715 	// Reject parent chain with attr, never worked; see golang.org/issue/5033.
   1716 	{
   1717 		Value: &AttrParent{},
   1718 		Err:   `xml: X>Y chain not valid with attr flag`,
   1719 	},
   1720 	{
   1721 		Value: BadAttr{map[string]string{"X": "Y"}},
   1722 		Err:   `xml: unsupported type: map[string]string`,
   1723 	},
   1724 }
   1725 
   1726 var marshalIndentTests = []struct {
   1727 	Value     interface{}
   1728 	Prefix    string
   1729 	Indent    string
   1730 	ExpectXML string
   1731 }{
   1732 	{
   1733 		Value: &SecretAgent{
   1734 			Handle:    "007",
   1735 			Identity:  "James Bond",
   1736 			Obfuscate: "<redacted/>",
   1737 		},
   1738 		Prefix:    "",
   1739 		Indent:    "\t",
   1740 		ExpectXML: fmt.Sprintf("<agent handle=\"007\">\n\t<Identity>James Bond</Identity><redacted/>\n</agent>"),
   1741 	},
   1742 }
   1743 
   1744 func TestMarshalErrors(t *testing.T) {
   1745 	for idx, test := range marshalErrorTests {
   1746 		data, err := Marshal(test.Value)
   1747 		if err == nil {
   1748 			t.Errorf("#%d: marshal(%#v) = [success] %q, want error %v", idx, test.Value, data, test.Err)
   1749 			continue
   1750 		}
   1751 		if err.Error() != test.Err {
   1752 			t.Errorf("#%d: marshal(%#v) = [error] %v, want %v", idx, test.Value, err, test.Err)
   1753 		}
   1754 		if test.Kind != reflect.Invalid {
   1755 			if kind := err.(*UnsupportedTypeError).Type.Kind(); kind != test.Kind {
   1756 				t.Errorf("#%d: marshal(%#v) = [error kind] %s, want %s", idx, test.Value, kind, test.Kind)
   1757 			}
   1758 		}
   1759 	}
   1760 }
   1761 
   1762 // Do invertibility testing on the various structures that we test
   1763 func TestUnmarshal(t *testing.T) {
   1764 	for i, test := range marshalTests {
   1765 		if test.MarshalOnly {
   1766 			continue
   1767 		}
   1768 		if _, ok := test.Value.(*Plain); ok {
   1769 			continue
   1770 		}
   1771 		if test.ExpectXML == `<top>`+
   1772 			`<x><b xmlns="space">b</b>`+
   1773 			`<b xmlns="space1">b1</b></x>`+
   1774 			`</top>` {
   1775 			// TODO(rogpeppe): re-enable this test in
   1776 			// https://go-review.googlesource.com/#/c/5910/
   1777 			continue
   1778 		}
   1779 
   1780 		vt := reflect.TypeOf(test.Value)
   1781 		dest := reflect.New(vt.Elem()).Interface()
   1782 		err := Unmarshal([]byte(test.ExpectXML), dest)
   1783 
   1784 		switch fix := dest.(type) {
   1785 		case *Feed:
   1786 			fix.Author.InnerXML = ""
   1787 			for i := range fix.Entry {
   1788 				fix.Entry[i].Author.InnerXML = ""
   1789 			}
   1790 		}
   1791 
   1792 		if err != nil {
   1793 			if test.UnmarshalError == "" {
   1794 				t.Errorf("#%d: unmarshal(%#v): %s", i, test.ExpectXML, err)
   1795 				continue
   1796 			}
   1797 			if !strings.Contains(err.Error(), test.UnmarshalError) {
   1798 				t.Errorf("#%d: unmarshal(%#v): %s, want %q", i, test.ExpectXML, err, test.UnmarshalError)
   1799 			}
   1800 			continue
   1801 		}
   1802 		if got, want := dest, test.Value; !reflect.DeepEqual(got, want) {
   1803 			t.Errorf("#%d: unmarshal(%q):\nhave %#v\nwant %#v", i, test.ExpectXML, got, want)
   1804 		}
   1805 	}
   1806 }
   1807 
   1808 func TestMarshalIndent(t *testing.T) {
   1809 	for i, test := range marshalIndentTests {
   1810 		data, err := MarshalIndent(test.Value, test.Prefix, test.Indent)
   1811 		if err != nil {
   1812 			t.Errorf("#%d: Error: %s", i, err)
   1813 			continue
   1814 		}
   1815 		if got, want := string(data), test.ExpectXML; got != want {
   1816 			t.Errorf("#%d: MarshalIndent:\nGot:%s\nWant:\n%s", i, got, want)
   1817 		}
   1818 	}
   1819 }
   1820 
   1821 type limitedBytesWriter struct {
   1822 	w      io.Writer
   1823 	remain int // until writes fail
   1824 }
   1825 
   1826 func (lw *limitedBytesWriter) Write(p []byte) (n int, err error) {
   1827 	if lw.remain <= 0 {
   1828 		println("error")
   1829 		return 0, errors.New("write limit hit")
   1830 	}
   1831 	if len(p) > lw.remain {
   1832 		p = p[:lw.remain]
   1833 		n, _ = lw.w.Write(p)
   1834 		lw.remain = 0
   1835 		return n, errors.New("write limit hit")
   1836 	}
   1837 	n, err = lw.w.Write(p)
   1838 	lw.remain -= n
   1839 	return n, err
   1840 }
   1841 
   1842 func TestMarshalWriteErrors(t *testing.T) {
   1843 	var buf bytes.Buffer
   1844 	const writeCap = 1024
   1845 	w := &limitedBytesWriter{&buf, writeCap}
   1846 	enc := NewEncoder(w)
   1847 	var err error
   1848 	var i int
   1849 	const n = 4000
   1850 	for i = 1; i <= n; i++ {
   1851 		err = enc.Encode(&Passenger{
   1852 			Name:   []string{"Alice", "Bob"},
   1853 			Weight: 5,
   1854 		})
   1855 		if err != nil {
   1856 			break
   1857 		}
   1858 	}
   1859 	if err == nil {
   1860 		t.Error("expected an error")
   1861 	}
   1862 	if i == n {
   1863 		t.Errorf("expected to fail before the end")
   1864 	}
   1865 	if buf.Len() != writeCap {
   1866 		t.Errorf("buf.Len() = %d; want %d", buf.Len(), writeCap)
   1867 	}
   1868 }
   1869 
   1870 func TestMarshalWriteIOErrors(t *testing.T) {
   1871 	enc := NewEncoder(errWriter{})
   1872 
   1873 	expectErr := "unwritable"
   1874 	err := enc.Encode(&Passenger{})
   1875 	if err == nil || err.Error() != expectErr {
   1876 		t.Errorf("EscapeTest = [error] %v, want %v", err, expectErr)
   1877 	}
   1878 }
   1879 
   1880 func TestMarshalFlush(t *testing.T) {
   1881 	var buf bytes.Buffer
   1882 	enc := NewEncoder(&buf)
   1883 	if err := enc.EncodeToken(CharData("hello world")); err != nil {
   1884 		t.Fatalf("enc.EncodeToken: %v", err)
   1885 	}
   1886 	if buf.Len() > 0 {
   1887 		t.Fatalf("enc.EncodeToken caused actual write: %q", buf.Bytes())
   1888 	}
   1889 	if err := enc.Flush(); err != nil {
   1890 		t.Fatalf("enc.Flush: %v", err)
   1891 	}
   1892 	if buf.String() != "hello world" {
   1893 		t.Fatalf("after enc.Flush, buf.String() = %q, want %q", buf.String(), "hello world")
   1894 	}
   1895 }
   1896 
   1897 func BenchmarkMarshal(b *testing.B) {
   1898 	b.ReportAllocs()
   1899 	for i := 0; i < b.N; i++ {
   1900 		Marshal(atomValue)
   1901 	}
   1902 }
   1903 
   1904 func BenchmarkUnmarshal(b *testing.B) {
   1905 	b.ReportAllocs()
   1906 	xml := []byte(atomXml)
   1907 	for i := 0; i < b.N; i++ {
   1908 		Unmarshal(xml, &Feed{})
   1909 	}
   1910 }
   1911 
   1912 // golang.org/issue/6556
   1913 func TestStructPointerMarshal(t *testing.T) {
   1914 	type A struct {
   1915 		XMLName string `xml:"a"`
   1916 		B       []interface{}
   1917 	}
   1918 	type C struct {
   1919 		XMLName Name
   1920 		Value   string `xml:"value"`
   1921 	}
   1922 
   1923 	a := new(A)
   1924 	a.B = append(a.B, &C{
   1925 		XMLName: Name{Local: "c"},
   1926 		Value:   "x",
   1927 	})
   1928 
   1929 	b, err := Marshal(a)
   1930 	if err != nil {
   1931 		t.Fatal(err)
   1932 	}
   1933 	if x := string(b); x != "<a><c><value>x</value></c></a>" {
   1934 		t.Fatal(x)
   1935 	}
   1936 	var v A
   1937 	err = Unmarshal(b, &v)
   1938 	if err != nil {
   1939 		t.Fatal(err)
   1940 	}
   1941 }
   1942 
   1943 var encodeTokenTests = []struct {
   1944 	desc string
   1945 	toks []Token
   1946 	want string
   1947 	err  string
   1948 }{{
   1949 	desc: "start element with name space",
   1950 	toks: []Token{
   1951 		StartElement{Name{"space", "local"}, nil},
   1952 	},
   1953 	want: `<local xmlns="space">`,
   1954 }, {
   1955 	desc: "start element with no name",
   1956 	toks: []Token{
   1957 		StartElement{Name{"space", ""}, nil},
   1958 	},
   1959 	err: "xml: start tag with no name",
   1960 }, {
   1961 	desc: "end element with no name",
   1962 	toks: []Token{
   1963 		EndElement{Name{"space", ""}},
   1964 	},
   1965 	err: "xml: end tag with no name",
   1966 }, {
   1967 	desc: "char data",
   1968 	toks: []Token{
   1969 		CharData("foo"),
   1970 	},
   1971 	want: `foo`,
   1972 }, {
   1973 	desc: "char data with escaped chars",
   1974 	toks: []Token{
   1975 		CharData(" \t\n"),
   1976 	},
   1977 	want: " &#x9;\n",
   1978 }, {
   1979 	desc: "comment",
   1980 	toks: []Token{
   1981 		Comment("foo"),
   1982 	},
   1983 	want: `<!--foo-->`,
   1984 }, {
   1985 	desc: "comment with invalid content",
   1986 	toks: []Token{
   1987 		Comment("foo-->"),
   1988 	},
   1989 	err: "xml: EncodeToken of Comment containing --> marker",
   1990 }, {
   1991 	desc: "proc instruction",
   1992 	toks: []Token{
   1993 		ProcInst{"Target", []byte("Instruction")},
   1994 	},
   1995 	want: `<?Target Instruction?>`,
   1996 }, {
   1997 	desc: "proc instruction with empty target",
   1998 	toks: []Token{
   1999 		ProcInst{"", []byte("Instruction")},
   2000 	},
   2001 	err: "xml: EncodeToken of ProcInst with invalid Target",
   2002 }, {
   2003 	desc: "proc instruction with bad content",
   2004 	toks: []Token{
   2005 		ProcInst{"", []byte("Instruction?>")},
   2006 	},
   2007 	err: "xml: EncodeToken of ProcInst with invalid Target",
   2008 }, {
   2009 	desc: "directive",
   2010 	toks: []Token{
   2011 		Directive("foo"),
   2012 	},
   2013 	want: `<!foo>`,
   2014 }, {
   2015 	desc: "more complex directive",
   2016 	toks: []Token{
   2017 		Directive("DOCTYPE doc [ <!ELEMENT doc '>'> <!-- com>ment --> ]"),
   2018 	},
   2019 	want: `<!DOCTYPE doc [ <!ELEMENT doc '>'> <!-- com>ment --> ]>`,
   2020 }, {
   2021 	desc: "directive instruction with bad name",
   2022 	toks: []Token{
   2023 		Directive("foo>"),
   2024 	},
   2025 	err: "xml: EncodeToken of Directive containing wrong < or > markers",
   2026 }, {
   2027 	desc: "end tag without start tag",
   2028 	toks: []Token{
   2029 		EndElement{Name{"foo", "bar"}},
   2030 	},
   2031 	err: "xml: end tag </bar> without start tag",
   2032 }, {
   2033 	desc: "mismatching end tag local name",
   2034 	toks: []Token{
   2035 		StartElement{Name{"", "foo"}, nil},
   2036 		EndElement{Name{"", "bar"}},
   2037 	},
   2038 	err:  "xml: end tag </bar> does not match start tag <foo>",
   2039 	want: `<foo>`,
   2040 }, {
   2041 	desc: "mismatching end tag namespace",
   2042 	toks: []Token{
   2043 		StartElement{Name{"space", "foo"}, nil},
   2044 		EndElement{Name{"another", "foo"}},
   2045 	},
   2046 	err:  "xml: end tag </foo> in namespace another does not match start tag <foo> in namespace space",
   2047 	want: `<foo xmlns="space">`,
   2048 }, {
   2049 	desc: "start element with explicit namespace",
   2050 	toks: []Token{
   2051 		StartElement{Name{"space", "local"}, []Attr{
   2052 			{Name{"xmlns", "x"}, "space"},
   2053 			{Name{"space", "foo"}, "value"},
   2054 		}},
   2055 	},
   2056 	want: `<local xmlns="space" xmlns:_xmlns="xmlns" _xmlns:x="space" xmlns:space="space" space:foo="value">`,
   2057 }, {
   2058 	desc: "start element with explicit namespace and colliding prefix",
   2059 	toks: []Token{
   2060 		StartElement{Name{"space", "local"}, []Attr{
   2061 			{Name{"xmlns", "x"}, "space"},
   2062 			{Name{"space", "foo"}, "value"},
   2063 			{Name{"x", "bar"}, "other"},
   2064 		}},
   2065 	},
   2066 	want: `<local xmlns="space" xmlns:_xmlns="xmlns" _xmlns:x="space" xmlns:space="space" space:foo="value" xmlns:x="x" x:bar="other">`,
   2067 }, {
   2068 	desc: "start element using previously defined namespace",
   2069 	toks: []Token{
   2070 		StartElement{Name{"", "local"}, []Attr{
   2071 			{Name{"xmlns", "x"}, "space"},
   2072 		}},
   2073 		StartElement{Name{"space", "foo"}, []Attr{
   2074 			{Name{"space", "x"}, "y"},
   2075 		}},
   2076 	},
   2077 	want: `<local xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" xmlns:space="space" space:x="y">`,
   2078 }, {
   2079 	desc: "nested name space with same prefix",
   2080 	toks: []Token{
   2081 		StartElement{Name{"", "foo"}, []Attr{
   2082 			{Name{"xmlns", "x"}, "space1"},
   2083 		}},
   2084 		StartElement{Name{"", "foo"}, []Attr{
   2085 			{Name{"xmlns", "x"}, "space2"},
   2086 		}},
   2087 		StartElement{Name{"", "foo"}, []Attr{
   2088 			{Name{"space1", "a"}, "space1 value"},
   2089 			{Name{"space2", "b"}, "space2 value"},
   2090 		}},
   2091 		EndElement{Name{"", "foo"}},
   2092 		EndElement{Name{"", "foo"}},
   2093 		StartElement{Name{"", "foo"}, []Attr{
   2094 			{Name{"space1", "a"}, "space1 value"},
   2095 			{Name{"space2", "b"}, "space2 value"},
   2096 		}},
   2097 	},
   2098 	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">`,
   2099 }, {
   2100 	desc: "start element defining several prefixes for the same name space",
   2101 	toks: []Token{
   2102 		StartElement{Name{"space", "foo"}, []Attr{
   2103 			{Name{"xmlns", "a"}, "space"},
   2104 			{Name{"xmlns", "b"}, "space"},
   2105 			{Name{"space", "x"}, "value"},
   2106 		}},
   2107 	},
   2108 	want: `<foo xmlns="space" xmlns:_xmlns="xmlns" _xmlns:a="space" _xmlns:b="space" xmlns:space="space" space:x="value">`,
   2109 }, {
   2110 	desc: "nested element redefines name space",
   2111 	toks: []Token{
   2112 		StartElement{Name{"", "foo"}, []Attr{
   2113 			{Name{"xmlns", "x"}, "space"},
   2114 		}},
   2115 		StartElement{Name{"space", "foo"}, []Attr{
   2116 			{Name{"xmlns", "y"}, "space"},
   2117 			{Name{"space", "a"}, "value"},
   2118 		}},
   2119 	},
   2120 	want: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" _xmlns:y="space" xmlns:space="space" space:a="value">`,
   2121 }, {
   2122 	desc: "nested element creates alias for default name space",
   2123 	toks: []Token{
   2124 		StartElement{Name{"space", "foo"}, []Attr{
   2125 			{Name{"", "xmlns"}, "space"},
   2126 		}},
   2127 		StartElement{Name{"space", "foo"}, []Attr{
   2128 			{Name{"xmlns", "y"}, "space"},
   2129 			{Name{"space", "a"}, "value"},
   2130 		}},
   2131 	},
   2132 	want: `<foo xmlns="space" xmlns="space"><foo xmlns="space" xmlns:_xmlns="xmlns" _xmlns:y="space" xmlns:space="space" space:a="value">`,
   2133 }, {
   2134 	desc: "nested element defines default name space with existing prefix",
   2135 	toks: []Token{
   2136 		StartElement{Name{"", "foo"}, []Attr{
   2137 			{Name{"xmlns", "x"}, "space"},
   2138 		}},
   2139 		StartElement{Name{"space", "foo"}, []Attr{
   2140 			{Name{"", "xmlns"}, "space"},
   2141 			{Name{"space", "a"}, "value"},
   2142 		}},
   2143 	},
   2144 	want: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" xmlns="space" xmlns:space="space" space:a="value">`,
   2145 }, {
   2146 	desc: "nested element uses empty attribute name space when default ns defined",
   2147 	toks: []Token{
   2148 		StartElement{Name{"space", "foo"}, []Attr{
   2149 			{Name{"", "xmlns"}, "space"},
   2150 		}},
   2151 		StartElement{Name{"space", "foo"}, []Attr{
   2152 			{Name{"", "attr"}, "value"},
   2153 		}},
   2154 	},
   2155 	want: `<foo xmlns="space" xmlns="space"><foo xmlns="space" attr="value">`,
   2156 }, {
   2157 	desc: "redefine xmlns",
   2158 	toks: []Token{
   2159 		StartElement{Name{"", "foo"}, []Attr{
   2160 			{Name{"foo", "xmlns"}, "space"},
   2161 		}},
   2162 	},
   2163 	want: `<foo xmlns:foo="foo" foo:xmlns="space">`,
   2164 }, {
   2165 	desc: "xmlns with explicit name space #1",
   2166 	toks: []Token{
   2167 		StartElement{Name{"space", "foo"}, []Attr{
   2168 			{Name{"xml", "xmlns"}, "space"},
   2169 		}},
   2170 	},
   2171 	want: `<foo xmlns="space" xmlns:_xml="xml" _xml:xmlns="space">`,
   2172 }, {
   2173 	desc: "xmlns with explicit name space #2",
   2174 	toks: []Token{
   2175 		StartElement{Name{"space", "foo"}, []Attr{
   2176 			{Name{xmlURL, "xmlns"}, "space"},
   2177 		}},
   2178 	},
   2179 	want: `<foo xmlns="space" xml:xmlns="space">`,
   2180 }, {
   2181 	desc: "empty name space declaration is ignored",
   2182 	toks: []Token{
   2183 		StartElement{Name{"", "foo"}, []Attr{
   2184 			{Name{"xmlns", "foo"}, ""},
   2185 		}},
   2186 	},
   2187 	want: `<foo xmlns:_xmlns="xmlns" _xmlns:foo="">`,
   2188 }, {
   2189 	desc: "attribute with no name is ignored",
   2190 	toks: []Token{
   2191 		StartElement{Name{"", "foo"}, []Attr{
   2192 			{Name{"", ""}, "value"},
   2193 		}},
   2194 	},
   2195 	want: `<foo>`,
   2196 }, {
   2197 	desc: "namespace URL with non-valid name",
   2198 	toks: []Token{
   2199 		StartElement{Name{"/34", "foo"}, []Attr{
   2200 			{Name{"/34", "x"}, "value"},
   2201 		}},
   2202 	},
   2203 	want: `<foo xmlns="/34" xmlns:_="/34" _:x="value">`,
   2204 }, {
   2205 	desc: "nested element resets default namespace to empty",
   2206 	toks: []Token{
   2207 		StartElement{Name{"space", "foo"}, []Attr{
   2208 			{Name{"", "xmlns"}, "space"},
   2209 		}},
   2210 		StartElement{Name{"", "foo"}, []Attr{
   2211 			{Name{"", "xmlns"}, ""},
   2212 			{Name{"", "x"}, "value"},
   2213 			{Name{"space", "x"}, "value"},
   2214 		}},
   2215 	},
   2216 	want: `<foo xmlns="space" xmlns="space"><foo xmlns="" x="value" xmlns:space="space" space:x="value">`,
   2217 }, {
   2218 	desc: "nested element requires empty default name space",
   2219 	toks: []Token{
   2220 		StartElement{Name{"space", "foo"}, []Attr{
   2221 			{Name{"", "xmlns"}, "space"},
   2222 		}},
   2223 		StartElement{Name{"", "foo"}, nil},
   2224 	},
   2225 	want: `<foo xmlns="space" xmlns="space"><foo>`,
   2226 }, {
   2227 	desc: "attribute uses name space from xmlns",
   2228 	toks: []Token{
   2229 		StartElement{Name{"some/space", "foo"}, []Attr{
   2230 			{Name{"", "attr"}, "value"},
   2231 			{Name{"some/space", "other"}, "other value"},
   2232 		}},
   2233 	},
   2234 	want: `<foo xmlns="some/space" attr="value" xmlns:space="some/space" space:other="other value">`,
   2235 }, {
   2236 	desc: "default name space should not be used by attributes",
   2237 	toks: []Token{
   2238 		StartElement{Name{"space", "foo"}, []Attr{
   2239 			{Name{"", "xmlns"}, "space"},
   2240 			{Name{"xmlns", "bar"}, "space"},
   2241 			{Name{"space", "baz"}, "foo"},
   2242 		}},
   2243 		StartElement{Name{"space", "baz"}, nil},
   2244 		EndElement{Name{"space", "baz"}},
   2245 		EndElement{Name{"space", "foo"}},
   2246 	},
   2247 	want: `<foo xmlns="space" xmlns="space" xmlns:_xmlns="xmlns" _xmlns:bar="space" xmlns:space="space" space:baz="foo"><baz xmlns="space"></baz></foo>`,
   2248 }, {
   2249 	desc: "default name space not used by attributes, not explicitly defined",
   2250 	toks: []Token{
   2251 		StartElement{Name{"space", "foo"}, []Attr{
   2252 			{Name{"", "xmlns"}, "space"},
   2253 			{Name{"space", "baz"}, "foo"},
   2254 		}},
   2255 		StartElement{Name{"space", "baz"}, nil},
   2256 		EndElement{Name{"space", "baz"}},
   2257 		EndElement{Name{"space", "foo"}},
   2258 	},
   2259 	want: `<foo xmlns="space" xmlns="space" xmlns:space="space" space:baz="foo"><baz xmlns="space"></baz></foo>`,
   2260 }, {
   2261 	desc: "impossible xmlns declaration",
   2262 	toks: []Token{
   2263 		StartElement{Name{"", "foo"}, []Attr{
   2264 			{Name{"", "xmlns"}, "space"},
   2265 		}},
   2266 		StartElement{Name{"space", "bar"}, []Attr{
   2267 			{Name{"space", "attr"}, "value"},
   2268 		}},
   2269 	},
   2270 	want: `<foo xmlns="space"><bar xmlns="space" xmlns:space="space" space:attr="value">`,
   2271 }}
   2272 
   2273 func TestEncodeToken(t *testing.T) {
   2274 loop:
   2275 	for i, tt := range encodeTokenTests {
   2276 		var buf bytes.Buffer
   2277 		enc := NewEncoder(&buf)
   2278 		var err error
   2279 		for j, tok := range tt.toks {
   2280 			err = enc.EncodeToken(tok)
   2281 			if err != nil && j < len(tt.toks)-1 {
   2282 				t.Errorf("#%d %s token #%d: %v", i, tt.desc, j, err)
   2283 				continue loop
   2284 			}
   2285 		}
   2286 		errorf := func(f string, a ...interface{}) {
   2287 			t.Errorf("#%d %s token #%d:%s", i, tt.desc, len(tt.toks)-1, fmt.Sprintf(f, a...))
   2288 		}
   2289 		switch {
   2290 		case tt.err != "" && err == nil:
   2291 			errorf(" expected error; got none")
   2292 			continue
   2293 		case tt.err == "" && err != nil:
   2294 			errorf(" got error: %v", err)
   2295 			continue
   2296 		case tt.err != "" && err != nil && tt.err != err.Error():
   2297 			errorf(" error mismatch; got %v, want %v", err, tt.err)
   2298 			continue
   2299 		}
   2300 		if err := enc.Flush(); err != nil {
   2301 			errorf(" %v", err)
   2302 			continue
   2303 		}
   2304 		if got := buf.String(); got != tt.want {
   2305 			errorf("\ngot  %v\nwant %v", got, tt.want)
   2306 			continue
   2307 		}
   2308 	}
   2309 }
   2310 
   2311 func TestProcInstEncodeToken(t *testing.T) {
   2312 	var buf bytes.Buffer
   2313 	enc := NewEncoder(&buf)
   2314 
   2315 	if err := enc.EncodeToken(ProcInst{"xml", []byte("Instruction")}); err != nil {
   2316 		t.Fatalf("enc.EncodeToken: expected to be able to encode xml target ProcInst as first token, %s", err)
   2317 	}
   2318 
   2319 	if err := enc.EncodeToken(ProcInst{"Target", []byte("Instruction")}); err != nil {
   2320 		t.Fatalf("enc.EncodeToken: expected to be able to add non-xml target ProcInst")
   2321 	}
   2322 
   2323 	if err := enc.EncodeToken(ProcInst{"xml", []byte("Instruction")}); err == nil {
   2324 		t.Fatalf("enc.EncodeToken: expected to not be allowed to encode xml target ProcInst when not first token")
   2325 	}
   2326 }
   2327 
   2328 func TestDecodeEncode(t *testing.T) {
   2329 	var in, out bytes.Buffer
   2330 	in.WriteString(`<?xml version="1.0" encoding="UTF-8"?>
   2331 <?Target Instruction?>
   2332 <root>
   2333 </root>
   2334 `)
   2335 	dec := NewDecoder(&in)
   2336 	enc := NewEncoder(&out)
   2337 	for tok, err := dec.Token(); err == nil; tok, err = dec.Token() {
   2338 		err = enc.EncodeToken(tok)
   2339 		if err != nil {
   2340 			t.Fatalf("enc.EncodeToken: Unable to encode token (%#v), %v", tok, err)
   2341 		}
   2342 	}
   2343 }
   2344 
   2345 // Issue 9796. Used to fail with GORACE="halt_on_error=1" -race.
   2346 func TestRace9796(t *testing.T) {
   2347 	type A struct{}
   2348 	type B struct {
   2349 		C []A `xml:"X>Y"`
   2350 	}
   2351 	var wg sync.WaitGroup
   2352 	for i := 0; i < 2; i++ {
   2353 		wg.Add(1)
   2354 		go func() {
   2355 			Marshal(B{[]A{{}}})
   2356 			wg.Done()
   2357 		}()
   2358 	}
   2359 	wg.Wait()
   2360 }
   2361 
   2362 func TestIsValidDirective(t *testing.T) {
   2363 	testOK := []string{
   2364 		"<>",
   2365 		"< < > >",
   2366 		"<!DOCTYPE '<' '>' '>' <!--nothing-->>",
   2367 		"<!DOCTYPE doc [ <!ELEMENT doc ANY> <!ELEMENT doc ANY> ]>",
   2368 		"<!DOCTYPE doc [ <!ELEMENT doc \"ANY> '<' <!E\" LEMENT '>' doc ANY> ]>",
   2369 		"<!DOCTYPE doc <!-- just>>>> a < comment --> [ <!ITEM anything> ] >",
   2370 	}
   2371 	testKO := []string{
   2372 		"<",
   2373 		">",
   2374 		"<!--",
   2375 		"-->",
   2376 		"< > > < < >",
   2377 		"<!dummy <!-- > -->",
   2378 		"<!DOCTYPE doc '>",
   2379 		"<!DOCTYPE doc '>'",
   2380 		"<!DOCTYPE doc <!--comment>",
   2381 	}
   2382 	for _, s := range testOK {
   2383 		if !isValidDirective(Directive(s)) {
   2384 			t.Errorf("Directive %q is expected to be valid", s)
   2385 		}
   2386 	}
   2387 	for _, s := range testKO {
   2388 		if isValidDirective(Directive(s)) {
   2389 			t.Errorf("Directive %q is expected to be invalid", s)
   2390 		}
   2391 	}
   2392 }
   2393 
   2394 // Issue 11719. EncodeToken used to silently eat tokens with an invalid type.
   2395 func TestSimpleUseOfEncodeToken(t *testing.T) {
   2396 	var buf bytes.Buffer
   2397 	enc := NewEncoder(&buf)
   2398 	if err := enc.EncodeToken(&StartElement{Name: Name{"", "object1"}}); err == nil {
   2399 		t.Errorf("enc.EncodeToken: pointer type should be rejected")
   2400 	}
   2401 	if err := enc.EncodeToken(&EndElement{Name: Name{"", "object1"}}); err == nil {
   2402 		t.Errorf("enc.EncodeToken: pointer type should be rejected")
   2403 	}
   2404 	if err := enc.EncodeToken(StartElement{Name: Name{"", "object2"}}); err != nil {
   2405 		t.Errorf("enc.EncodeToken: StartElement %s", err)
   2406 	}
   2407 	if err := enc.EncodeToken(EndElement{Name: Name{"", "object2"}}); err != nil {
   2408 		t.Errorf("enc.EncodeToken: EndElement %s", err)
   2409 	}
   2410 	if err := enc.EncodeToken(Universe{}); err == nil {
   2411 		t.Errorf("enc.EncodeToken: invalid type not caught")
   2412 	}
   2413 	if err := enc.Flush(); err != nil {
   2414 		t.Errorf("enc.Flush: %s", err)
   2415 	}
   2416 	if buf.Len() == 0 {
   2417 		t.Errorf("enc.EncodeToken: empty buffer")
   2418 	}
   2419 	want := "<object2></object2>"
   2420 	if buf.String() != want {
   2421 		t.Errorf("enc.EncodeToken: expected %q; got %q", want, buf.String())
   2422 	}
   2423 }
   2424 
   2425 // Issue 16158. Decoder.unmarshalAttr ignores the return value of copyValue.
   2426 func TestIssue16158(t *testing.T) {
   2427 	const data = `<foo b="HELLOWORLD"></foo>`
   2428 	err := Unmarshal([]byte(data), &struct {
   2429 		B byte `xml:"b,attr,omitempty"`
   2430 	}{})
   2431 	if err == nil {
   2432 		t.Errorf("Unmarshal: expected error, got nil")
   2433 	}
   2434 }
   2435