...

Source file src/encoding/xml/marshal_test.go

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

View as plain text