marshal.go 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066
  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. package xml
  5. import (
  6. "bufio"
  7. "bytes"
  8. "encoding"
  9. "fmt"
  10. "io"
  11. "reflect"
  12. "strconv"
  13. "strings"
  14. )
  15. const (
  16. // Header is a generic XML header suitable for use with the output of Marshal.
  17. // This is not automatically added to any output of this package,
  18. // it is provided as a convenience.
  19. Header = `<?xml version="1.0" encoding="UTF-8"?>` + "\n"
  20. )
  21. // Marshal returns the XML encoding of v.
  22. //
  23. // Marshal handles an array or slice by marshaling each of the elements.
  24. // Marshal handles a pointer by marshaling the value it points at or, if the
  25. // pointer is nil, by writing nothing. Marshal handles an interface value by
  26. // marshaling the value it contains or, if the interface value is nil, by
  27. // writing nothing. Marshal handles all other data by writing one or more XML
  28. // elements containing the data.
  29. //
  30. // The name for the XML elements is taken from, in order of preference:
  31. // - the tag on the XMLName field, if the data is a struct
  32. // - the value of the XMLName field of type Name
  33. // - the tag of the struct field used to obtain the data
  34. // - the name of the struct field used to obtain the data
  35. // - the name of the marshaled type
  36. //
  37. // The XML element for a struct contains marshaled elements for each of the
  38. // exported fields of the struct, with these exceptions:
  39. // - the XMLName field, described above, is omitted.
  40. // - a field with tag "-" is omitted.
  41. // - a field with tag "name,attr" becomes an attribute with
  42. // the given name in the XML element.
  43. // - a field with tag ",attr" becomes an attribute with the
  44. // field name in the XML element.
  45. // - a field with tag ",chardata" is written as character data,
  46. // not as an XML element.
  47. // - a field with tag ",cdata" is written as character data
  48. // wrapped in one or more <![CDATA[ ... ]]> tags, not as an XML element.
  49. // - a field with tag ",innerxml" is written verbatim, not subject
  50. // to the usual marshaling procedure.
  51. // - a field with tag ",comment" is written as an XML comment, not
  52. // subject to the usual marshaling procedure. It must not contain
  53. // the "--" string within it.
  54. // - a field with a tag including the "omitempty" option is omitted
  55. // if the field value is empty. The empty values are false, 0, any
  56. // nil pointer or interface value, and any array, slice, map, or
  57. // string of length zero.
  58. // - an anonymous struct field is handled as if the fields of its
  59. // value were part of the outer struct.
  60. // - a field implementing Marshaler is written by calling its MarshalXML
  61. // method.
  62. // - a field implementing encoding.TextMarshaler is written by encoding the
  63. // result of its MarshalText method as text.
  64. //
  65. // If a field uses a tag "a>b>c", then the element c will be nested inside
  66. // parent elements a and b. Fields that appear next to each other that name
  67. // the same parent will be enclosed in one XML element.
  68. //
  69. // If the XML name for a struct field is defined by both the field tag and the
  70. // struct's XMLName field, the names must match.
  71. //
  72. // See MarshalIndent for an example.
  73. //
  74. // Marshal will return an error if asked to marshal a channel, function, or map.
  75. func Marshal(v interface{}) ([]byte, error) {
  76. var b bytes.Buffer
  77. if err := NewEncoder(&b).Encode(v); err != nil {
  78. return nil, err
  79. }
  80. return b.Bytes(), nil
  81. }
  82. // Marshaler is the interface implemented by objects that can marshal
  83. // themselves into valid XML elements.
  84. //
  85. // MarshalXML encodes the receiver as zero or more XML elements.
  86. // By convention, arrays or slices are typically encoded as a sequence
  87. // of elements, one per entry.
  88. // Using start as the element tag is not required, but doing so
  89. // will enable Unmarshal to match the XML elements to the correct
  90. // struct field.
  91. // One common implementation strategy is to construct a separate
  92. // value with a layout corresponding to the desired XML and then
  93. // to encode it using e.EncodeElement.
  94. // Another common strategy is to use repeated calls to e.EncodeToken
  95. // to generate the XML output one token at a time.
  96. // The sequence of encoded tokens must make up zero or more valid
  97. // XML elements.
  98. type Marshaler interface {
  99. MarshalXML(e *Encoder, start StartElement) error
  100. }
  101. // MarshalerAttr is the interface implemented by objects that can marshal
  102. // themselves into valid XML attributes.
  103. //
  104. // MarshalXMLAttr returns an XML attribute with the encoded value of the receiver.
  105. // Using name as the attribute name is not required, but doing so
  106. // will enable Unmarshal to match the attribute to the correct
  107. // struct field.
  108. // If MarshalXMLAttr returns the zero attribute Attr{}, no attribute
  109. // will be generated in the output.
  110. // MarshalXMLAttr is used only for struct fields with the
  111. // "attr" option in the field tag.
  112. type MarshalerAttr interface {
  113. MarshalXMLAttr(name Name) (Attr, error)
  114. }
  115. // MarshalIndent works like Marshal, but each XML element begins on a new
  116. // indented line that starts with prefix and is followed by one or more
  117. // copies of indent according to the nesting depth.
  118. func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
  119. var b bytes.Buffer
  120. enc := NewEncoder(&b)
  121. enc.Indent(prefix, indent)
  122. if err := enc.Encode(v); err != nil {
  123. return nil, err
  124. }
  125. return b.Bytes(), nil
  126. }
  127. // An Encoder writes XML data to an output stream.
  128. type Encoder struct {
  129. p printer
  130. }
  131. // NewEncoder returns a new encoder that writes to w.
  132. func NewEncoder(w io.Writer) *Encoder {
  133. e := &Encoder{printer{Writer: bufio.NewWriter(w)}}
  134. e.p.encoder = e
  135. return e
  136. }
  137. // Indent sets the encoder to generate XML in which each element
  138. // begins on a new indented line that starts with prefix and is followed by
  139. // one or more copies of indent according to the nesting depth.
  140. func (enc *Encoder) Indent(prefix, indent string) {
  141. enc.p.prefix = prefix
  142. enc.p.indent = indent
  143. }
  144. // Encode writes the XML encoding of v to the stream.
  145. //
  146. // See the documentation for Marshal for details about the conversion
  147. // of Go values to XML.
  148. //
  149. // Encode calls Flush before returning.
  150. func (enc *Encoder) Encode(v interface{}) error {
  151. err := enc.p.marshalValue(reflect.ValueOf(v), nil, nil)
  152. if err != nil {
  153. return err
  154. }
  155. return enc.p.Flush()
  156. }
  157. // EncodeElement writes the XML encoding of v to the stream,
  158. // using start as the outermost tag in the encoding.
  159. //
  160. // See the documentation for Marshal for details about the conversion
  161. // of Go values to XML.
  162. //
  163. // EncodeElement calls Flush before returning.
  164. func (enc *Encoder) EncodeElement(v interface{}, start StartElement) error {
  165. err := enc.p.marshalValue(reflect.ValueOf(v), nil, &start)
  166. if err != nil {
  167. return err
  168. }
  169. return enc.p.Flush()
  170. }
  171. var (
  172. begComment = []byte("<!--")
  173. endComment = []byte("-->")
  174. endProcInst = []byte("?>")
  175. )
  176. // EncodeToken writes the given XML token to the stream.
  177. // It returns an error if StartElement and EndElement tokens are not properly matched.
  178. //
  179. // EncodeToken does not call Flush, because usually it is part of a larger operation
  180. // such as Encode or EncodeElement (or a custom Marshaler's MarshalXML invoked
  181. // during those), and those will call Flush when finished.
  182. // Callers that create an Encoder and then invoke EncodeToken directly, without
  183. // using Encode or EncodeElement, need to call Flush when finished to ensure
  184. // that the XML is written to the underlying writer.
  185. //
  186. // EncodeToken allows writing a ProcInst with Target set to "xml" only as the first token
  187. // in the stream.
  188. func (enc *Encoder) EncodeToken(t Token) error {
  189. p := &enc.p
  190. switch t := t.(type) {
  191. case StartElement:
  192. if err := p.writeStart(&t); err != nil {
  193. return err
  194. }
  195. case EndElement:
  196. if err := p.writeEnd(t.Name); err != nil {
  197. return err
  198. }
  199. case CharData:
  200. escapeText(p, t, false)
  201. case Comment:
  202. if bytes.Contains(t, endComment) {
  203. return fmt.Errorf("xml: EncodeToken of Comment containing --> marker")
  204. }
  205. p.WriteString("<!--")
  206. p.Write(t)
  207. p.WriteString("-->")
  208. return p.cachedWriteError()
  209. case ProcInst:
  210. // First token to be encoded which is also a ProcInst with target of xml
  211. // is the xml declaration. The only ProcInst where target of xml is allowed.
  212. if t.Target == "xml" && p.Buffered() != 0 {
  213. return fmt.Errorf("xml: EncodeToken of ProcInst xml target only valid for xml declaration, first token encoded")
  214. }
  215. if !isNameString(t.Target) {
  216. return fmt.Errorf("xml: EncodeToken of ProcInst with invalid Target")
  217. }
  218. if bytes.Contains(t.Inst, endProcInst) {
  219. return fmt.Errorf("xml: EncodeToken of ProcInst containing ?> marker")
  220. }
  221. p.WriteString("<?")
  222. p.WriteString(t.Target)
  223. if len(t.Inst) > 0 {
  224. p.WriteByte(' ')
  225. p.Write(t.Inst)
  226. }
  227. p.WriteString("?>")
  228. case Directive:
  229. if !isValidDirective(t) {
  230. return fmt.Errorf("xml: EncodeToken of Directive containing wrong < or > markers")
  231. }
  232. p.WriteString("<!")
  233. p.Write(t)
  234. p.WriteString(">")
  235. default:
  236. return fmt.Errorf("xml: EncodeToken of invalid token type")
  237. }
  238. return p.cachedWriteError()
  239. }
  240. // isValidDirective reports whether dir is a valid directive text,
  241. // meaning angle brackets are matched, ignoring comments and strings.
  242. func isValidDirective(dir Directive) bool {
  243. var (
  244. depth int
  245. inquote uint8
  246. incomment bool
  247. )
  248. for i, c := range dir {
  249. switch {
  250. case incomment:
  251. if c == '>' {
  252. if n := 1 + i - len(endComment); n >= 0 && bytes.Equal(dir[n:i+1], endComment) {
  253. incomment = false
  254. }
  255. }
  256. // Just ignore anything in comment
  257. case inquote != 0:
  258. if c == inquote {
  259. inquote = 0
  260. }
  261. // Just ignore anything within quotes
  262. case c == '\'' || c == '"':
  263. inquote = c
  264. case c == '<':
  265. if i+len(begComment) < len(dir) && bytes.Equal(dir[i:i+len(begComment)], begComment) {
  266. incomment = true
  267. } else {
  268. depth++
  269. }
  270. case c == '>':
  271. if depth == 0 {
  272. return false
  273. }
  274. depth--
  275. }
  276. }
  277. return depth == 0 && inquote == 0 && !incomment
  278. }
  279. // Flush flushes any buffered XML to the underlying writer.
  280. // See the EncodeToken documentation for details about when it is necessary.
  281. func (enc *Encoder) Flush() error {
  282. return enc.p.Flush()
  283. }
  284. type printer struct {
  285. *bufio.Writer
  286. encoder *Encoder
  287. seq int
  288. indent string
  289. prefix string
  290. depth int
  291. indentedIn bool
  292. putNewline bool
  293. attrNS map[string]string // map prefix -> name space
  294. attrPrefix map[string]string // map name space -> prefix
  295. prefixes []string
  296. tags []Name
  297. }
  298. // createAttrPrefix finds the name space prefix attribute to use for the given name space,
  299. // defining a new prefix if necessary. It returns the prefix.
  300. func (p *printer) createAttrPrefix(url string) string {
  301. if prefix := p.attrPrefix[url]; prefix != "" {
  302. return prefix
  303. }
  304. // The "http://www.w3.org/XML/1998/namespace" name space is predefined as "xml"
  305. // and must be referred to that way.
  306. // (The "http://www.w3.org/2000/xmlns/" name space is also predefined as "xmlns",
  307. // but users should not be trying to use that one directly - that's our job.)
  308. if url == xmlURL {
  309. return xmlPrefix
  310. }
  311. // Need to define a new name space.
  312. if p.attrPrefix == nil {
  313. p.attrPrefix = make(map[string]string)
  314. p.attrNS = make(map[string]string)
  315. }
  316. // Pick a name. We try to use the final element of the path
  317. // but fall back to _.
  318. prefix := strings.TrimRight(url, "/")
  319. if i := strings.LastIndex(prefix, "/"); i >= 0 {
  320. prefix = prefix[i+1:]
  321. }
  322. if prefix == "" || !isName([]byte(prefix)) || strings.Contains(prefix, ":") {
  323. prefix = "_"
  324. }
  325. if strings.HasPrefix(prefix, "xml") {
  326. // xmlanything is reserved.
  327. prefix = "_" + prefix
  328. }
  329. if p.attrNS[prefix] != "" {
  330. // Name is taken. Find a better one.
  331. for p.seq++; ; p.seq++ {
  332. if id := prefix + "_" + strconv.Itoa(p.seq); p.attrNS[id] == "" {
  333. prefix = id
  334. break
  335. }
  336. }
  337. }
  338. p.attrPrefix[url] = prefix
  339. p.attrNS[prefix] = url
  340. p.WriteString(`xmlns:`)
  341. p.WriteString(prefix)
  342. p.WriteString(`="`)
  343. EscapeText(p, []byte(url))
  344. p.WriteString(`" `)
  345. p.prefixes = append(p.prefixes, prefix)
  346. return prefix
  347. }
  348. // deleteAttrPrefix removes an attribute name space prefix.
  349. func (p *printer) deleteAttrPrefix(prefix string) {
  350. delete(p.attrPrefix, p.attrNS[prefix])
  351. delete(p.attrNS, prefix)
  352. }
  353. func (p *printer) markPrefix() {
  354. p.prefixes = append(p.prefixes, "")
  355. }
  356. func (p *printer) popPrefix() {
  357. for len(p.prefixes) > 0 {
  358. prefix := p.prefixes[len(p.prefixes)-1]
  359. p.prefixes = p.prefixes[:len(p.prefixes)-1]
  360. if prefix == "" {
  361. break
  362. }
  363. p.deleteAttrPrefix(prefix)
  364. }
  365. }
  366. var (
  367. marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
  368. marshalerAttrType = reflect.TypeOf((*MarshalerAttr)(nil)).Elem()
  369. textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
  370. )
  371. // marshalValue writes one or more XML elements representing val.
  372. // If val was obtained from a struct field, finfo must have its details.
  373. func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplate *StartElement) error {
  374. if startTemplate != nil && startTemplate.Name.Local == "" {
  375. return fmt.Errorf("xml: EncodeElement of StartElement with missing name")
  376. }
  377. if !val.IsValid() {
  378. return nil
  379. }
  380. if finfo != nil && finfo.flags&fOmitEmpty != 0 && isEmptyValue(val) {
  381. return nil
  382. }
  383. // Drill into interfaces and pointers.
  384. // This can turn into an infinite loop given a cyclic chain,
  385. // but it matches the Go 1 behavior.
  386. for val.Kind() == reflect.Interface || val.Kind() == reflect.Ptr {
  387. if val.IsNil() {
  388. return nil
  389. }
  390. val = val.Elem()
  391. }
  392. kind := val.Kind()
  393. typ := val.Type()
  394. // Check for marshaler.
  395. if val.CanInterface() && typ.Implements(marshalerType) {
  396. return p.marshalInterface(val.Interface().(Marshaler), defaultStart(typ, finfo, startTemplate))
  397. }
  398. if val.CanAddr() {
  399. pv := val.Addr()
  400. if pv.CanInterface() && pv.Type().Implements(marshalerType) {
  401. return p.marshalInterface(pv.Interface().(Marshaler), defaultStart(pv.Type(), finfo, startTemplate))
  402. }
  403. }
  404. // Check for text marshaler.
  405. if val.CanInterface() && typ.Implements(textMarshalerType) {
  406. return p.marshalTextInterface(val.Interface().(encoding.TextMarshaler), defaultStart(typ, finfo, startTemplate))
  407. }
  408. if val.CanAddr() {
  409. pv := val.Addr()
  410. if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
  411. return p.marshalTextInterface(pv.Interface().(encoding.TextMarshaler), defaultStart(pv.Type(), finfo, startTemplate))
  412. }
  413. }
  414. // Slices and arrays iterate over the elements. They do not have an enclosing tag.
  415. if (kind == reflect.Slice || kind == reflect.Array) && typ.Elem().Kind() != reflect.Uint8 {
  416. for i, n := 0, val.Len(); i < n; i++ {
  417. if err := p.marshalValue(val.Index(i), finfo, startTemplate); err != nil {
  418. return err
  419. }
  420. }
  421. return nil
  422. }
  423. tinfo, err := getTypeInfo(typ)
  424. if err != nil {
  425. return err
  426. }
  427. // Create start element.
  428. // Precedence for the XML element name is:
  429. // 0. startTemplate
  430. // 1. XMLName field in underlying struct;
  431. // 2. field name/tag in the struct field; and
  432. // 3. type name
  433. var start StartElement
  434. if startTemplate != nil {
  435. start.Name = startTemplate.Name
  436. start.Attr = append(start.Attr, startTemplate.Attr...)
  437. } else if tinfo.xmlname != nil {
  438. xmlname := tinfo.xmlname
  439. if xmlname.name != "" {
  440. start.Name.Space, start.Name.Local = xmlname.xmlns, xmlname.name
  441. } else {
  442. fv := xmlname.value(val, dontInitNilPointers)
  443. if v, ok := fv.Interface().(Name); ok && v.Local != "" {
  444. start.Name = v
  445. }
  446. }
  447. }
  448. if start.Name.Local == "" && finfo != nil {
  449. start.Name.Space, start.Name.Local = finfo.xmlns, finfo.name
  450. }
  451. if start.Name.Local == "" {
  452. name := typ.Name()
  453. if name == "" {
  454. return &UnsupportedTypeError{typ}
  455. }
  456. start.Name.Local = name
  457. }
  458. // Add type attribute if necessary
  459. if finfo != nil && finfo.flags&fTypeAttr != 0 {
  460. start.Attr = append(start.Attr, Attr{xmlSchemaInstance, typeToString(typ)})
  461. }
  462. // Attributes
  463. for i := range tinfo.fields {
  464. finfo := &tinfo.fields[i]
  465. if finfo.flags&fAttr == 0 {
  466. continue
  467. }
  468. fv := finfo.value(val, dontInitNilPointers)
  469. if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) {
  470. continue
  471. }
  472. if fv.Kind() == reflect.Interface && fv.IsNil() {
  473. continue
  474. }
  475. name := Name{Space: finfo.xmlns, Local: finfo.name}
  476. if err := p.marshalAttr(&start, name, fv); err != nil {
  477. return err
  478. }
  479. }
  480. if err := p.writeStart(&start); err != nil {
  481. return err
  482. }
  483. if val.Kind() == reflect.Struct {
  484. err = p.marshalStruct(tinfo, val)
  485. } else {
  486. s, b, err1 := p.marshalSimple(typ, val)
  487. if err1 != nil {
  488. err = err1
  489. } else if b != nil {
  490. EscapeText(p, b)
  491. } else {
  492. p.EscapeString(s)
  493. }
  494. }
  495. if err != nil {
  496. return err
  497. }
  498. if err := p.writeEnd(start.Name); err != nil {
  499. return err
  500. }
  501. return p.cachedWriteError()
  502. }
  503. // marshalAttr marshals an attribute with the given name and value, adding to start.Attr.
  504. func (p *printer) marshalAttr(start *StartElement, name Name, val reflect.Value) error {
  505. if val.CanInterface() && val.Type().Implements(marshalerAttrType) {
  506. attr, err := val.Interface().(MarshalerAttr).MarshalXMLAttr(name)
  507. if err != nil {
  508. return err
  509. }
  510. if attr.Name.Local != "" {
  511. start.Attr = append(start.Attr, attr)
  512. }
  513. return nil
  514. }
  515. if val.CanAddr() {
  516. pv := val.Addr()
  517. if pv.CanInterface() && pv.Type().Implements(marshalerAttrType) {
  518. attr, err := pv.Interface().(MarshalerAttr).MarshalXMLAttr(name)
  519. if err != nil {
  520. return err
  521. }
  522. if attr.Name.Local != "" {
  523. start.Attr = append(start.Attr, attr)
  524. }
  525. return nil
  526. }
  527. }
  528. if val.CanInterface() && val.Type().Implements(textMarshalerType) {
  529. text, err := val.Interface().(encoding.TextMarshaler).MarshalText()
  530. if err != nil {
  531. return err
  532. }
  533. start.Attr = append(start.Attr, Attr{name, string(text)})
  534. return nil
  535. }
  536. if val.CanAddr() {
  537. pv := val.Addr()
  538. if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
  539. text, err := pv.Interface().(encoding.TextMarshaler).MarshalText()
  540. if err != nil {
  541. return err
  542. }
  543. start.Attr = append(start.Attr, Attr{name, string(text)})
  544. return nil
  545. }
  546. }
  547. // Dereference or skip nil pointer, interface values.
  548. switch val.Kind() {
  549. case reflect.Ptr, reflect.Interface:
  550. if val.IsNil() {
  551. return nil
  552. }
  553. val = val.Elem()
  554. }
  555. // Walk slices.
  556. if val.Kind() == reflect.Slice && val.Type().Elem().Kind() != reflect.Uint8 {
  557. n := val.Len()
  558. for i := 0; i < n; i++ {
  559. if err := p.marshalAttr(start, name, val.Index(i)); err != nil {
  560. return err
  561. }
  562. }
  563. return nil
  564. }
  565. if val.Type() == attrType {
  566. start.Attr = append(start.Attr, val.Interface().(Attr))
  567. return nil
  568. }
  569. s, b, err := p.marshalSimple(val.Type(), val)
  570. if err != nil {
  571. return err
  572. }
  573. if b != nil {
  574. s = string(b)
  575. }
  576. start.Attr = append(start.Attr, Attr{name, s})
  577. return nil
  578. }
  579. // defaultStart returns the default start element to use,
  580. // given the reflect type, field info, and start template.
  581. func defaultStart(typ reflect.Type, finfo *fieldInfo, startTemplate *StartElement) StartElement {
  582. var start StartElement
  583. // Precedence for the XML element name is as above,
  584. // except that we do not look inside structs for the first field.
  585. if startTemplate != nil {
  586. start.Name = startTemplate.Name
  587. start.Attr = append(start.Attr, startTemplate.Attr...)
  588. } else if finfo != nil && finfo.name != "" {
  589. start.Name.Local = finfo.name
  590. start.Name.Space = finfo.xmlns
  591. } else if typ.Name() != "" {
  592. start.Name.Local = typ.Name()
  593. } else {
  594. // Must be a pointer to a named type,
  595. // since it has the Marshaler methods.
  596. start.Name.Local = typ.Elem().Name()
  597. }
  598. // Add type attribute if necessary
  599. if finfo != nil && finfo.flags&fTypeAttr != 0 {
  600. start.Attr = append(start.Attr, Attr{xmlSchemaInstance, typeToString(typ)})
  601. }
  602. return start
  603. }
  604. // marshalInterface marshals a Marshaler interface value.
  605. func (p *printer) marshalInterface(val Marshaler, start StartElement) error {
  606. // Push a marker onto the tag stack so that MarshalXML
  607. // cannot close the XML tags that it did not open.
  608. p.tags = append(p.tags, Name{})
  609. n := len(p.tags)
  610. err := val.MarshalXML(p.encoder, start)
  611. if err != nil {
  612. return err
  613. }
  614. // Make sure MarshalXML closed all its tags. p.tags[n-1] is the mark.
  615. if len(p.tags) > n {
  616. return fmt.Errorf("xml: %s.MarshalXML wrote invalid XML: <%s> not closed", receiverType(val), p.tags[len(p.tags)-1].Local)
  617. }
  618. p.tags = p.tags[:n-1]
  619. return nil
  620. }
  621. // marshalTextInterface marshals a TextMarshaler interface value.
  622. func (p *printer) marshalTextInterface(val encoding.TextMarshaler, start StartElement) error {
  623. if err := p.writeStart(&start); err != nil {
  624. return err
  625. }
  626. text, err := val.MarshalText()
  627. if err != nil {
  628. return err
  629. }
  630. EscapeText(p, text)
  631. return p.writeEnd(start.Name)
  632. }
  633. // writeStart writes the given start element.
  634. func (p *printer) writeStart(start *StartElement) error {
  635. if start.Name.Local == "" {
  636. return fmt.Errorf("xml: start tag with no name")
  637. }
  638. p.tags = append(p.tags, start.Name)
  639. p.markPrefix()
  640. p.writeIndent(1)
  641. p.WriteByte('<')
  642. p.WriteString(start.Name.Local)
  643. if start.Name.Space != "" {
  644. p.WriteString(` xmlns="`)
  645. p.EscapeString(start.Name.Space)
  646. p.WriteByte('"')
  647. }
  648. // Attributes
  649. for _, attr := range start.Attr {
  650. name := attr.Name
  651. if name.Local == "" {
  652. continue
  653. }
  654. p.WriteByte(' ')
  655. if name.Space != "" {
  656. p.WriteString(p.createAttrPrefix(name.Space))
  657. p.WriteByte(':')
  658. }
  659. p.WriteString(name.Local)
  660. p.WriteString(`="`)
  661. p.EscapeString(attr.Value)
  662. p.WriteByte('"')
  663. }
  664. p.WriteByte('>')
  665. return nil
  666. }
  667. func (p *printer) writeEnd(name Name) error {
  668. if name.Local == "" {
  669. return fmt.Errorf("xml: end tag with no name")
  670. }
  671. if len(p.tags) == 0 || p.tags[len(p.tags)-1].Local == "" {
  672. return fmt.Errorf("xml: end tag </%s> without start tag", name.Local)
  673. }
  674. if top := p.tags[len(p.tags)-1]; top != name {
  675. if top.Local != name.Local {
  676. return fmt.Errorf("xml: end tag </%s> does not match start tag <%s>", name.Local, top.Local)
  677. }
  678. return fmt.Errorf("xml: end tag </%s> in namespace %s does not match start tag <%s> in namespace %s", name.Local, name.Space, top.Local, top.Space)
  679. }
  680. p.tags = p.tags[:len(p.tags)-1]
  681. p.writeIndent(-1)
  682. p.WriteByte('<')
  683. p.WriteByte('/')
  684. p.WriteString(name.Local)
  685. p.WriteByte('>')
  686. p.popPrefix()
  687. return nil
  688. }
  689. func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) (string, []byte, error) {
  690. switch val.Kind() {
  691. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  692. return strconv.FormatInt(val.Int(), 10), nil, nil
  693. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  694. return strconv.FormatUint(val.Uint(), 10), nil, nil
  695. case reflect.Float32, reflect.Float64:
  696. return strconv.FormatFloat(val.Float(), 'g', -1, val.Type().Bits()), nil, nil
  697. case reflect.String:
  698. return val.String(), nil, nil
  699. case reflect.Bool:
  700. return strconv.FormatBool(val.Bool()), nil, nil
  701. case reflect.Array:
  702. if typ.Elem().Kind() != reflect.Uint8 {
  703. break
  704. }
  705. // [...]byte
  706. var bytes []byte
  707. if val.CanAddr() {
  708. bytes = val.Slice(0, val.Len()).Bytes()
  709. } else {
  710. bytes = make([]byte, val.Len())
  711. reflect.Copy(reflect.ValueOf(bytes), val)
  712. }
  713. return "", bytes, nil
  714. case reflect.Slice:
  715. if typ.Elem().Kind() != reflect.Uint8 {
  716. break
  717. }
  718. // []byte
  719. return "", val.Bytes(), nil
  720. }
  721. return "", nil, &UnsupportedTypeError{typ}
  722. }
  723. var ddBytes = []byte("--")
  724. // indirect drills into interfaces and pointers, returning the pointed-at value.
  725. // If it encounters a nil interface or pointer, indirect returns that nil value.
  726. // This can turn into an infinite loop given a cyclic chain,
  727. // but it matches the Go 1 behavior.
  728. func indirect(vf reflect.Value) reflect.Value {
  729. for vf.Kind() == reflect.Interface || vf.Kind() == reflect.Ptr {
  730. if vf.IsNil() {
  731. return vf
  732. }
  733. vf = vf.Elem()
  734. }
  735. return vf
  736. }
  737. func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
  738. s := parentStack{p: p}
  739. for i := range tinfo.fields {
  740. finfo := &tinfo.fields[i]
  741. if finfo.flags&fAttr != 0 {
  742. continue
  743. }
  744. vf := finfo.value(val, dontInitNilPointers)
  745. if !vf.IsValid() {
  746. // The field is behind an anonymous struct field that's
  747. // nil. Skip it.
  748. continue
  749. }
  750. switch finfo.flags & fMode {
  751. case fCDATA, fCharData:
  752. emit := EscapeText
  753. if finfo.flags&fMode == fCDATA {
  754. emit = emitCDATA
  755. }
  756. if err := s.trim(finfo.parents); err != nil {
  757. return err
  758. }
  759. if vf.CanInterface() && vf.Type().Implements(textMarshalerType) {
  760. data, err := vf.Interface().(encoding.TextMarshaler).MarshalText()
  761. if err != nil {
  762. return err
  763. }
  764. if err := emit(p, data); err != nil {
  765. return err
  766. }
  767. continue
  768. }
  769. if vf.CanAddr() {
  770. pv := vf.Addr()
  771. if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
  772. data, err := pv.Interface().(encoding.TextMarshaler).MarshalText()
  773. if err != nil {
  774. return err
  775. }
  776. if err := emit(p, data); err != nil {
  777. return err
  778. }
  779. continue
  780. }
  781. }
  782. var scratch [64]byte
  783. vf = indirect(vf)
  784. switch vf.Kind() {
  785. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  786. if err := emit(p, strconv.AppendInt(scratch[:0], vf.Int(), 10)); err != nil {
  787. return err
  788. }
  789. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  790. if err := emit(p, strconv.AppendUint(scratch[:0], vf.Uint(), 10)); err != nil {
  791. return err
  792. }
  793. case reflect.Float32, reflect.Float64:
  794. if err := emit(p, strconv.AppendFloat(scratch[:0], vf.Float(), 'g', -1, vf.Type().Bits())); err != nil {
  795. return err
  796. }
  797. case reflect.Bool:
  798. if err := emit(p, strconv.AppendBool(scratch[:0], vf.Bool())); err != nil {
  799. return err
  800. }
  801. case reflect.String:
  802. if err := emit(p, []byte(vf.String())); err != nil {
  803. return err
  804. }
  805. case reflect.Slice:
  806. if elem, ok := vf.Interface().([]byte); ok {
  807. if err := emit(p, elem); err != nil {
  808. return err
  809. }
  810. }
  811. }
  812. continue
  813. case fComment:
  814. if err := s.trim(finfo.parents); err != nil {
  815. return err
  816. }
  817. vf = indirect(vf)
  818. k := vf.Kind()
  819. if !(k == reflect.String || k == reflect.Slice && vf.Type().Elem().Kind() == reflect.Uint8) {
  820. return fmt.Errorf("xml: bad type for comment field of %s", val.Type())
  821. }
  822. if vf.Len() == 0 {
  823. continue
  824. }
  825. p.writeIndent(0)
  826. p.WriteString("<!--")
  827. dashDash := false
  828. dashLast := false
  829. switch k {
  830. case reflect.String:
  831. s := vf.String()
  832. dashDash = strings.Contains(s, "--")
  833. dashLast = s[len(s)-1] == '-'
  834. if !dashDash {
  835. p.WriteString(s)
  836. }
  837. case reflect.Slice:
  838. b := vf.Bytes()
  839. dashDash = bytes.Contains(b, ddBytes)
  840. dashLast = b[len(b)-1] == '-'
  841. if !dashDash {
  842. p.Write(b)
  843. }
  844. default:
  845. panic("can't happen")
  846. }
  847. if dashDash {
  848. return fmt.Errorf(`xml: comments must not contain "--"`)
  849. }
  850. if dashLast {
  851. // "--->" is invalid grammar. Make it "- -->"
  852. p.WriteByte(' ')
  853. }
  854. p.WriteString("-->")
  855. continue
  856. case fInnerXML:
  857. vf = indirect(vf)
  858. iface := vf.Interface()
  859. switch raw := iface.(type) {
  860. case []byte:
  861. p.Write(raw)
  862. continue
  863. case string:
  864. p.WriteString(raw)
  865. continue
  866. }
  867. case fElement, fElement | fAny:
  868. if err := s.trim(finfo.parents); err != nil {
  869. return err
  870. }
  871. if len(finfo.parents) > len(s.stack) {
  872. if vf.Kind() != reflect.Ptr && vf.Kind() != reflect.Interface || !vf.IsNil() {
  873. if err := s.push(finfo.parents[len(s.stack):]); err != nil {
  874. return err
  875. }
  876. }
  877. }
  878. }
  879. if err := p.marshalValue(vf, finfo, nil); err != nil {
  880. return err
  881. }
  882. }
  883. s.trim(nil)
  884. return p.cachedWriteError()
  885. }
  886. // return the bufio Writer's cached write error
  887. func (p *printer) cachedWriteError() error {
  888. _, err := p.Write(nil)
  889. return err
  890. }
  891. func (p *printer) writeIndent(depthDelta int) {
  892. if len(p.prefix) == 0 && len(p.indent) == 0 {
  893. return
  894. }
  895. if depthDelta < 0 {
  896. p.depth--
  897. if p.indentedIn {
  898. p.indentedIn = false
  899. return
  900. }
  901. p.indentedIn = false
  902. }
  903. if p.putNewline {
  904. p.WriteByte('\n')
  905. } else {
  906. p.putNewline = true
  907. }
  908. if len(p.prefix) > 0 {
  909. p.WriteString(p.prefix)
  910. }
  911. if len(p.indent) > 0 {
  912. for i := 0; i < p.depth; i++ {
  913. p.WriteString(p.indent)
  914. }
  915. }
  916. if depthDelta > 0 {
  917. p.depth++
  918. p.indentedIn = true
  919. }
  920. }
  921. type parentStack struct {
  922. p *printer
  923. stack []string
  924. }
  925. // trim updates the XML context to match the longest common prefix of the stack
  926. // and the given parents. A closing tag will be written for every parent
  927. // popped. Passing a zero slice or nil will close all the elements.
  928. func (s *parentStack) trim(parents []string) error {
  929. split := 0
  930. for ; split < len(parents) && split < len(s.stack); split++ {
  931. if parents[split] != s.stack[split] {
  932. break
  933. }
  934. }
  935. for i := len(s.stack) - 1; i >= split; i-- {
  936. if err := s.p.writeEnd(Name{Local: s.stack[i]}); err != nil {
  937. return err
  938. }
  939. }
  940. s.stack = s.stack[:split]
  941. return nil
  942. }
  943. // push adds parent elements to the stack and writes open tags.
  944. func (s *parentStack) push(parents []string) error {
  945. for i := 0; i < len(parents); i++ {
  946. if err := s.p.writeStart(&StartElement{Name: Name{Local: parents[i]}}); err != nil {
  947. return err
  948. }
  949. }
  950. s.stack = append(s.stack, parents...)
  951. return nil
  952. }
  953. // UnsupportedTypeError is returned when Marshal encounters a type
  954. // that cannot be converted into XML.
  955. type UnsupportedTypeError struct {
  956. Type reflect.Type
  957. }
  958. func (e *UnsupportedTypeError) Error() string {
  959. return "xml: unsupported type: " + e.Type.String()
  960. }
  961. func isEmptyValue(v reflect.Value) bool {
  962. switch v.Kind() {
  963. case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
  964. return v.Len() == 0
  965. case reflect.Bool:
  966. return !v.Bool()
  967. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  968. return v.Int() == 0
  969. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  970. return v.Uint() == 0
  971. case reflect.Float32, reflect.Float64:
  972. return v.Float() == 0
  973. case reflect.Interface, reflect.Ptr:
  974. return v.IsNil()
  975. }
  976. return false
  977. }