Skip to content

Commit 92294cf

Browse files
committed
1 parent e165f62 commit 92294cf

File tree

6 files changed

+62
-64
lines changed

6 files changed

+62
-64
lines changed

marshal.go

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
)
1818

1919
const (
20-
// Header is a generic XML header suitable for use with the output of Marshal.
20+
// Header is a generic XML header suitable for use with the output of [Marshal].
2121
// This is not automatically added to any output of this package,
2222
// it is provided as a convenience.
2323
Header = `<?xml version="1.0" encoding="UTF-8"?>` + "\n"
@@ -34,7 +34,7 @@ const (
3434
//
3535
// The name for the XML elements is taken from, in order of preference:
3636
// - the tag on the XMLName field, if the data is a struct
37-
// - the value of the XMLName field of type Name
37+
// - the value of the XMLName field of type [Name]
3838
// - the tag of the struct field used to obtain the data
3939
// - the name of the struct field used to obtain the data
4040
// - the name of the marshaled type
@@ -62,9 +62,9 @@ const (
6262
// string of length zero.
6363
// - an anonymous struct field is handled as if the fields of its
6464
// value were part of the outer struct.
65-
// - a field implementing Marshaler is written by calling its MarshalXML
65+
// - a field implementing [Marshaler] is written by calling its MarshalXML
6666
// method.
67-
// - a field implementing encoding.TextMarshaler is written by encoding the
67+
// - a field implementing [encoding.TextMarshaler] is written by encoding the
6868
// result of its MarshalText method as text.
6969
//
7070
// If a field uses a tag "a>b>c", then the element c will be nested inside
@@ -74,7 +74,7 @@ const (
7474
// If the XML name for a struct field is defined by both the field tag and the
7575
// struct's XMLName field, the names must match.
7676
//
77-
// See MarshalIndent for an example.
77+
// See [MarshalIndent] for an example.
7878
//
7979
// Marshal will return an error if asked to marshal a channel, function, or map.
8080
func Marshal(v any) ([]byte, error) {
@@ -96,7 +96,7 @@ func Marshal(v any) ([]byte, error) {
9696
// By convention, arrays or slices are typically encoded as a sequence
9797
// of elements, one per entry.
9898
// Using start as the element tag is not required, but doing so
99-
// will enable Unmarshal to match the XML elements to the correct
99+
// will enable [Unmarshal] to match the XML elements to the correct
100100
// struct field.
101101
// One common implementation strategy is to construct a separate
102102
// value with a layout corresponding to the desired XML and then
@@ -114,17 +114,17 @@ type Marshaler interface {
114114
//
115115
// MarshalXMLAttr returns an XML attribute with the encoded value of the receiver.
116116
// Using name as the attribute name is not required, but doing so
117-
// will enable Unmarshal to match the attribute to the correct
117+
// will enable [Unmarshal] to match the attribute to the correct
118118
// struct field.
119-
// If MarshalXMLAttr returns the zero attribute Attr{}, no attribute
119+
// If MarshalXMLAttr returns the zero attribute [Attr]{}, no attribute
120120
// will be generated in the output.
121121
// MarshalXMLAttr is used only for struct fields with the
122122
// "attr" option in the field tag.
123123
type MarshalerAttr interface {
124124
MarshalXMLAttr(name Name) (Attr, error)
125125
}
126126

127-
// MarshalIndent works like Marshal, but each XML element begins on a new
127+
// MarshalIndent works like [Marshal], but each XML element begins on a new
128128
// indented line that starts with prefix and is followed by one or more
129129
// copies of indent according to the nesting depth.
130130
func MarshalIndent(v any, prefix, indent string) ([]byte, error) {
@@ -162,10 +162,10 @@ func (enc *Encoder) Indent(prefix, indent string) {
162162

163163
// Encode writes the XML encoding of v to the stream.
164164
//
165-
// See the documentation for Marshal for details about the conversion
165+
// See the documentation for [Marshal] for details about the conversion
166166
// of Go values to XML.
167167
//
168-
// Encode calls Flush before returning.
168+
// Encode calls [Encoder.Flush] before returning.
169169
func (enc *Encoder) Encode(v any) error {
170170
err := enc.p.marshalValue(reflect.ValueOf(v), nil, nil)
171171
if err != nil {
@@ -177,10 +177,10 @@ func (enc *Encoder) Encode(v any) error {
177177
// EncodeElement writes the XML encoding of v to the stream,
178178
// using start as the outermost tag in the encoding.
179179
//
180-
// See the documentation for Marshal for details about the conversion
180+
// See the documentation for [Marshal] for details about the conversion
181181
// of Go values to XML.
182182
//
183-
// EncodeElement calls Flush before returning.
183+
// EncodeElement calls [Encoder.Flush] before returning.
184184
func (enc *Encoder) EncodeElement(v any, start StartElement) error {
185185
err := enc.p.marshalValue(reflect.ValueOf(v), nil, &start)
186186
if err != nil {
@@ -196,16 +196,16 @@ var (
196196
)
197197

198198
// EncodeToken writes the given XML token to the stream.
199-
// It returns an error if StartElement and EndElement tokens are not properly matched.
199+
// It returns an error if [StartElement] and [EndElement] tokens are not properly matched.
200200
//
201-
// EncodeToken does not call Flush, because usually it is part of a larger operation
202-
// such as Encode or EncodeElement (or a custom Marshaler's MarshalXML invoked
201+
// EncodeToken does not call [Encoder.Flush], because usually it is part of a larger operation
202+
// such as [Encoder.Encode] or [Encoder.EncodeElement] (or a custom [Marshaler]'s MarshalXML invoked
203203
// during those), and those will call Flush when finished.
204204
// Callers that create an Encoder and then invoke EncodeToken directly, without
205205
// using Encode or EncodeElement, need to call Flush when finished to ensure
206206
// that the XML is written to the underlying writer.
207207
//
208-
// EncodeToken allows writing a ProcInst with Target set to "xml" only as the first token
208+
// EncodeToken allows writing a [ProcInst] with Target set to "xml" only as the first token
209209
// in the stream.
210210
func (enc *Encoder) EncodeToken(t Token) error {
211211

@@ -303,7 +303,7 @@ func isValidDirective(dir Directive) bool {
303303
}
304304

305305
// Flush flushes any buffered XML to the underlying writer.
306-
// See the EncodeToken documentation for details about when it is necessary.
306+
// See the [Encoder.EncodeToken] documentation for details about when it is necessary.
307307
func (enc *Encoder) Flush() error {
308308
return enc.p.w.Flush()
309309
}
@@ -455,9 +455,9 @@ func (p *printer) writePrefixAttr(prefix, uri string) {
455455
}
456456

457457
var (
458-
marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
459-
marshalerAttrType = reflect.TypeOf((*MarshalerAttr)(nil)).Elem()
460-
textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
458+
marshalerType = reflect.TypeFor[Marshaler]()
459+
marshalerAttrType = reflect.TypeFor[MarshalerAttr]()
460+
textMarshalerType = reflect.TypeFor[encoding.TextMarshaler]()
461461
)
462462

463463
// marshalValue writes one or more XML elements representing val.
@@ -586,10 +586,10 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
586586
}
587587
}
588588

589-
// If an xmlname was found, namespace must be overridden.
589+
// If an empty name was found, namespace is overridden with an empty space
590590
if tinfo.xmlname != nil && start.Name.Space == "" &&
591+
tinfo.xmlname.xmlns == "" && tinfo.xmlname.name == "" &&
591592
len(p.elements) != 0 && p.elements[len(p.elements)-1].xmlns != "" {
592-
// Add attr xmlns="" to override the outer tag namespace
593593
start.Attr = append(start.Attr, Attr{Name{Space: "", Local: xmlnsPrefix}, ""})
594594
}
595595

@@ -916,7 +916,7 @@ func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) (string, []
916916
// [...]byte
917917
var bytes []byte
918918
if val.CanAddr() {
919-
bytes = val.Slice(0, val.Len()).Bytes()
919+
bytes = val.Bytes()
920920
} else {
921921
bytes = make([]byte, val.Len())
922922
reflect.Copy(reflect.ValueOf(bytes), val)
@@ -1225,7 +1225,7 @@ func (s *parentStack) push(parents []string) error {
12251225
return nil
12261226
}
12271227

1228-
// UnsupportedTypeError is returned when Marshal encounters a type
1228+
// UnsupportedTypeError is returned when [Marshal] encounters a type
12291229
// that cannot be converted into XML.
12301230
type UnsupportedTypeError struct {
12311231
Type reflect.Type

read.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
// an XML element is an order-dependent collection of anonymous
2020
// values, while a data structure is an order-independent collection
2121
// of named values.
22-
// See package json for a textual representation more suitable
22+
// See [encoding/json] for a textual representation more suitable
2323
// to data structures.
2424

2525
// Unmarshal parses the XML-encoded data and stores the result in
@@ -100,7 +100,7 @@ import (
100100
// If Unmarshal encounters a field type that implements the Unmarshaler
101101
// interface, Unmarshal calls its UnmarshalXML method to produce the value from
102102
// the XML element. Otherwise, if the value implements
103-
// encoding.TextUnmarshaler, Unmarshal calls that value's UnmarshalText method.
103+
// [encoding.TextUnmarshaler], Unmarshal calls that value's UnmarshalText method.
104104
//
105105
// Unmarshal maps an XML element to a string or []byte by saving the
106106
// concatenation of that element's character data in the string or
@@ -109,7 +109,7 @@ import (
109109
// Unmarshal maps an attribute value to a string or []byte by saving
110110
// the value in the string or slice.
111111
//
112-
// Unmarshal maps an attribute value to an Attr by saving the attribute,
112+
// Unmarshal maps an attribute value to an [Attr] by saving the attribute,
113113
// including its name, in the Attr.
114114
//
115115
// Unmarshal maps an XML element or attribute value to a slice by
@@ -138,16 +138,16 @@ func Unmarshal(data []byte, v any) error {
138138
return NewDecoder(bytes.NewReader(data)).Decode(v)
139139
}
140140

141-
// Decode works like Unmarshal, except it reads the decoder
141+
// Decode works like [Unmarshal], except it reads the decoder
142142
// stream to find the start element.
143143
func (d *Decoder) Decode(v any) error {
144144
return d.DecodeElement(v, nil)
145145
}
146146

147-
// DecodeElement works like Unmarshal except that it takes
147+
// DecodeElement works like [Unmarshal] except that it takes
148148
// a pointer to the start XML element to decode into v.
149149
// It is useful when a client reads some raw XML tokens itself
150-
// but also wants to defer to Unmarshal for some elements.
150+
// but also wants to defer to [Unmarshal] for some elements.
151151
func (d *Decoder) DecodeElement(v any, start *StartElement) error {
152152
val := reflect.ValueOf(v)
153153
if val.Kind() != reflect.Pointer {
@@ -188,7 +188,7 @@ type Unmarshaler interface {
188188
// an XML attribute description of themselves.
189189
//
190190
// UnmarshalXMLAttr decodes a single XML attribute.
191-
// If it returns an error, the outer call to Unmarshal stops and
191+
// If it returns an error, the outer call to [Unmarshal] stops and
192192
// returns that error.
193193
// UnmarshalXMLAttr is used only for struct fields with the
194194
// "attr" option in the field tag.
@@ -308,10 +308,10 @@ func (d *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error {
308308
}
309309

310310
var (
311-
attrType = reflect.TypeOf(Attr{})
312-
unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
313-
unmarshalerAttrType = reflect.TypeOf((*UnmarshalerAttr)(nil)).Elem()
314-
textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
311+
attrType = reflect.TypeFor[Attr]()
312+
unmarshalerType = reflect.TypeFor[Unmarshaler]()
313+
unmarshalerAttrType = reflect.TypeFor[UnmarshalerAttr]()
314+
textUnmarshalerType = reflect.TypeFor[encoding.TextUnmarshaler]()
315315
)
316316

317317
const (

read_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,10 @@ type BadPathEmbeddedB struct {
326326
var badPathTests = []struct {
327327
v, e any
328328
}{
329-
{&BadPathTestA{}, &TagPathError{reflect.TypeOf(BadPathTestA{}), "First", "items>item1", "Second", "items"}},
330-
{&BadPathTestB{}, &TagPathError{reflect.TypeOf(BadPathTestB{}), "First", "items>item1", "Second", "items>item1>value"}},
331-
{&BadPathTestC{}, &TagPathError{reflect.TypeOf(BadPathTestC{}), "First", "", "Second", "First"}},
332-
{&BadPathTestD{}, &TagPathError{reflect.TypeOf(BadPathTestD{}), "First", "", "Second", "First"}},
329+
{&BadPathTestA{}, &TagPathError{reflect.TypeFor[BadPathTestA](), "First", "items>item1", "Second", "items"}},
330+
{&BadPathTestB{}, &TagPathError{reflect.TypeFor[BadPathTestB](), "First", "items>item1", "Second", "items>item1>value"}},
331+
{&BadPathTestC{}, &TagPathError{reflect.TypeFor[BadPathTestC](), "First", "", "Second", "First"}},
332+
{&BadPathTestD{}, &TagPathError{reflect.TypeFor[BadPathTestD](), "First", "", "Second", "First"}},
333333
}
334334

335335
func TestUnmarshalBadPaths(t *testing.T) {

typeinfo.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const (
4747

4848
var tinfoMap sync.Map // map[reflect.Type]*typeInfo
4949

50-
var nameType = reflect.TypeOf(Name{})
50+
var nameType = reflect.TypeFor[Name]()
5151

5252
// getTypeInfo returns the typeInfo structure with details necessary
5353
// for marshaling and unmarshaling typ.
@@ -255,13 +255,6 @@ func lookupXMLName(typ reflect.Type) (xmlname *fieldInfo) {
255255
return nil
256256
}
257257

258-
func min(a, b int) int {
259-
if a <= b {
260-
return a
261-
}
262-
return b
263-
}
264-
265258
// addFieldInfo adds finfo to tinfo.fields if there are no
266259
// conflicts, or if conflicts arise from previous fields that were
267260
// obtained from deeper embedded structures than finfo. In the latter

xml.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func (e *SyntaxError) Error() string {
3434

3535
// A Name represents an XML name (Local) annotated
3636
// with a namespace identifier (Space).
37-
// In tokens returned by Decoder.Token, the Space identifier
37+
// In tokens returned by [Decoder.Token], the Space identifier
3838
// is given as a canonical URL, not the short prefix used
3939
// in the document being parsed. If Local is prefixed in
4040
// the form of "prefix:name", this package will attempt to
@@ -51,7 +51,7 @@ type Attr struct {
5151
}
5252

5353
// A Token is an interface holding one of the token types:
54-
// StartElement, EndElement, CharData, Comment, ProcInst, or Directive.
54+
// [StartElement], [EndElement], [CharData], [Comment], [ProcInst], or [Directive].
5555
type Token any
5656

5757
// A StartElement represents an XML start element.
@@ -130,14 +130,14 @@ func CopyToken(t Token) Token {
130130
}
131131

132132
// A TokenReader is anything that can decode a stream of XML tokens, including a
133-
// Decoder.
133+
// [Decoder].
134134
//
135135
// When Token encounters an error or end-of-file condition after successfully
136136
// reading a token, it returns the token. It may return the (non-nil) error from
137137
// the same call or return the error (and a nil token) from a subsequent call.
138138
// An instance of this general case is that a TokenReader returning a non-nil
139139
// token at the end of the token stream may return either io.EOF or a nil error.
140-
// The next Read should return nil, io.EOF.
140+
// The next Read should return nil, [io.EOF].
141141
//
142142
// Implementations of Token are discouraged from returning a nil token with a
143143
// nil error. Callers should treat a return of nil, nil as indicating that
@@ -219,7 +219,7 @@ type Decoder struct {
219219
}
220220

221221
// NewDecoder creates a new XML parser reading from r.
222-
// If r does not implement io.ByteReader, NewDecoder will
222+
// If r does not implement [io.ByteReader], NewDecoder will
223223
// do its own buffering.
224224
func NewDecoder(r io.Reader) *Decoder {
225225
d := &Decoder{
@@ -249,28 +249,28 @@ func NewTokenDecoder(t TokenReader) *Decoder {
249249
}
250250

251251
// Token returns the next XML token in the input stream.
252-
// At the end of the input stream, Token returns nil, io.EOF.
252+
// At the end of the input stream, Token returns nil, [io.EOF].
253253
//
254254
// Slices of bytes in the returned token data refer to the
255255
// parser's internal buffer and remain valid only until the next
256-
// call to Token. To acquire a copy of the bytes, call CopyToken
256+
// call to Token. To acquire a copy of the bytes, call [CopyToken]
257257
// or the token's Copy method.
258258
//
259259
// Token expands self-closing elements such as <br>
260260
// into separate start and end elements returned by successive calls.
261261
//
262-
// Token guarantees that the StartElement and EndElement
262+
// Token guarantees that the [StartElement] and [EndElement]
263263
// tokens it returns are properly nested and matched:
264264
// if Token encounters an unexpected end element
265265
// or EOF before all expected end elements,
266266
// it will return an error.
267267
//
268-
// If CharsetReader is called and returns an error,
268+
// If [Decoder.CharsetReader] is called and returns an error,
269269
// the error is wrapped and returned.
270270
//
271271
// Token implements XML namespaces as described by
272272
// https://www.w3.org/TR/REC-xml-names/. Each of the
273-
// Name structures contained in the Token has the Space
273+
// [Name] structures contained in the Token has the Space
274274
// set to the URL identifying its namespace when known.
275275
// If Token encounters an unrecognized namespace prefix,
276276
// it uses the prefix as the Space rather than report an error.
@@ -548,7 +548,7 @@ func (d *Decoder) autoClose(t Token) (Token, bool) {
548548

549549
var errRawToken = errors.New("xml: cannot use RawToken from UnmarshalXML method")
550550

551-
// RawToken is like Token but does not verify that
551+
// RawToken is like [Decoder.Token] but does not verify that
552552
// start and end elements match and does not translate
553553
// namespace prefixes to their corresponding URLs.
554554
func (d *Decoder) RawToken() (Token, error) {
@@ -1623,7 +1623,7 @@ var second = &unicode.RangeTable{
16231623
// HTMLEntity is an entity map containing translations for the
16241624
// standard HTML entity characters.
16251625
//
1626-
// See the Decoder.Strict and Decoder.Entity fields' documentation.
1626+
// See the [Decoder.Strict] and [Decoder.Entity] fields' documentation.
16271627
var HTMLEntity map[string]string = htmlEntity
16281628

16291629
var htmlEntity = map[string]string{
@@ -1892,7 +1892,7 @@ var htmlEntity = map[string]string{
18921892
// HTMLAutoClose is the set of HTML elements that
18931893
// should be considered to close automatically.
18941894
//
1895-
// See the Decoder.Strict and Decoder.Entity fields' documentation.
1895+
// See the [Decoder.Strict] and [Decoder.Entity] fields' documentation.
18961896
var HTMLAutoClose []string = htmlAutoClose
18971897

18981898
var htmlAutoClose = []string{
@@ -2020,9 +2020,9 @@ func (p *printer) EscapeString(s string) {
20202020
p.WriteString(s[last:])
20212021
}
20222022

2023-
// Escape is like EscapeText but omits the error return value.
2023+
// Escape is like [EscapeText] but omits the error return value.
20242024
// It is provided for backwards compatibility with Go 1.0.
2025-
// Code targeting Go 1.1 or later should use EscapeText.
2025+
// Code targeting Go 1.1 or later should use [EscapeText].
20262026
func Escape(w io.Writer, s []byte) {
20272027
EscapeText(w, s)
20282028
}

0 commit comments

Comments
 (0)