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.
23 HyperDrive DriveType
= iota
27 type Passenger
struct {
28 Name
[]string `xml:"name"`
29 Weight
float32 `xml:"weight"`
33 XMLName
struct{} `xml:"spaceship"`
35 Name
string `xml:"name,attr"`
36 Pilot
string `xml:"pilot,attr"`
37 Drive DriveType
`xml:"drive"`
39 Passenger
[]*Passenger
`xml:"passenger"`
46 XMLName
struct{} `xml:"port"`
47 Type
string `xml:"type,attr,omitempty"`
48 Comment
string `xml:",comment"`
49 Number
string `xml:",chardata"`
53 XMLName
struct{} `xml:"domain"`
54 Country
string `xml:",attr,omitempty"`
55 Name
[]byte `xml:",chardata"`
56 Comment
[]byte `xml:",comment"`
60 XMLName
struct{} `xml:"book"`
61 Title
string `xml:",chardata"`
65 XMLName
struct{} `xml:"event"`
66 Year
int `xml:",chardata"`
70 XMLName
struct{} `xml:"movie"`
71 Length
uint `xml:",chardata"`
75 XMLName
struct{} `xml:"pi"`
76 Approximation
float32 `xml:",chardata"`
79 type Universe
struct {
80 XMLName
struct{} `xml:"universe"`
81 Visible
float64 `xml:",chardata"`
84 type Particle
struct {
85 XMLName
struct{} `xml:"particle"`
86 HasMass
bool `xml:",chardata"`
89 type Departure
struct {
90 XMLName
struct{} `xml:"departure"`
91 When time
.Time
`xml:",chardata"`
94 type SecretAgent
struct {
95 XMLName
struct{} `xml:"agent"`
96 Handle
string `xml:"handle,attr"`
98 Obfuscate
string `xml:",innerxml"`
101 type NestedItems
struct {
102 XMLName
struct{} `xml:"result"`
103 Items
[]string `xml:">item"`
104 Item1
[]string `xml:"Items>item1"`
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"`
114 type MixedNested
struct {
115 XMLName
struct{} `xml:"result"`
116 A
string `xml:"parent1>a"`
118 C
string `xml:"parent1>parent2>c"`
119 D
string `xml:"parent1>d"`
122 type NilTest
struct {
123 A
interface{} `xml:"parent1>parent2>a"`
124 B
interface{} `xml:"parent1>b"`
125 C
interface{} `xml:"parent1>parent2>c"`
128 type Service
struct {
129 XMLName
struct{} `xml:"service"`
130 Domain
*Domain
`xml:"host>domain"`
131 Port
*Port
`xml:"host>port"`
133 Extra2
interface{} `xml:"host>extra2"`
151 FieldA1
string `xml:"FieldA>A1"`
152 FieldA2
string `xml:"FieldA>A2"`
159 FieldE
string // Promoted and visible when embedD is embedded.
162 type NameCasing
struct {
163 XMLName
struct{} `xml:"casing"`
166 XyA
string `xml:"Xy,attr"`
167 XYA
string `xml:"XY,attr"`
170 type NamePrecedence
struct {
171 XMLName Name
`xml:"Parent"`
172 FromTag XMLNameWithoutTag
`xml:"InTag"`
173 FromNameVal XMLNameWithoutTag
174 FromNameTag XMLNameWithTag
178 type XMLNameWithTag
struct {
179 XMLName Name
`xml:"InXMLNameTag"`
180 Value
string `xml:",chardata"`
183 type XMLNameWithoutTag
struct {
185 Value
string `xml:",chardata"`
188 type NameInField
struct {
189 Foo Name
`xml:"ns foo"`
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"`
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"`
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"`
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"`
236 type AnyTest
struct {
237 XMLName
struct{} `xml:"a"`
238 Nested
string `xml:"nested>value"`
239 AnyField AnyHolder
`xml:",any"`
242 type AnyOmitTest
struct {
243 XMLName
struct{} `xml:"a"`
244 Nested
string `xml:"nested>value"`
245 AnyField
*AnyHolder
`xml:",any,omitempty"`
248 type AnySliceTest
struct {
249 XMLName
struct{} `xml:"a"`
250 Nested
string `xml:"nested>value"`
251 AnyField
[]AnyHolder
`xml:",any"`
254 type AnyHolder
struct {
256 XML
string `xml:",innerxml"`
259 type RecurseA
struct {
264 type RecurseB
struct {
269 type PresenceTest
struct {
273 type IgnoreTest
struct {
274 PublicSecret
string `xml:"-"`
281 Attr
[]byte `xml:",attr"`
291 type EmbedInt
struct {
295 type Strings
struct {
296 X
[]string `xml:"A>B,omitempty"`
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"`
307 type ChardataEmptyTest
struct {
308 XMLName Name
`xml:"test"`
309 Contents
*string `xml:",chardata"`
312 type MyMarshalerTest
struct {
315 var _ Marshaler
= (*MyMarshalerTest
)(nil)
317 func (m
*MyMarshalerTest
) MarshalXML(e
*Encoder
, start StartElement
) error
{
319 e
.EncodeToken(CharData([]byte("hello world")))
320 e
.EncodeToken(EndElement
{start
.Name
})
324 type MyMarshalerAttrTest
struct {
327 var _ MarshalerAttr
= (*MyMarshalerAttrTest
)(nil)
329 func (m
*MyMarshalerAttrTest
) MarshalXMLAttr(name Name
) (Attr
, error
) {
330 return Attr
{name
, "hello world"}, nil
333 func (m
*MyMarshalerAttrTest
) UnmarshalXMLAttr(attr Attr
) error
{
337 type MarshalerStruct
struct {
338 Foo MyMarshalerAttrTest
`xml:",attr"`
341 type InnerStruct
struct {
342 XMLName Name
`xml:"testns outer"`
345 type OuterStruct
struct {
347 IntAttr
int `xml:"int,attr"`
350 type OuterNamedStruct
struct {
352 XMLName Name
`xml:"outerns test"`
353 IntAttr
int `xml:"int,attr"`
356 type OuterNamedOrderedStruct
struct {
357 XMLName Name
`xml:"outerns test"`
359 IntAttr
int `xml:"int,attr"`
362 type OuterOuterStruct
struct {
366 type NestedAndChardata
struct {
367 AB
[]string `xml:"A>B"`
368 Chardata
string `xml:",chardata"`
371 type NestedAndComment
struct {
372 AB
[]string `xml:"A>B"`
373 Comment
string `xml:",comment"`
376 type CDataTest
struct {
377 Chardata
string `xml:",cdata"`
380 type NestedAndCData
struct {
381 AB
[]string `xml:"A>B"`
382 CDATA
string `xml:",cdata"`
385 func ifaceptr(x
interface{}) interface{} {
389 func stringptr(x
string) *string {
397 type IndirComment
struct {
399 Comment
*string `xml:",comment"`
403 type DirectComment
struct {
405 Comment
string `xml:",comment"`
409 type IfaceComment
struct {
411 Comment
interface{} `xml:",comment"`
415 type IndirChardata
struct {
417 Chardata
*string `xml:",chardata"`
421 type DirectChardata
struct {
423 Chardata
string `xml:",chardata"`
427 type IfaceChardata
struct {
429 Chardata
interface{} `xml:",chardata"`
433 type IndirCDATA
struct {
435 CDATA
*string `xml:",cdata"`
439 type DirectCDATA
struct {
441 CDATA
string `xml:",cdata"`
445 type IfaceCDATA
struct {
447 CDATA
interface{} `xml:",cdata"`
451 type IndirInnerXML
struct {
453 InnerXML
*string `xml:",innerxml"`
457 type DirectInnerXML
struct {
459 InnerXML
string `xml:",innerxml"`
463 type IfaceInnerXML
struct {
465 InnerXML
interface{} `xml:",innerxml"`
469 type IndirElement
struct {
475 type DirectElement
struct {
481 type IfaceElement
struct {
487 type IndirOmitEmpty
struct {
489 OmitEmpty
*string `xml:",omitempty"`
493 type DirectOmitEmpty
struct {
495 OmitEmpty
string `xml:",omitempty"`
499 type IfaceOmitEmpty
struct {
501 OmitEmpty
interface{} `xml:",omitempty"`
505 type IndirAny
struct {
507 Any
*string `xml:",any"`
511 type DirectAny
struct {
513 Any
string `xml:",any"`
517 type IfaceAny
struct {
519 Any
interface{} `xml:",any"`
526 contentsAttr
= "lorem ipsum"
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 {
540 UnmarshalError
string
542 // Test nil marshals to nothing
543 {Value
: nil, ExpectXML
: ``, MarshalOnly
: true},
544 {Value
: nilStruct
, ExpectXML
: ``, MarshalOnly
: true},
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></></V></Plain>`},
563 {Value
: &Plain
{[]byte("</>")}, ExpectXML
: `<Plain><V></></V></Plain>`},
564 {Value
: &Plain
{[3]byte{'<', '/', '>'}}, ExpectXML
: `<Plain><V></></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>`},
572 Value
: &Plain
{time
.Unix(1e9
, 123456789).UTC()},
573 ExpectXML
: `<Plain><V>2001-09-09T01:46:40.123456789Z</V></Plain>`,
576 // A pointer to struct{} may be used to test for an element's presence.
578 Value
: &PresenceTest
{new(struct{})},
579 ExpectXML
: `<PresenceTest><Exists></Exists></PresenceTest>`,
582 Value
: &PresenceTest
{},
583 ExpectXML
: `<PresenceTest></PresenceTest>`,
586 // A pointer to struct{} may be used to test for an element's presence.
588 Value
: &PresenceTest
{new(struct{})},
589 ExpectXML
: `<PresenceTest><Exists></Exists></PresenceTest>`,
592 Value
: &PresenceTest
{},
593 ExpectXML
: `<PresenceTest></PresenceTest>`,
596 // A []byte field is only nil if the element was not found.
599 ExpectXML
: `<Data></Data>`,
603 Value
: &Data
{Bytes
: []byte{}, Custom
: MyBytes
{}, Attr
: []byte{}},
604 ExpectXML
: `<Data Attr=""><Bytes></Bytes><Custom></Custom></Data>`,
608 // Check that []byte works, including named []byte types.
610 Value
: &Data
{Bytes
: []byte("ab"), Custom
: MyBytes("cd"), Attr
: []byte{'v'}},
611 ExpectXML
: `<Data Attr="v"><Bytes>ab</Bytes><Custom>cd</Custom></Data>`,
618 Identity
: "James Bond",
619 Obfuscate
: "<redacted/>",
621 ExpectXML
: `<agent handle="007"><Identity>James Bond</Identity><redacted/></agent>`,
627 Identity
: "James Bond",
628 Obfuscate
: "<Identity>James Bond</Identity><redacted/>",
630 ExpectXML
: `<agent handle="007"><Identity>James Bond</Identity><redacted/></agent>`,
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="<unix>"></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&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 & 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
},
652 Name
: "Heart of Gold",
655 Drive
: ImprobabilityDrive
,
656 Passenger
: []*Passenger
{
658 Name
: []string{"Zaphod", "Beeblebrox"},
662 Name
: []string{"Trisha", "McMillen"},
666 Name
: []string{"Ford", "Prefect"},
670 Name
: []string{"Arthur", "Dent"},
675 ExpectXML
: `<spaceship name="Heart of Gold" pilot="Computer">` +
676 `<drive>` + strconv
.Itoa(int(ImprobabilityDrive
)) + `</drive>` +
679 `<name>Zaphod</name>` +
680 `<name>Beeblebrox</name>` +
681 `<weight>7.25</weight>` +
684 `<name>Trisha</name>` +
685 `<name>McMillen</name>` +
686 `<weight>5.5</weight>` +
689 `<name>Ford</name>` +
690 `<name>Prefect</name>` +
691 `<weight>7</weight>` +
694 `<name>Arthur</name>` +
695 `<name>Dent</name>` +
696 `<weight>6.75</weight>` +
703 Value
: &NestedItems
{Items
: nil, Item1
: nil},
704 ExpectXML
: `<result>` +
710 Value
: &NestedItems
{Items
: []string{}, Item1
: []string{}},
711 ExpectXML
: `<result>` +
718 Value
: &NestedItems
{Items
: nil, Item1
: []string{"A"}},
719 ExpectXML
: `<result>` +
726 Value
: &NestedItems
{Items
: []string{"A", "B"}, Item1
: nil},
727 ExpectXML
: `<result>` +
735 Value
: &NestedItems
{Items
: []string{"A", "B"}, Item1
: []string{"C"}},
736 ExpectXML
: `<result>` +
745 Value
: &NestedOrder
{Field1
: "C", Field2
: "B", Field3
: "A"},
746 ExpectXML
: `<result>` +
755 Value
: &NilTest
{A
: "A", B
: nil, C
: "C"},
756 ExpectXML
: `<NilTest>` +
758 `<parent2><a>A</a></parent2>` +
759 `<parent2><c>C</c></parent2>` +
762 MarshalOnly
: true, // Uses interface{}
765 Value
: &MixedNested
{A
: "A", B
: "B", C
: "C", D
: "D"},
766 ExpectXML
: `<result>` +
767 `<parent1><a>A</a></parent1>` +
770 `<parent2><c>C</c></parent2>` +
776 Value
: &Service
{Port
: &Port
{Number
: "80"}},
777 ExpectXML
: `<service><host><port>80</port></host></service>`,
781 ExpectXML
: `<service></service>`,
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>` +
793 Value
: &Service
{Port
: &Port
{Number
: "80"}, Extra2
: "example"},
794 ExpectXML
: `<service>` +
795 `<host><port>80</port></host>` +
796 `<host><extra2>example</extra2></host>` +
802 XMLName
struct{} `xml:"space top"`
805 C
string `xml:"space x>c"`
806 C1
string `xml:"space1 x>c"`
807 D1
string `xml:"space1 x>d"`
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>` +
827 C
string `xml:"space x>c"`
828 C1
string `xml:"space1 x>c"`
829 D1
string `xml:"space1 x>d"`
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>` +
851 XMLName
struct{} `xml:"top"`
852 B
string `xml:"space x>b"`
853 B1
string `xml:"space1 x>b"`
859 `<x><b xmlns="space">b</b>` +
860 `<b xmlns="space1">b1</b></x>` +
864 // Test struct embedding
868 FieldA1
: "", // Shadowed by A.A
869 FieldA2
: "", // Shadowed by A.A
878 FieldB
: "", // Shadowed by A.B.B
887 ExpectXML
: `<EmbedA>` +
888 `<FieldB>A.C.B</FieldB>` +
889 `<FieldC>A.C.C</FieldC>` +
891 `<FieldB>A.B.B</FieldB>` +
893 `<A1>A.B.C.A1</A1>` +
894 `<A2>A.B.C.A2</A2>` +
896 `<FieldC>A.B.C.C</FieldC>` +
898 `<FieldA>A.A</FieldA>` +
899 `<FieldE>A.D.E</FieldE>` +
903 // Test that name casing matters
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>`,
909 // Test the order in which the XML element name is chosen
911 Value
: &NamePrecedence
{
912 FromTag
: XMLNameWithoutTag
{Value
: "A"},
913 FromNameVal
: XMLNameWithoutTag
{XMLName
: Name
{Local
: "InXMLName"}, Value
: "B"},
914 FromNameTag
: XMLNameWithTag
{Value
: "C"},
917 ExpectXML
: `<Parent>` +
919 `<InXMLName>B</InXMLName>` +
920 `<InXMLNameTag>C</InXMLNameTag>` +
921 `<InFieldName>D</InFieldName>` +
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"},
933 ExpectXML
: `<Parent>` +
935 `<FromNameVal>B</FromNameVal>` +
936 `<InXMLNameTag>C</InXMLNameTag>` +
937 `<InFieldName>D</InFieldName>` +
942 // xml.Name works in a plain field as well.
944 Value
: &NameInField
{Name
{Space
: "ns", Local
: "foo"}},
945 ExpectXML
: `<NameInField><foo xmlns="ns"></foo></NameInField>`,
948 Value
: &NameInField
{Name
{Space
: "ns", Local
: "foo"}},
949 ExpectXML
: `<NameInField><foo xmlns="ns"><ignore></ignore></foo></NameInField>`,
953 // Marshaling zero xml.Name uses the tag or field name.
955 Value
: &NameInField
{},
956 ExpectXML
: `<NameInField><foo xmlns="ns"></foo></NameInField>`,
969 Bytes
: []byte("byt"),
971 ExpectXML
: `<AttrTest Int="8" int="9" Float="23.5" Uint8="255"` +
972 ` Bool="true" Str="str" Bytes="byt"></AttrTest>`,
975 Value
: &AttrTest
{Bytes
: []byte{}},
976 ExpectXML
: `<AttrTest Int="0" int="0" Float="0" Uint8="0"` +
977 ` Bool="false" Str="" Bytes=""></AttrTest>`,
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"},
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>`,
998 {Name
: Name
{Local
: "Answer"}, Value
: "42"},
1006 Bytes
: []byte("byt"),
1008 ExpectXML
: `<AttrsTest Answer="42" Int="8" int="9" Float="23.5" Uint8="255" Bool="true" Str="str" Bytes="byt"></AttrsTest>`,
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"}},
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>`,
1027 Value
: &OmitAttrTest
{
1034 Bytes
: []byte("byt"),
1037 ExpectXML
: `<OmitAttrTest Int="8" int="9" Float="23.5" Uint8="255"` +
1038 ` Bool="true" Str="str" Bytes="byt" PStr=""></OmitAttrTest>`,
1041 Value
: &OmitAttrTest
{},
1042 ExpectXML
: `<OmitAttrTest></OmitAttrTest>`,
1047 Value
: &PointerFieldsTest
{Name
: &nameAttr
, Age
: &ageAttr
, Contents
: &contentsAttr
},
1048 ExpectXML
: `<dummy name="Sarah" age="12">lorem ipsum</dummy>`,
1052 // empty chardata pointer field
1054 Value
: &ChardataEmptyTest
{},
1055 ExpectXML
: `<test></test>`,
1059 // omitempty on fields
1061 Value
: &OmitFieldTest
{
1068 Bytes
: []byte("byt"),
1070 Ptr
: &PresenceTest
{},
1072 ExpectXML
: `<OmitFieldTest>` +
1075 `<Float>23.5</Float>` +
1076 `<Uint8>255</Uint8>` +
1077 `<Bool>true</Bool>` +
1079 `<Bytes>byt</Bytes>` +
1085 Value
: &OmitFieldTest
{},
1086 ExpectXML
: `<OmitFieldTest></OmitFieldTest>`,
1091 ExpectXML
: `<a><nested><value>known</value></nested><other><sub>unknown</sub></other></a>`,
1094 AnyField
: AnyHolder
{
1095 XMLName
: Name
{Local
: "other"},
1096 XML
: "<sub>unknown</sub>",
1101 Value
: &AnyTest
{Nested
: "known",
1102 AnyField
: AnyHolder
{
1104 XMLName
: Name
{Local
: "AnyField"},
1107 ExpectXML
: `<a><nested><value>known</value></nested><AnyField><unknown/></AnyField></a>`,
1110 ExpectXML
: `<a><nested><value>b</value></nested></a>`,
1111 Value
: &AnyOmitTest
{
1116 ExpectXML
: `<a><nested><value>b</value></nested><c><d>e</d></c><g xmlns="f"><h>i</h></g></a>`,
1117 Value
: &AnySliceTest
{
1119 AnyField
: []AnyHolder
{
1121 XMLName
: Name
{Local
: "c"},
1125 XMLName
: Name
{Space
: "f", Local
: "g"},
1132 ExpectXML
: `<a><nested><value>b</value></nested></a>`,
1133 Value
: &AnySliceTest
{
1138 // Test recursive types.
1143 A
: &RecurseA
{"a2", nil},
1147 ExpectXML
: `<RecurseA><A>a1</A><B><A><A>a2</A></A><B>b1</B></B></RecurseA>`,
1150 // Test ignoring fields via "-" tag
1152 ExpectXML
: `<IgnoreTest></IgnoreTest>`,
1153 Value
: &IgnoreTest
{},
1156 ExpectXML
: `<IgnoreTest></IgnoreTest>`,
1157 Value
: &IgnoreTest
{PublicSecret
: "can't tell"},
1161 ExpectXML
: `<IgnoreTest><PublicSecret>ignore me</PublicSecret></IgnoreTest>`,
1162 Value
: &IgnoreTest
{},
1163 UnmarshalOnly
: true,
1168 ExpectXML
: `<a><nested><value>dquote: "; squote: '; ampersand: &; less: <; greater: >;</value></nested><empty></empty></a>`,
1170 Nested
: `dquote: "; squote: '; ampersand: &; less: <; greater: >;`,
1171 AnyField
: AnyHolder
{XMLName
: Name
{Local
: "empty"}},
1175 ExpectXML
: `<a><nested><value>newline: 
; cr: 
; tab: 	;</value></nested><AnyField></AnyField></a>`,
1177 Nested
: "newline: \n; cr: \r; tab: \t;",
1178 AnyField
: AnyHolder
{XMLName
: Name
{Local
: "AnyField"}},
1182 ExpectXML
: "<a><nested><value>1\r2\r\n3\n\r4\n5</value></nested></a>",
1184 Nested
: "1\n2\n3\n\n4\n5",
1186 UnmarshalOnly
: true,
1189 ExpectXML
: `<EmbedInt><MyInt>42</MyInt></EmbedInt>`,
1194 // Test outputting CDATA-wrapped text.
1196 ExpectXML
: `<CDataTest></CDataTest>`,
1197 Value
: &CDataTest
{},
1200 ExpectXML
: `<CDataTest><![CDATA[http://example.com/tests/1?foo=1&bar=baz]]></CDataTest>`,
1202 Chardata
: "http://example.com/tests/1?foo=1&bar=baz",
1206 ExpectXML
: `<CDataTest><![CDATA[Literal <![CDATA[Nested]]]]><![CDATA[>!]]></CDataTest>`,
1208 Chardata
: "Literal <![CDATA[Nested]]>!",
1212 ExpectXML
: `<CDataTest><![CDATA[<![CDATA[Nested]]]]><![CDATA[> Literal!]]></CDataTest>`,
1214 Chardata
: "<![CDATA[Nested]]> Literal!",
1218 ExpectXML
: `<CDataTest><![CDATA[<![CDATA[Nested]]]]><![CDATA[> Literal! <![CDATA[Nested]]]]><![CDATA[> Literal!]]></CDataTest>`,
1220 Chardata
: "<![CDATA[Nested]]> Literal! <![CDATA[Nested]]> Literal!",
1224 ExpectXML
: `<CDataTest><![CDATA[<![CDATA[<![CDATA[Nested]]]]><![CDATA[>]]]]><![CDATA[>]]></CDataTest>`,
1226 Chardata
: "<![CDATA[<![CDATA[Nested]]>]]>",
1230 // Test omitempty with parent chain; see golang.org/issue/4168.
1232 ExpectXML
: `<Strings><A></A></Strings>`,
1235 // Custom marshalers.
1237 ExpectXML
: `<MyMarshalerTest>hello world</MyMarshalerTest>`,
1238 Value
: &MyMarshalerTest
{},
1241 ExpectXML
: `<MarshalerStruct Foo="hello world"></MarshalerStruct>`,
1242 Value
: &MarshalerStruct
{},
1245 ExpectXML
: `<outer xmlns="testns" int="10"></outer>`,
1246 Value
: &OuterStruct
{IntAttr
: 10},
1249 ExpectXML
: `<test xmlns="outerns" int="10"></test>`,
1250 Value
: &OuterNamedStruct
{XMLName
: Name
{Space
: "outerns", Local
: "test"}, IntAttr
: 10},
1253 ExpectXML
: `<test xmlns="outerns" int="10"></test>`,
1254 Value
: &OuterNamedOrderedStruct
{XMLName
: Name
{Space
: "outerns", Local
: "test"}, IntAttr
: 10},
1257 ExpectXML
: `<outer xmlns="testns" int="10"></outer>`,
1258 Value
: &OuterOuterStruct
{OuterStruct
{IntAttr
: 10}},
1261 ExpectXML
: `<NestedAndChardata><A><B></B><B></B></A>test</NestedAndChardata>`,
1262 Value
: &NestedAndChardata
{AB
: make([]string, 2), Chardata
: "test"},
1265 ExpectXML
: `<NestedAndComment><A><B></B><B></B></A><!--test--></NestedAndComment>`,
1266 Value
: &NestedAndComment
{AB
: make([]string, 2), Comment
: "test"},
1269 ExpectXML
: `<NestedAndCData><A><B></B><B></B></A><![CDATA[test]]></NestedAndCData>`,
1270 Value
: &NestedAndCData
{AB
: make([]string, 2), CDATA
: "test"},
1272 // Test pointer indirection in various kinds of fields.
1273 // https://golang.org/issue/19063
1275 ExpectXML
: `<IndirComment><T1></T1><!--hi--><T2></T2></IndirComment>`,
1276 Value
: &IndirComment
{Comment
: stringptr("hi")},
1280 ExpectXML
: `<IndirComment><T1></T1><T2></T2></IndirComment>`,
1281 Value
: &IndirComment
{Comment
: stringptr("")},
1285 ExpectXML
: `<IndirComment><T1></T1><T2></T2></IndirComment>`,
1286 Value
: &IndirComment
{Comment
: nil},
1287 MarshalError
: "xml: bad type for comment field of xml.IndirComment",
1290 ExpectXML
: `<IndirComment><T1></T1><!--hi--><T2></T2></IndirComment>`,
1291 Value
: &IndirComment
{Comment
: nil},
1292 UnmarshalOnly
: true,
1295 ExpectXML
: `<IfaceComment><T1></T1><!--hi--><T2></T2></IfaceComment>`,
1296 Value
: &IfaceComment
{Comment
: "hi"},
1300 ExpectXML
: `<IfaceComment><T1></T1><!--hi--><T2></T2></IfaceComment>`,
1301 Value
: &IfaceComment
{Comment
: nil},
1302 UnmarshalOnly
: true,
1305 ExpectXML
: `<IfaceComment><T1></T1><T2></T2></IfaceComment>`,
1306 Value
: &IfaceComment
{Comment
: nil},
1307 MarshalError
: "xml: bad type for comment field of xml.IfaceComment",
1310 ExpectXML
: `<IfaceComment><T1></T1><T2></T2></IfaceComment>`,
1311 Value
: &IfaceComment
{Comment
: nil},
1312 UnmarshalOnly
: true,
1315 ExpectXML
: `<DirectComment><T1></T1><!--hi--><T2></T2></DirectComment>`,
1316 Value
: &DirectComment
{Comment
: string("hi")},
1319 ExpectXML
: `<DirectComment><T1></T1><T2></T2></DirectComment>`,
1320 Value
: &DirectComment
{Comment
: string("")},
1323 ExpectXML
: `<IndirChardata><T1></T1>hi<T2></T2></IndirChardata>`,
1324 Value
: &IndirChardata
{Chardata
: stringptr("hi")},
1327 ExpectXML
: `<IndirChardata><T1></T1><![CDATA[hi]]><T2></T2></IndirChardata>`,
1328 Value
: &IndirChardata
{Chardata
: stringptr("hi")},
1329 UnmarshalOnly
: true, // marshals without CDATA
1332 ExpectXML
: `<IndirChardata><T1></T1><T2></T2></IndirChardata>`,
1333 Value
: &IndirChardata
{Chardata
: stringptr("")},
1336 ExpectXML
: `<IndirChardata><T1></T1><T2></T2></IndirChardata>`,
1337 Value
: &IndirChardata
{Chardata
: nil},
1338 MarshalOnly
: true, // unmarshal leaves Chardata=stringptr("")
1341 ExpectXML
: `<IfaceChardata><T1></T1>hi<T2></T2></IfaceChardata>`,
1342 Value
: &IfaceChardata
{Chardata
: string("hi")},
1343 UnmarshalError
: "cannot unmarshal into interface {}",
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 {}",
1352 ExpectXML
: `<IfaceChardata><T1></T1><T2></T2></IfaceChardata>`,
1353 Value
: &IfaceChardata
{Chardata
: string("")},
1354 UnmarshalError
: "cannot unmarshal into interface {}",
1357 ExpectXML
: `<IfaceChardata><T1></T1><T2></T2></IfaceChardata>`,
1358 Value
: &IfaceChardata
{Chardata
: nil},
1359 UnmarshalError
: "cannot unmarshal into interface {}",
1362 ExpectXML
: `<DirectChardata><T1></T1>hi<T2></T2></DirectChardata>`,
1363 Value
: &DirectChardata
{Chardata
: string("hi")},
1366 ExpectXML
: `<DirectChardata><T1></T1><![CDATA[hi]]><T2></T2></DirectChardata>`,
1367 Value
: &DirectChardata
{Chardata
: string("hi")},
1368 UnmarshalOnly
: true, // marshals without CDATA
1371 ExpectXML
: `<DirectChardata><T1></T1><T2></T2></DirectChardata>`,
1372 Value
: &DirectChardata
{Chardata
: string("")},
1375 ExpectXML
: `<IndirCDATA><T1></T1><![CDATA[hi]]><T2></T2></IndirCDATA>`,
1376 Value
: &IndirCDATA
{CDATA
: stringptr("hi")},
1379 ExpectXML
: `<IndirCDATA><T1></T1>hi<T2></T2></IndirCDATA>`,
1380 Value
: &IndirCDATA
{CDATA
: stringptr("hi")},
1381 UnmarshalOnly
: true, // marshals with CDATA
1384 ExpectXML
: `<IndirCDATA><T1></T1><T2></T2></IndirCDATA>`,
1385 Value
: &IndirCDATA
{CDATA
: stringptr("")},
1388 ExpectXML
: `<IndirCDATA><T1></T1><T2></T2></IndirCDATA>`,
1389 Value
: &IndirCDATA
{CDATA
: nil},
1390 MarshalOnly
: true, // unmarshal leaves CDATA=stringptr("")
1393 ExpectXML
: `<IfaceCDATA><T1></T1><![CDATA[hi]]><T2></T2></IfaceCDATA>`,
1394 Value
: &IfaceCDATA
{CDATA
: string("hi")},
1395 UnmarshalError
: "cannot unmarshal into interface {}",
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 {}",
1404 ExpectXML
: `<IfaceCDATA><T1></T1><T2></T2></IfaceCDATA>`,
1405 Value
: &IfaceCDATA
{CDATA
: string("")},
1406 UnmarshalError
: "cannot unmarshal into interface {}",
1409 ExpectXML
: `<IfaceCDATA><T1></T1><T2></T2></IfaceCDATA>`,
1410 Value
: &IfaceCDATA
{CDATA
: nil},
1411 UnmarshalError
: "cannot unmarshal into interface {}",
1414 ExpectXML
: `<DirectCDATA><T1></T1><![CDATA[hi]]><T2></T2></DirectCDATA>`,
1415 Value
: &DirectCDATA
{CDATA
: string("hi")},
1418 ExpectXML
: `<DirectCDATA><T1></T1>hi<T2></T2></DirectCDATA>`,
1419 Value
: &DirectCDATA
{CDATA
: string("hi")},
1420 UnmarshalOnly
: true, // marshals with CDATA
1423 ExpectXML
: `<DirectCDATA><T1></T1><T2></T2></DirectCDATA>`,
1424 Value
: &DirectCDATA
{CDATA
: string("")},
1427 ExpectXML
: `<IndirInnerXML><T1></T1><hi/><T2></T2></IndirInnerXML>`,
1428 Value
: &IndirInnerXML
{InnerXML
: stringptr("<hi/>")},
1432 ExpectXML
: `<IndirInnerXML><T1></T1><T2></T2></IndirInnerXML>`,
1433 Value
: &IndirInnerXML
{InnerXML
: stringptr("")},
1437 ExpectXML
: `<IndirInnerXML><T1></T1><T2></T2></IndirInnerXML>`,
1438 Value
: &IndirInnerXML
{InnerXML
: nil},
1441 ExpectXML
: `<IndirInnerXML><T1></T1><hi/><T2></T2></IndirInnerXML>`,
1442 Value
: &IndirInnerXML
{InnerXML
: nil},
1443 UnmarshalOnly
: true,
1446 ExpectXML
: `<IfaceInnerXML><T1></T1><hi/><T2></T2></IfaceInnerXML>`,
1447 Value
: &IfaceInnerXML
{InnerXML
: "<hi/>"},
1451 ExpectXML
: `<IfaceInnerXML><T1></T1><hi/><T2></T2></IfaceInnerXML>`,
1452 Value
: &IfaceInnerXML
{InnerXML
: nil},
1453 UnmarshalOnly
: true,
1456 ExpectXML
: `<IfaceInnerXML><T1></T1><T2></T2></IfaceInnerXML>`,
1457 Value
: &IfaceInnerXML
{InnerXML
: nil},
1460 ExpectXML
: `<IfaceInnerXML><T1></T1><T2></T2></IfaceInnerXML>`,
1461 Value
: &IfaceInnerXML
{InnerXML
: nil},
1462 UnmarshalOnly
: true,
1465 ExpectXML
: `<DirectInnerXML><T1></T1><hi/><T2></T2></DirectInnerXML>`,
1466 Value
: &DirectInnerXML
{InnerXML
: string("<hi/>")},
1470 ExpectXML
: `<DirectInnerXML><T1></T1><hi/><T2></T2></DirectInnerXML>`,
1471 Value
: &DirectInnerXML
{InnerXML
: string("<T1></T1><hi/><T2></T2>")},
1472 UnmarshalOnly
: true,
1475 ExpectXML
: `<DirectInnerXML><T1></T1><T2></T2></DirectInnerXML>`,
1476 Value
: &DirectInnerXML
{InnerXML
: string("")},
1480 ExpectXML
: `<DirectInnerXML><T1></T1><T2></T2></DirectInnerXML>`,
1481 Value
: &DirectInnerXML
{InnerXML
: string("<T1></T1><T2></T2>")},
1482 UnmarshalOnly
: true,
1485 ExpectXML
: `<IndirElement><T1></T1><Element>hi</Element><T2></T2></IndirElement>`,
1486 Value
: &IndirElement
{Element
: stringptr("hi")},
1489 ExpectXML
: `<IndirElement><T1></T1><Element></Element><T2></T2></IndirElement>`,
1490 Value
: &IndirElement
{Element
: stringptr("")},
1493 ExpectXML
: `<IndirElement><T1></T1><T2></T2></IndirElement>`,
1494 Value
: &IndirElement
{Element
: nil},
1497 ExpectXML
: `<IfaceElement><T1></T1><Element>hi</Element><T2></T2></IfaceElement>`,
1498 Value
: &IfaceElement
{Element
: "hi"},
1502 ExpectXML
: `<IfaceElement><T1></T1><Element>hi</Element><T2></T2></IfaceElement>`,
1503 Value
: &IfaceElement
{Element
: nil},
1504 UnmarshalOnly
: true,
1507 ExpectXML
: `<IfaceElement><T1></T1><T2></T2></IfaceElement>`,
1508 Value
: &IfaceElement
{Element
: nil},
1511 ExpectXML
: `<IfaceElement><T1></T1><T2></T2></IfaceElement>`,
1512 Value
: &IfaceElement
{Element
: nil},
1513 UnmarshalOnly
: true,
1516 ExpectXML
: `<DirectElement><T1></T1><Element>hi</Element><T2></T2></DirectElement>`,
1517 Value
: &DirectElement
{Element
: string("hi")},
1520 ExpectXML
: `<DirectElement><T1></T1><Element></Element><T2></T2></DirectElement>`,
1521 Value
: &DirectElement
{Element
: string("")},
1524 ExpectXML
: `<IndirOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></IndirOmitEmpty>`,
1525 Value
: &IndirOmitEmpty
{OmitEmpty
: stringptr("hi")},
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("")},
1534 ExpectXML
: `<IndirOmitEmpty><T1></T1><OmitEmpty></OmitEmpty><T2></T2></IndirOmitEmpty>`,
1535 Value
: &IndirOmitEmpty
{OmitEmpty
: stringptr("")},
1536 UnmarshalOnly
: true,
1539 ExpectXML
: `<IndirOmitEmpty><T1></T1><T2></T2></IndirOmitEmpty>`,
1540 Value
: &IndirOmitEmpty
{OmitEmpty
: nil},
1543 ExpectXML
: `<IfaceOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></IfaceOmitEmpty>`,
1544 Value
: &IfaceOmitEmpty
{OmitEmpty
: "hi"},
1548 ExpectXML
: `<IfaceOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></IfaceOmitEmpty>`,
1549 Value
: &IfaceOmitEmpty
{OmitEmpty
: nil},
1550 UnmarshalOnly
: true,
1553 ExpectXML
: `<IfaceOmitEmpty><T1></T1><T2></T2></IfaceOmitEmpty>`,
1554 Value
: &IfaceOmitEmpty
{OmitEmpty
: nil},
1557 ExpectXML
: `<IfaceOmitEmpty><T1></T1><T2></T2></IfaceOmitEmpty>`,
1558 Value
: &IfaceOmitEmpty
{OmitEmpty
: nil},
1559 UnmarshalOnly
: true,
1562 ExpectXML
: `<DirectOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></DirectOmitEmpty>`,
1563 Value
: &DirectOmitEmpty
{OmitEmpty
: string("hi")},
1566 ExpectXML
: `<DirectOmitEmpty><T1></T1><T2></T2></DirectOmitEmpty>`,
1567 Value
: &DirectOmitEmpty
{OmitEmpty
: string("")},
1570 ExpectXML
: `<IndirAny><T1></T1><Any>hi</Any><T2></T2></IndirAny>`,
1571 Value
: &IndirAny
{Any
: stringptr("hi")},
1574 ExpectXML
: `<IndirAny><T1></T1><Any></Any><T2></T2></IndirAny>`,
1575 Value
: &IndirAny
{Any
: stringptr("")},
1578 ExpectXML
: `<IndirAny><T1></T1><T2></T2></IndirAny>`,
1579 Value
: &IndirAny
{Any
: nil},
1582 ExpectXML
: `<IfaceAny><T1></T1><Any>hi</Any><T2></T2></IfaceAny>`,
1583 Value
: &IfaceAny
{Any
: "hi"},
1587 ExpectXML
: `<IfaceAny><T1></T1><Any>hi</Any><T2></T2></IfaceAny>`,
1588 Value
: &IfaceAny
{Any
: nil},
1589 UnmarshalOnly
: true,
1592 ExpectXML
: `<IfaceAny><T1></T1><T2></T2></IfaceAny>`,
1593 Value
: &IfaceAny
{Any
: nil},
1596 ExpectXML
: `<IfaceAny><T1></T1><T2></T2></IfaceAny>`,
1597 Value
: &IfaceAny
{Any
: nil},
1598 UnmarshalOnly
: true,
1601 ExpectXML
: `<DirectAny><T1></T1><Any>hi</Any><T2></T2></DirectAny>`,
1602 Value
: &DirectAny
{Any
: string("hi")},
1605 ExpectXML
: `<DirectAny><T1></T1><Any></Any><T2></T2></DirectAny>`,
1606 Value
: &DirectAny
{Any
: string("")},
1609 ExpectXML
: `<IndirFoo><T1></T1><Foo>hi</Foo><T2></T2></IndirFoo>`,
1610 Value
: &IndirAny
{Any
: stringptr("hi")},
1611 UnmarshalOnly
: true,
1614 ExpectXML
: `<IndirFoo><T1></T1><Foo></Foo><T2></T2></IndirFoo>`,
1615 Value
: &IndirAny
{Any
: stringptr("")},
1616 UnmarshalOnly
: true,
1619 ExpectXML
: `<IndirFoo><T1></T1><T2></T2></IndirFoo>`,
1620 Value
: &IndirAny
{Any
: nil},
1621 UnmarshalOnly
: true,
1624 ExpectXML
: `<IfaceFoo><T1></T1><Foo>hi</Foo><T2></T2></IfaceFoo>`,
1625 Value
: &IfaceAny
{Any
: nil},
1626 UnmarshalOnly
: true,
1629 ExpectXML
: `<IfaceFoo><T1></T1><T2></T2></IfaceFoo>`,
1630 Value
: &IfaceAny
{Any
: nil},
1631 UnmarshalOnly
: true,
1634 ExpectXML
: `<IfaceFoo><T1></T1><T2></T2></IfaceFoo>`,
1635 Value
: &IfaceAny
{Any
: nil},
1636 UnmarshalOnly
: true,
1639 ExpectXML
: `<DirectFoo><T1></T1><Foo>hi</Foo><T2></T2></DirectFoo>`,
1640 Value
: &DirectAny
{Any
: string("hi")},
1641 UnmarshalOnly
: true,
1644 ExpectXML
: `<DirectFoo><T1></T1><Foo></Foo><T2></T2></DirectFoo>`,
1645 Value
: &DirectAny
{Any
: string("")},
1646 UnmarshalOnly
: true,
1650 func TestMarshal(t
*testing
.T
) {
1651 for idx
, test
:= range marshalTests
{
1652 if test
.UnmarshalOnly
{
1656 t
.Run(fmt
.Sprintf("%d", idx
), func(t
*testing
.T
) {
1657 data
, err
:= Marshal(test
.Value
)
1659 if test
.MarshalError
== "" {
1660 t
.Errorf("marshal(%#v): %s", test
.Value
, err
)
1663 if !strings
.Contains(err
.Error(), test
.MarshalError
) {
1664 t
.Errorf("marshal(%#v): %s, want %q", test
.Value
, err
, test
.MarshalError
)
1668 if test
.MarshalError
!= "" {
1669 t
.Errorf("Marshal succeeded, want error %q", test
.MarshalError
)
1672 if got
, want
:= string(data
), test
.ExpectXML
; got
!= want
{
1673 if strings
.Contains(want
, "\n") {
1674 t
.Errorf("marshal(%#v):\nHAVE:\n%s\nWANT:\n%s", test
.Value
, got
, want
)
1676 t
.Errorf("marshal(%#v):\nhave %#q\nwant %#q", test
.Value
, got
, want
)
1683 type AttrParent
struct {
1684 X
string `xml:"X>Y,attr"`
1687 type BadAttr
struct {
1688 Name
map[string]string `xml:"name,attr"`
1691 var marshalErrorTests
= []struct {
1697 Value
: make(chan bool),
1698 Err
: "xml: unsupported type: chan bool",
1702 Value
: map[string]string{
1703 "question": "What do you get when you multiply six by nine?",
1706 Err
: "xml: unsupported type: map[string]string",
1710 Value
: map[*Ship
]bool{nil: false},
1711 Err
: "xml: unsupported type: map[*xml.Ship]bool",
1715 Value
: &Domain
{Comment
: []byte("f--bar")},
1716 Err
: `xml: comments must not contain "--"`,
1718 // Reject parent chain with attr, never worked; see golang.org/issue/5033.
1720 Value
: &AttrParent
{},
1721 Err
: `xml: X>Y chain not valid with attr flag`,
1724 Value
: BadAttr
{map[string]string{"X": "Y"}},
1725 Err
: `xml: unsupported type: map[string]string`,
1729 var marshalIndentTests
= []struct {
1736 Value
: &SecretAgent
{
1738 Identity
: "James Bond",
1739 Obfuscate
: "<redacted/>",
1743 ExpectXML
: fmt
.Sprintf("<agent handle=\"007\">\n\t<Identity>James Bond</Identity><redacted/>\n</agent>"),
1747 func TestMarshalErrors(t
*testing
.T
) {
1748 for idx
, test
:= range marshalErrorTests
{
1749 data
, err
:= Marshal(test
.Value
)
1751 t
.Errorf("#%d: marshal(%#v) = [success] %q, want error %v", idx
, test
.Value
, data
, test
.Err
)
1754 if err
.Error() != test
.Err
{
1755 t
.Errorf("#%d: marshal(%#v) = [error] %v, want %v", idx
, test
.Value
, err
, test
.Err
)
1757 if test
.Kind
!= reflect
.Invalid
{
1758 if kind
:= err
.(*UnsupportedTypeError
).Type
.Kind(); kind
!= test
.Kind
{
1759 t
.Errorf("#%d: marshal(%#v) = [error kind] %s, want %s", idx
, test
.Value
, kind
, test
.Kind
)
1765 // Do invertibility testing on the various structures that we test
1766 func TestUnmarshal(t
*testing
.T
) {
1767 for i
, test
:= range marshalTests
{
1768 if test
.MarshalOnly
{
1771 if _
, ok
:= test
.Value
.(*Plain
); ok
{
1774 if test
.ExpectXML
== `<top>`+
1775 `<x><b xmlns="space">b</b>`+
1776 `<b xmlns="space1">b1</b></x>`+
1778 // TODO(rogpeppe): re-enable this test in
1779 // https://go-review.googlesource.com/#/c/5910/
1783 vt
:= reflect
.TypeOf(test
.Value
)
1784 dest
:= reflect
.New(vt
.Elem()).Interface()
1785 err
:= Unmarshal([]byte(test
.ExpectXML
), dest
)
1787 t
.Run(fmt
.Sprintf("%d", i
), func(t
*testing
.T
) {
1788 switch fix
:= dest
.(type) {
1790 fix
.Author
.InnerXML
= ""
1791 for i
:= range fix
.Entry
{
1792 fix
.Entry
[i
].Author
.InnerXML
= ""
1797 if test
.UnmarshalError
== "" {
1798 t
.Errorf("unmarshal(%#v): %s", test
.ExpectXML
, err
)
1801 if !strings
.Contains(err
.Error(), test
.UnmarshalError
) {
1802 t
.Errorf("unmarshal(%#v): %s, want %q", test
.ExpectXML
, err
, test
.UnmarshalError
)
1806 if got
, want
:= dest
, test
.Value
; !reflect
.DeepEqual(got
, want
) {
1807 t
.Errorf("unmarshal(%q):\nhave %#v\nwant %#v", test
.ExpectXML
, got
, want
)
1813 func TestMarshalIndent(t
*testing
.T
) {
1814 for i
, test
:= range marshalIndentTests
{
1815 data
, err
:= MarshalIndent(test
.Value
, test
.Prefix
, test
.Indent
)
1817 t
.Errorf("#%d: Error: %s", i
, err
)
1820 if got
, want
:= string(data
), test
.ExpectXML
; got
!= want
{
1821 t
.Errorf("#%d: MarshalIndent:\nGot:%s\nWant:\n%s", i
, got
, want
)
1826 type limitedBytesWriter
struct {
1828 remain
int // until writes fail
1831 func (lw
*limitedBytesWriter
) Write(p
[]byte) (n
int, err error
) {
1834 return 0, errors
.New("write limit hit")
1836 if len(p
) > lw
.remain
{
1838 n
, _
= lw
.w
.Write(p
)
1840 return n
, errors
.New("write limit hit")
1842 n
, err
= lw
.w
.Write(p
)
1847 func TestMarshalWriteErrors(t
*testing
.T
) {
1848 var buf bytes
.Buffer
1849 const writeCap
= 1024
1850 w
:= &limitedBytesWriter
{&buf
, writeCap
}
1851 enc
:= NewEncoder(w
)
1855 for i
= 1; i
<= n
; i
++ {
1856 err
= enc
.Encode(&Passenger
{
1857 Name
: []string{"Alice", "Bob"},
1865 t
.Error("expected an error")
1868 t
.Errorf("expected to fail before the end")
1870 if buf
.Len() != writeCap
{
1871 t
.Errorf("buf.Len() = %d; want %d", buf
.Len(), writeCap
)
1875 func TestMarshalWriteIOErrors(t
*testing
.T
) {
1876 enc
:= NewEncoder(errWriter
{})
1878 expectErr
:= "unwritable"
1879 err
:= enc
.Encode(&Passenger
{})
1880 if err
== nil || err
.Error() != expectErr
{
1881 t
.Errorf("EscapeTest = [error] %v, want %v", err
, expectErr
)
1885 func TestMarshalFlush(t
*testing
.T
) {
1886 var buf bytes
.Buffer
1887 enc
:= NewEncoder(&buf
)
1888 if err
:= enc
.EncodeToken(CharData("hello world")); err
!= nil {
1889 t
.Fatalf("enc.EncodeToken: %v", err
)
1892 t
.Fatalf("enc.EncodeToken caused actual write: %q", buf
.Bytes())
1894 if err
:= enc
.Flush(); err
!= nil {
1895 t
.Fatalf("enc.Flush: %v", err
)
1897 if buf
.String() != "hello world" {
1898 t
.Fatalf("after enc.Flush, buf.String() = %q, want %q", buf
.String(), "hello world")
1902 func BenchmarkMarshal(b
*testing
.B
) {
1904 b
.RunParallel(func(pb
*testing
.PB
) {
1911 func BenchmarkUnmarshal(b
*testing
.B
) {
1913 xml
:= []byte(atomXml
)
1914 b
.RunParallel(func(pb
*testing
.PB
) {
1916 Unmarshal(xml
, &Feed
{})
1921 // golang.org/issue/6556
1922 func TestStructPointerMarshal(t
*testing
.T
) {
1924 XMLName
string `xml:"a"`
1929 Value
string `xml:"value"`
1933 a
.B
= append(a
.B
, &C
{
1934 XMLName
: Name
{Local
: "c"},
1938 b
, err
:= Marshal(a
)
1942 if x
:= string(b
); x
!= "<a><c><value>x</value></c></a>" {
1946 err
= Unmarshal(b
, &v
)
1952 var encodeTokenTests
= []struct {
1958 desc
: "start element with name space",
1960 StartElement
{Name
{"space", "local"}, nil},
1962 want
: `<local xmlns="space">`,
1964 desc
: "start element with no name",
1966 StartElement
{Name
{"space", ""}, nil},
1968 err
: "xml: start tag with no name",
1970 desc
: "end element with no name",
1972 EndElement
{Name
{"space", ""}},
1974 err
: "xml: end tag with no name",
1982 desc
: "char data with escaped chars",
1994 desc
: "comment with invalid content",
1998 err
: "xml: EncodeToken of Comment containing --> marker",
2000 desc
: "proc instruction",
2002 ProcInst
{"Target", []byte("Instruction")},
2004 want
: `<?Target Instruction?>`,
2006 desc
: "proc instruction with empty target",
2008 ProcInst
{"", []byte("Instruction")},
2010 err
: "xml: EncodeToken of ProcInst with invalid Target",
2012 desc
: "proc instruction with bad content",
2014 ProcInst
{"", []byte("Instruction?>")},
2016 err
: "xml: EncodeToken of ProcInst with invalid Target",
2024 desc
: "more complex directive",
2026 Directive("DOCTYPE doc [ <!ELEMENT doc '>'> <!-- com>ment --> ]"),
2028 want
: `<!DOCTYPE doc [ <!ELEMENT doc '>'> <!-- com>ment --> ]>`,
2030 desc
: "directive instruction with bad name",
2034 err
: "xml: EncodeToken of Directive containing wrong < or > markers",
2036 desc
: "end tag without start tag",
2038 EndElement
{Name
{"foo", "bar"}},
2040 err
: "xml: end tag </bar> without start tag",
2042 desc
: "mismatching end tag local name",
2044 StartElement
{Name
{"", "foo"}, nil},
2045 EndElement
{Name
{"", "bar"}},
2047 err
: "xml: end tag </bar> does not match start tag <foo>",
2050 desc
: "mismatching end tag namespace",
2052 StartElement
{Name
{"space", "foo"}, nil},
2053 EndElement
{Name
{"another", "foo"}},
2055 err
: "xml: end tag </foo> in namespace another does not match start tag <foo> in namespace space",
2056 want
: `<foo xmlns="space">`,
2058 desc
: "start element with explicit namespace",
2060 StartElement
{Name
{"space", "local"}, []Attr
{
2061 {Name
{"xmlns", "x"}, "space"},
2062 {Name
{"space", "foo"}, "value"},
2065 want
: `<local xmlns="space" xmlns:_xmlns="xmlns" _xmlns:x="space" xmlns:space="space" space:foo="value">`,
2067 desc
: "start element with explicit namespace and colliding prefix",
2069 StartElement
{Name
{"space", "local"}, []Attr
{
2070 {Name
{"xmlns", "x"}, "space"},
2071 {Name
{"space", "foo"}, "value"},
2072 {Name
{"x", "bar"}, "other"},
2075 want
: `<local xmlns="space" xmlns:_xmlns="xmlns" _xmlns:x="space" xmlns:space="space" space:foo="value" xmlns:x="x" x:bar="other">`,
2077 desc
: "start element using previously defined namespace",
2079 StartElement
{Name
{"", "local"}, []Attr
{
2080 {Name
{"xmlns", "x"}, "space"},
2082 StartElement
{Name
{"space", "foo"}, []Attr
{
2083 {Name
{"space", "x"}, "y"},
2086 want
: `<local xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" xmlns:space="space" space:x="y">`,
2088 desc
: "nested name space with same prefix",
2090 StartElement
{Name
{"", "foo"}, []Attr
{
2091 {Name
{"xmlns", "x"}, "space1"},
2093 StartElement
{Name
{"", "foo"}, []Attr
{
2094 {Name
{"xmlns", "x"}, "space2"},
2096 StartElement
{Name
{"", "foo"}, []Attr
{
2097 {Name
{"space1", "a"}, "space1 value"},
2098 {Name
{"space2", "b"}, "space2 value"},
2100 EndElement
{Name
{"", "foo"}},
2101 EndElement
{Name
{"", "foo"}},
2102 StartElement
{Name
{"", "foo"}, []Attr
{
2103 {Name
{"space1", "a"}, "space1 value"},
2104 {Name
{"space2", "b"}, "space2 value"},
2107 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">`,
2109 desc
: "start element defining several prefixes for the same name space",
2111 StartElement
{Name
{"space", "foo"}, []Attr
{
2112 {Name
{"xmlns", "a"}, "space"},
2113 {Name
{"xmlns", "b"}, "space"},
2114 {Name
{"space", "x"}, "value"},
2117 want
: `<foo xmlns="space" xmlns:_xmlns="xmlns" _xmlns:a="space" _xmlns:b="space" xmlns:space="space" space:x="value">`,
2119 desc
: "nested element redefines name space",
2121 StartElement
{Name
{"", "foo"}, []Attr
{
2122 {Name
{"xmlns", "x"}, "space"},
2124 StartElement
{Name
{"space", "foo"}, []Attr
{
2125 {Name
{"xmlns", "y"}, "space"},
2126 {Name
{"space", "a"}, "value"},
2129 want
: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" _xmlns:y="space" xmlns:space="space" space:a="value">`,
2131 desc
: "nested element creates alias for default name space",
2133 StartElement
{Name
{"space", "foo"}, []Attr
{
2134 {Name
{"", "xmlns"}, "space"},
2136 StartElement
{Name
{"space", "foo"}, []Attr
{
2137 {Name
{"xmlns", "y"}, "space"},
2138 {Name
{"space", "a"}, "value"},
2141 want
: `<foo xmlns="space" xmlns="space"><foo xmlns="space" xmlns:_xmlns="xmlns" _xmlns:y="space" xmlns:space="space" space:a="value">`,
2143 desc
: "nested element defines default name space with existing prefix",
2145 StartElement
{Name
{"", "foo"}, []Attr
{
2146 {Name
{"xmlns", "x"}, "space"},
2148 StartElement
{Name
{"space", "foo"}, []Attr
{
2149 {Name
{"", "xmlns"}, "space"},
2150 {Name
{"space", "a"}, "value"},
2153 want
: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" xmlns="space" xmlns:space="space" space:a="value">`,
2155 desc
: "nested element uses empty attribute name space when default ns defined",
2157 StartElement
{Name
{"space", "foo"}, []Attr
{
2158 {Name
{"", "xmlns"}, "space"},
2160 StartElement
{Name
{"space", "foo"}, []Attr
{
2161 {Name
{"", "attr"}, "value"},
2164 want
: `<foo xmlns="space" xmlns="space"><foo xmlns="space" attr="value">`,
2166 desc
: "redefine xmlns",
2168 StartElement
{Name
{"", "foo"}, []Attr
{
2169 {Name
{"foo", "xmlns"}, "space"},
2172 want
: `<foo xmlns:foo="foo" foo:xmlns="space">`,
2174 desc
: "xmlns with explicit name space #1",
2176 StartElement
{Name
{"space", "foo"}, []Attr
{
2177 {Name
{"xml", "xmlns"}, "space"},
2180 want
: `<foo xmlns="space" xmlns:_xml="xml" _xml:xmlns="space">`,
2182 desc
: "xmlns with explicit name space #2",
2184 StartElement
{Name
{"space", "foo"}, []Attr
{
2185 {Name
{xmlURL
, "xmlns"}, "space"},
2188 want
: `<foo xmlns="space" xml:xmlns="space">`,
2190 desc
: "empty name space declaration is ignored",
2192 StartElement
{Name
{"", "foo"}, []Attr
{
2193 {Name
{"xmlns", "foo"}, ""},
2196 want
: `<foo xmlns:_xmlns="xmlns" _xmlns:foo="">`,
2198 desc
: "attribute with no name is ignored",
2200 StartElement
{Name
{"", "foo"}, []Attr
{
2201 {Name
{"", ""}, "value"},
2206 desc
: "namespace URL with non-valid name",
2208 StartElement
{Name
{"/34", "foo"}, []Attr
{
2209 {Name
{"/34", "x"}, "value"},
2212 want
: `<foo xmlns="/34" xmlns:_="/34" _:x="value">`,
2214 desc
: "nested element resets default namespace to empty",
2216 StartElement
{Name
{"space", "foo"}, []Attr
{
2217 {Name
{"", "xmlns"}, "space"},
2219 StartElement
{Name
{"", "foo"}, []Attr
{
2220 {Name
{"", "xmlns"}, ""},
2221 {Name
{"", "x"}, "value"},
2222 {Name
{"space", "x"}, "value"},
2225 want
: `<foo xmlns="space" xmlns="space"><foo xmlns="" x="value" xmlns:space="space" space:x="value">`,
2227 desc
: "nested element requires empty default name space",
2229 StartElement
{Name
{"space", "foo"}, []Attr
{
2230 {Name
{"", "xmlns"}, "space"},
2232 StartElement
{Name
{"", "foo"}, nil},
2234 want
: `<foo xmlns="space" xmlns="space"><foo>`,
2236 desc
: "attribute uses name space from xmlns",
2238 StartElement
{Name
{"some/space", "foo"}, []Attr
{
2239 {Name
{"", "attr"}, "value"},
2240 {Name
{"some/space", "other"}, "other value"},
2243 want
: `<foo xmlns="some/space" attr="value" xmlns:space="some/space" space:other="other value">`,
2245 desc
: "default name space should not be used by attributes",
2247 StartElement
{Name
{"space", "foo"}, []Attr
{
2248 {Name
{"", "xmlns"}, "space"},
2249 {Name
{"xmlns", "bar"}, "space"},
2250 {Name
{"space", "baz"}, "foo"},
2252 StartElement
{Name
{"space", "baz"}, nil},
2253 EndElement
{Name
{"space", "baz"}},
2254 EndElement
{Name
{"space", "foo"}},
2256 want
: `<foo xmlns="space" xmlns="space" xmlns:_xmlns="xmlns" _xmlns:bar="space" xmlns:space="space" space:baz="foo"><baz xmlns="space"></baz></foo>`,
2258 desc
: "default name space not used by attributes, not explicitly defined",
2260 StartElement
{Name
{"space", "foo"}, []Attr
{
2261 {Name
{"", "xmlns"}, "space"},
2262 {Name
{"space", "baz"}, "foo"},
2264 StartElement
{Name
{"space", "baz"}, nil},
2265 EndElement
{Name
{"space", "baz"}},
2266 EndElement
{Name
{"space", "foo"}},
2268 want
: `<foo xmlns="space" xmlns="space" xmlns:space="space" space:baz="foo"><baz xmlns="space"></baz></foo>`,
2270 desc
: "impossible xmlns declaration",
2272 StartElement
{Name
{"", "foo"}, []Attr
{
2273 {Name
{"", "xmlns"}, "space"},
2275 StartElement
{Name
{"space", "bar"}, []Attr
{
2276 {Name
{"space", "attr"}, "value"},
2279 want
: `<foo xmlns="space"><bar xmlns="space" xmlns:space="space" space:attr="value">`,
2282 func TestEncodeToken(t
*testing
.T
) {
2284 for i
, tt
:= range encodeTokenTests
{
2285 var buf bytes
.Buffer
2286 enc
:= NewEncoder(&buf
)
2288 for j
, tok
:= range tt
.toks
{
2289 err
= enc
.EncodeToken(tok
)
2290 if err
!= nil && j
< len(tt
.toks
)-1 {
2291 t
.Errorf("#%d %s token #%d: %v", i
, tt
.desc
, j
, err
)
2295 errorf
:= func(f
string, a
...interface{}) {
2296 t
.Errorf("#%d %s token #%d:%s", i
, tt
.desc
, len(tt
.toks
)-1, fmt
.Sprintf(f
, a
...))
2299 case tt
.err
!= "" && err
== nil:
2300 errorf(" expected error; got none")
2302 case tt
.err
== "" && err
!= nil:
2303 errorf(" got error: %v", err
)
2305 case tt
.err
!= "" && err
!= nil && tt
.err
!= err
.Error():
2306 errorf(" error mismatch; got %v, want %v", err
, tt
.err
)
2309 if err
:= enc
.Flush(); err
!= nil {
2313 if got
:= buf
.String(); got
!= tt
.want
{
2314 errorf("\ngot %v\nwant %v", got
, tt
.want
)
2320 func TestProcInstEncodeToken(t
*testing
.T
) {
2321 var buf bytes
.Buffer
2322 enc
:= NewEncoder(&buf
)
2324 if err
:= enc
.EncodeToken(ProcInst
{"xml", []byte("Instruction")}); err
!= nil {
2325 t
.Fatalf("enc.EncodeToken: expected to be able to encode xml target ProcInst as first token, %s", err
)
2328 if err
:= enc
.EncodeToken(ProcInst
{"Target", []byte("Instruction")}); err
!= nil {
2329 t
.Fatalf("enc.EncodeToken: expected to be able to add non-xml target ProcInst")
2332 if err
:= enc
.EncodeToken(ProcInst
{"xml", []byte("Instruction")}); err
== nil {
2333 t
.Fatalf("enc.EncodeToken: expected to not be allowed to encode xml target ProcInst when not first token")
2337 func TestDecodeEncode(t
*testing
.T
) {
2338 var in
, out bytes
.Buffer
2339 in
.WriteString(`<?xml version="1.0" encoding="UTF-8"?>
2340 <?Target Instruction?>
2344 dec
:= NewDecoder(&in
)
2345 enc
:= NewEncoder(&out
)
2346 for tok
, err
:= dec
.Token(); err
== nil; tok
, err
= dec
.Token() {
2347 err
= enc
.EncodeToken(tok
)
2349 t
.Fatalf("enc.EncodeToken: Unable to encode token (%#v), %v", tok
, err
)
2354 // Issue 9796. Used to fail with GORACE="halt_on_error=1" -race.
2355 func TestRace9796(t
*testing
.T
) {
2360 var wg sync
.WaitGroup
2361 for i
:= 0; i
< 2; i
++ {
2371 func TestIsValidDirective(t
*testing
.T
) {
2375 "<!DOCTYPE '<' '>' '>' <!--nothing-->>",
2376 "<!DOCTYPE doc [ <!ELEMENT doc ANY> <!ELEMENT doc ANY> ]>",
2377 "<!DOCTYPE doc [ <!ELEMENT doc \"ANY> '<' <!E\" LEMENT '>' doc ANY> ]>",
2378 "<!DOCTYPE doc <!-- just>>>> a < comment --> [ <!ITEM anything> ] >",
2386 "<!dummy <!-- > -->",
2388 "<!DOCTYPE doc '>'",
2389 "<!DOCTYPE doc <!--comment>",
2391 for _
, s
:= range testOK
{
2392 if !isValidDirective(Directive(s
)) {
2393 t
.Errorf("Directive %q is expected to be valid", s
)
2396 for _
, s
:= range testKO
{
2397 if isValidDirective(Directive(s
)) {
2398 t
.Errorf("Directive %q is expected to be invalid", s
)
2403 // Issue 11719. EncodeToken used to silently eat tokens with an invalid type.
2404 func TestSimpleUseOfEncodeToken(t
*testing
.T
) {
2405 var buf bytes
.Buffer
2406 enc
:= NewEncoder(&buf
)
2407 if err
:= enc
.EncodeToken(&StartElement
{Name
: Name
{"", "object1"}}); err
== nil {
2408 t
.Errorf("enc.EncodeToken: pointer type should be rejected")
2410 if err
:= enc
.EncodeToken(&EndElement
{Name
: Name
{"", "object1"}}); err
== nil {
2411 t
.Errorf("enc.EncodeToken: pointer type should be rejected")
2413 if err
:= enc
.EncodeToken(StartElement
{Name
: Name
{"", "object2"}}); err
!= nil {
2414 t
.Errorf("enc.EncodeToken: StartElement %s", err
)
2416 if err
:= enc
.EncodeToken(EndElement
{Name
: Name
{"", "object2"}}); err
!= nil {
2417 t
.Errorf("enc.EncodeToken: EndElement %s", err
)
2419 if err
:= enc
.EncodeToken(Universe
{}); err
== nil {
2420 t
.Errorf("enc.EncodeToken: invalid type not caught")
2422 if err
:= enc
.Flush(); err
!= nil {
2423 t
.Errorf("enc.Flush: %s", err
)
2426 t
.Errorf("enc.EncodeToken: empty buffer")
2428 want
:= "<object2></object2>"
2429 if buf
.String() != want
{
2430 t
.Errorf("enc.EncodeToken: expected %q; got %q", want
, buf
.String())
2434 // Issue 16158. Decoder.unmarshalAttr ignores the return value of copyValue.
2435 func TestIssue16158(t
*testing
.T
) {
2436 const data
= `<foo b="HELLOWORLD"></foo>`
2437 err
:= Unmarshal([]byte(data
), &struct {
2438 B
byte `xml:"b,attr,omitempty"`
2441 t
.Errorf("Unmarshal: expected error, got nil")