marshal.go 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223
  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. // 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 marshalling each of the elements.
  24. // Marshal handles a pointer by marshalling the value it points at or, if the
  25. // pointer is nil, by writing nothing. Marshal handles an interface value by
  26. // marshalling 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 xml.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 marshalled type
  36. //
  37. // The XML element for a struct contains marshalled 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 ",innerxml" is written verbatim, not subject
  48. // to the usual marshalling procedure.
  49. // - a field with tag ",comment" is written as an XML comment, not
  50. // subject to the usual marshalling procedure. It must not contain
  51. // the "--" string within it.
  52. // - a field with a tag including the "omitempty" option is omitted
  53. // if the field value is empty. The empty values are false, 0, any
  54. // nil pointer or interface value, and any array, slice, map, or
  55. // string of length zero.
  56. // - an anonymous struct field is handled as if the fields of its
  57. // value were part of the outer struct.
  58. //
  59. // If a field uses a tag "a>b>c", then the element c will be nested inside
  60. // parent elements a and b. Fields that appear next to each other that name
  61. // the same parent will be enclosed in one XML element.
  62. //
  63. // See MarshalIndent for an example.
  64. //
  65. // Marshal will return an error if asked to marshal a channel, function, or map.
  66. func Marshal(v interface{}) ([]byte, error) {
  67. var b bytes.Buffer
  68. if err := NewEncoder(&b).Encode(v); err != nil {
  69. return nil, err
  70. }
  71. return b.Bytes(), nil
  72. }
  73. // Marshaler is the interface implemented by objects that can marshal
  74. // themselves into valid XML elements.
  75. //
  76. // MarshalXML encodes the receiver as zero or more XML elements.
  77. // By convention, arrays or slices are typically encoded as a sequence
  78. // of elements, one per entry.
  79. // Using start as the element tag is not required, but doing so
  80. // will enable Unmarshal to match the XML elements to the correct
  81. // struct field.
  82. // One common implementation strategy is to construct a separate
  83. // value with a layout corresponding to the desired XML and then
  84. // to encode it using e.EncodeElement.
  85. // Another common strategy is to use repeated calls to e.EncodeToken
  86. // to generate the XML output one token at a time.
  87. // The sequence of encoded tokens must make up zero or more valid
  88. // XML elements.
  89. type Marshaler interface {
  90. MarshalXML(e *Encoder, start StartElement) error
  91. }
  92. // MarshalerAttr is the interface implemented by objects that can marshal
  93. // themselves into valid XML attributes.
  94. //
  95. // MarshalXMLAttr returns an XML attribute with the encoded value of the receiver.
  96. // Using name as the attribute name is not required, but doing so
  97. // will enable Unmarshal to match the attribute to the correct
  98. // struct field.
  99. // If MarshalXMLAttr returns the zero attribute Attr{}, no attribute
  100. // will be generated in the output.
  101. // MarshalXMLAttr is used only for struct fields with the
  102. // "attr" option in the field tag.
  103. type MarshalerAttr interface {
  104. MarshalXMLAttr(name Name) (Attr, error)
  105. }
  106. // MarshalIndent works like Marshal, but each XML element begins on a new
  107. // indented line that starts with prefix and is followed by one or more
  108. // copies of indent according to the nesting depth.
  109. func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
  110. var b bytes.Buffer
  111. enc := NewEncoder(&b)
  112. enc.Indent(prefix, indent)
  113. if err := enc.Encode(v); err != nil {
  114. return nil, err
  115. }
  116. return b.Bytes(), nil
  117. }
  118. // An Encoder writes XML data to an output stream.
  119. type Encoder struct {
  120. p printer
  121. }
  122. // NewEncoder returns a new encoder that writes to w.
  123. func NewEncoder(w io.Writer) *Encoder {
  124. e := &Encoder{printer{Writer: bufio.NewWriter(w)}}
  125. e.p.encoder = e
  126. return e
  127. }
  128. // Indent sets the encoder to generate XML in which each element
  129. // begins on a new indented line that starts with prefix and is followed by
  130. // one or more copies of indent according to the nesting depth.
  131. func (enc *Encoder) Indent(prefix, indent string) {
  132. enc.p.prefix = prefix
  133. enc.p.indent = indent
  134. }
  135. // Encode writes the XML encoding of v to the stream.
  136. //
  137. // See the documentation for Marshal for details about the conversion
  138. // of Go values to XML.
  139. //
  140. // Encode calls Flush before returning.
  141. func (enc *Encoder) Encode(v interface{}) error {
  142. err := enc.p.marshalValue(reflect.ValueOf(v), nil, nil)
  143. if err != nil {
  144. return err
  145. }
  146. return enc.p.Flush()
  147. }
  148. // EncodeElement writes the XML encoding of v to the stream,
  149. // using start as the outermost tag in the encoding.
  150. //
  151. // See the documentation for Marshal for details about the conversion
  152. // of Go values to XML.
  153. //
  154. // EncodeElement calls Flush before returning.
  155. func (enc *Encoder) EncodeElement(v interface{}, start StartElement) error {
  156. err := enc.p.marshalValue(reflect.ValueOf(v), nil, &start)
  157. if err != nil {
  158. return err
  159. }
  160. return enc.p.Flush()
  161. }
  162. var (
  163. begComment = []byte("<!--")
  164. endComment = []byte("-->")
  165. endProcInst = []byte("?>")
  166. endDirective = []byte(">")
  167. )
  168. // EncodeToken writes the given XML token to the stream.
  169. // It returns an error if StartElement and EndElement tokens are not
  170. // properly matched.
  171. //
  172. // EncodeToken does not call Flush, because usually it is part of a
  173. // larger operation such as Encode or EncodeElement (or a custom
  174. // Marshaler's MarshalXML invoked during those), and those will call
  175. // Flush when finished. Callers that create an Encoder and then invoke
  176. // EncodeToken directly, without using Encode or EncodeElement, need to
  177. // call Flush when finished to ensure that the XML is written to the
  178. // underlying writer.
  179. //
  180. // EncodeToken allows writing a ProcInst with Target set to "xml" only
  181. // as the first token in the stream.
  182. //
  183. // When encoding a StartElement holding an XML namespace prefix
  184. // declaration for a prefix that is not already declared, contained
  185. // elements (including the StartElement itself) will use the declared
  186. // prefix when encoding names with matching namespace URIs.
  187. func (enc *Encoder) EncodeToken(t Token) error {
  188. p := &enc.p
  189. switch t := t.(type) {
  190. case StartElement:
  191. if err := p.writeStart(&t); err != nil {
  192. return err
  193. }
  194. case EndElement:
  195. if err := p.writeEnd(t.Name); err != nil {
  196. return err
  197. }
  198. case CharData:
  199. escapeText(p, t, false)
  200. case Comment:
  201. if bytes.Contains(t, endComment) {
  202. return fmt.Errorf("xml: EncodeToken of Comment containing --> marker")
  203. }
  204. p.WriteString("<!--")
  205. p.Write(t)
  206. p.WriteString("-->")
  207. return p.cachedWriteError()
  208. case ProcInst:
  209. // First token to be encoded which is also a ProcInst with target of xml
  210. // is the xml declaration. The only ProcInst where target of xml is allowed.
  211. if t.Target == "xml" && p.Buffered() != 0 {
  212. return fmt.Errorf("xml: EncodeToken of ProcInst xml target only valid for xml declaration, first token encoded")
  213. }
  214. if !isNameString(t.Target) {
  215. return fmt.Errorf("xml: EncodeToken of ProcInst with invalid Target")
  216. }
  217. if bytes.Contains(t.Inst, endProcInst) {
  218. return fmt.Errorf("xml: EncodeToken of ProcInst containing ?> marker")
  219. }
  220. p.WriteString("<?")
  221. p.WriteString(t.Target)
  222. if len(t.Inst) > 0 {
  223. p.WriteByte(' ')
  224. p.Write(t.Inst)
  225. }
  226. p.WriteString("?>")
  227. case Directive:
  228. if !isValidDirective(t) {
  229. return fmt.Errorf("xml: EncodeToken of Directive containing wrong < or > markers")
  230. }
  231. p.WriteString("<!")
  232. p.Write(t)
  233. p.WriteString(">")
  234. default:
  235. return fmt.Errorf("xml: EncodeToken of invalid token type")
  236. }
  237. return p.cachedWriteError()
  238. }
  239. // isValidDirective reports whether dir is a valid directive text,
  240. // meaning angle brackets are matched, ignoring comments and strings.
  241. func isValidDirective(dir Directive) bool {
  242. var (
  243. depth int
  244. inquote uint8
  245. incomment bool
  246. )
  247. for i, c := range dir {
  248. switch {
  249. case incomment:
  250. if c == '>' {
  251. if n := 1 + i - len(endComment); n >= 0 && bytes.Equal(dir[n:i+1], endComment) {
  252. incomment = false
  253. }
  254. }
  255. // Just ignore anything in comment
  256. case inquote != 0:
  257. if c == inquote {
  258. inquote = 0
  259. }
  260. // Just ignore anything within quotes
  261. case c == '\'' || c == '"':
  262. inquote = c
  263. case c == '<':
  264. if i+len(begComment) < len(dir) && bytes.Equal(dir[i:i+len(begComment)], begComment) {
  265. incomment = true
  266. } else {
  267. depth++
  268. }
  269. case c == '>':
  270. if depth == 0 {
  271. return false
  272. }
  273. depth--
  274. }
  275. }
  276. return depth == 0 && inquote == 0 && !incomment
  277. }
  278. // Flush flushes any buffered XML to the underlying writer.
  279. // See the EncodeToken documentation for details about when it is necessary.
  280. func (enc *Encoder) Flush() error {
  281. return enc.p.Flush()
  282. }
  283. type printer struct {
  284. *bufio.Writer
  285. encoder *Encoder
  286. seq int
  287. indent string
  288. prefix string
  289. depth int
  290. indentedIn bool
  291. putNewline bool
  292. defaultNS string
  293. attrNS map[string]string // map prefix -> name space
  294. attrPrefix map[string]string // map name space -> prefix
  295. prefixes []printerPrefix
  296. tags []Name
  297. }
  298. // printerPrefix holds a namespace undo record.
  299. // When an element is popped, the prefix record
  300. // is set back to the recorded URL. The empty
  301. // prefix records the URL for the default name space.
  302. //
  303. // The start of an element is recorded with an element
  304. // that has mark=true.
  305. type printerPrefix struct {
  306. prefix string
  307. url string
  308. mark bool
  309. }
  310. func (p *printer) prefixForNS(url string, isAttr bool) string {
  311. // The "http://www.w3.org/XML/1998/namespace" name space is predefined as "xml"
  312. // and must be referred to that way.
  313. // (The "http://www.w3.org/2000/xmlns/" name space is also predefined as "xmlns",
  314. // but users should not be trying to use that one directly - that's our job.)
  315. if url == xmlURL {
  316. return "xml"
  317. }
  318. if !isAttr && url == p.defaultNS {
  319. // We can use the default name space.
  320. return ""
  321. }
  322. return p.attrPrefix[url]
  323. }
  324. // defineNS pushes any namespace definition found in the given attribute.
  325. // If ignoreNonEmptyDefault is true, an xmlns="nonempty"
  326. // attribute will be ignored.
  327. func (p *printer) defineNS(attr Attr, ignoreNonEmptyDefault bool) error {
  328. var prefix string
  329. if attr.Name.Local == "xmlns" {
  330. if attr.Name.Space != "" && attr.Name.Space != "xml" && attr.Name.Space != xmlURL {
  331. return fmt.Errorf("xml: cannot redefine xmlns attribute prefix")
  332. }
  333. } else if attr.Name.Space == "xmlns" && attr.Name.Local != "" {
  334. prefix = attr.Name.Local
  335. if attr.Value == "" {
  336. // Technically, an empty XML namespace is allowed for an attribute.
  337. // From http://www.w3.org/TR/xml-names11/#scoping-defaulting:
  338. //
  339. // The attribute value in a namespace declaration for a prefix may be
  340. // empty. This has the effect, within the scope of the declaration, of removing
  341. // any association of the prefix with a namespace name.
  342. //
  343. // However our namespace prefixes here are used only as hints. There's
  344. // no need to respect the removal of a namespace prefix, so we ignore it.
  345. return nil
  346. }
  347. } else {
  348. // Ignore: it's not a namespace definition
  349. return nil
  350. }
  351. if prefix == "" {
  352. if attr.Value == p.defaultNS {
  353. // No need for redefinition.
  354. return nil
  355. }
  356. if attr.Value != "" && ignoreNonEmptyDefault {
  357. // We have an xmlns="..." value but
  358. // it can't define a name space in this context,
  359. // probably because the element has an empty
  360. // name space. In this case, we just ignore
  361. // the name space declaration.
  362. return nil
  363. }
  364. } else if _, ok := p.attrPrefix[attr.Value]; ok {
  365. // There's already a prefix for the given name space,
  366. // so use that. This prevents us from
  367. // having two prefixes for the same name space
  368. // so attrNS and attrPrefix can remain bijective.
  369. return nil
  370. }
  371. p.pushPrefix(prefix, attr.Value)
  372. return nil
  373. }
  374. // createNSPrefix creates a name space prefix attribute
  375. // to use for the given name space, defining a new prefix
  376. // if necessary.
  377. // If isAttr is true, the prefix is to be created for an attribute
  378. // prefix, which means that the default name space cannot
  379. // be used.
  380. func (p *printer) createNSPrefix(url string, isAttr bool) {
  381. if _, ok := p.attrPrefix[url]; ok {
  382. // We already have a prefix for the given URL.
  383. return
  384. }
  385. switch {
  386. case !isAttr && url == p.defaultNS:
  387. // We can use the default name space.
  388. return
  389. case url == "":
  390. // The only way we can encode names in the empty
  391. // name space is by using the default name space,
  392. // so we must use that.
  393. if p.defaultNS != "" {
  394. // The default namespace is non-empty, so we
  395. // need to set it to empty.
  396. p.pushPrefix("", "")
  397. }
  398. return
  399. case url == xmlURL:
  400. return
  401. }
  402. // TODO If the URL is an existing prefix, we could
  403. // use it as is. That would enable the
  404. // marshaling of elements that had been unmarshaled
  405. // and with a name space prefix that was not found.
  406. // although technically it would be incorrect.
  407. // Pick a name. We try to use the final element of the path
  408. // but fall back to _.
  409. prefix := strings.TrimRight(url, "/")
  410. if i := strings.LastIndex(prefix, "/"); i >= 0 {
  411. prefix = prefix[i+1:]
  412. }
  413. if prefix == "" || !isName([]byte(prefix)) || strings.Contains(prefix, ":") {
  414. prefix = "_"
  415. }
  416. if strings.HasPrefix(prefix, "xml") {
  417. // xmlanything is reserved.
  418. prefix = "_" + prefix
  419. }
  420. if p.attrNS[prefix] != "" {
  421. // Name is taken. Find a better one.
  422. for p.seq++; ; p.seq++ {
  423. if id := prefix + "_" + strconv.Itoa(p.seq); p.attrNS[id] == "" {
  424. prefix = id
  425. break
  426. }
  427. }
  428. }
  429. p.pushPrefix(prefix, url)
  430. }
  431. // writeNamespaces writes xmlns attributes for all the
  432. // namespace prefixes that have been defined in
  433. // the current element.
  434. func (p *printer) writeNamespaces() {
  435. for i := len(p.prefixes) - 1; i >= 0; i-- {
  436. prefix := p.prefixes[i]
  437. if prefix.mark {
  438. return
  439. }
  440. p.WriteString(" ")
  441. if prefix.prefix == "" {
  442. // Default name space.
  443. p.WriteString(`xmlns="`)
  444. } else {
  445. p.WriteString("xmlns:")
  446. p.WriteString(prefix.prefix)
  447. p.WriteString(`="`)
  448. }
  449. EscapeText(p, []byte(p.nsForPrefix(prefix.prefix)))
  450. p.WriteString(`"`)
  451. }
  452. }
  453. // pushPrefix pushes a new prefix on the prefix stack
  454. // without checking to see if it is already defined.
  455. func (p *printer) pushPrefix(prefix, url string) {
  456. p.prefixes = append(p.prefixes, printerPrefix{
  457. prefix: prefix,
  458. url: p.nsForPrefix(prefix),
  459. })
  460. p.setAttrPrefix(prefix, url)
  461. }
  462. // nsForPrefix returns the name space for the given
  463. // prefix. Note that this is not valid for the
  464. // empty attribute prefix, which always has an empty
  465. // name space.
  466. func (p *printer) nsForPrefix(prefix string) string {
  467. if prefix == "" {
  468. return p.defaultNS
  469. }
  470. return p.attrNS[prefix]
  471. }
  472. // markPrefix marks the start of an element on the prefix
  473. // stack.
  474. func (p *printer) markPrefix() {
  475. p.prefixes = append(p.prefixes, printerPrefix{
  476. mark: true,
  477. })
  478. }
  479. // popPrefix pops all defined prefixes for the current
  480. // element.
  481. func (p *printer) popPrefix() {
  482. for len(p.prefixes) > 0 {
  483. prefix := p.prefixes[len(p.prefixes)-1]
  484. p.prefixes = p.prefixes[:len(p.prefixes)-1]
  485. if prefix.mark {
  486. break
  487. }
  488. p.setAttrPrefix(prefix.prefix, prefix.url)
  489. }
  490. }
  491. // setAttrPrefix sets an attribute name space prefix.
  492. // If url is empty, the attribute is removed.
  493. // If prefix is empty, the default name space is set.
  494. func (p *printer) setAttrPrefix(prefix, url string) {
  495. if prefix == "" {
  496. p.defaultNS = url
  497. return
  498. }
  499. if url == "" {
  500. delete(p.attrPrefix, p.attrNS[prefix])
  501. delete(p.attrNS, prefix)
  502. return
  503. }
  504. if p.attrPrefix == nil {
  505. // Need to define a new name space.
  506. p.attrPrefix = make(map[string]string)
  507. p.attrNS = make(map[string]string)
  508. }
  509. // Remove any old prefix value. This is OK because we maintain a
  510. // strict one-to-one mapping between prefix and URL (see
  511. // defineNS)
  512. delete(p.attrPrefix, p.attrNS[prefix])
  513. p.attrPrefix[url] = prefix
  514. p.attrNS[prefix] = url
  515. }
  516. var (
  517. marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
  518. marshalerAttrType = reflect.TypeOf((*MarshalerAttr)(nil)).Elem()
  519. textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
  520. )
  521. // marshalValue writes one or more XML elements representing val.
  522. // If val was obtained from a struct field, finfo must have its details.
  523. func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplate *StartElement) error {
  524. if startTemplate != nil && startTemplate.Name.Local == "" {
  525. return fmt.Errorf("xml: EncodeElement of StartElement with missing name")
  526. }
  527. if !val.IsValid() {
  528. return nil
  529. }
  530. if finfo != nil && finfo.flags&fOmitEmpty != 0 && isEmptyValue(val) {
  531. return nil
  532. }
  533. // Drill into interfaces and pointers.
  534. // This can turn into an infinite loop given a cyclic chain,
  535. // but it matches the Go 1 behavior.
  536. for val.Kind() == reflect.Interface || val.Kind() == reflect.Ptr {
  537. if val.IsNil() {
  538. return nil
  539. }
  540. val = val.Elem()
  541. }
  542. kind := val.Kind()
  543. typ := val.Type()
  544. // Check for marshaler.
  545. if val.CanInterface() && typ.Implements(marshalerType) {
  546. return p.marshalInterface(val.Interface().(Marshaler), p.defaultStart(typ, finfo, startTemplate))
  547. }
  548. if val.CanAddr() {
  549. pv := val.Addr()
  550. if pv.CanInterface() && pv.Type().Implements(marshalerType) {
  551. return p.marshalInterface(pv.Interface().(Marshaler), p.defaultStart(pv.Type(), finfo, startTemplate))
  552. }
  553. }
  554. // Check for text marshaler.
  555. if val.CanInterface() && typ.Implements(textMarshalerType) {
  556. return p.marshalTextInterface(val.Interface().(encoding.TextMarshaler), p.defaultStart(typ, finfo, startTemplate))
  557. }
  558. if val.CanAddr() {
  559. pv := val.Addr()
  560. if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
  561. return p.marshalTextInterface(pv.Interface().(encoding.TextMarshaler), p.defaultStart(pv.Type(), finfo, startTemplate))
  562. }
  563. }
  564. // Slices and arrays iterate over the elements. They do not have an enclosing tag.
  565. if (kind == reflect.Slice || kind == reflect.Array) && typ.Elem().Kind() != reflect.Uint8 {
  566. for i, n := 0, val.Len(); i < n; i++ {
  567. if err := p.marshalValue(val.Index(i), finfo, startTemplate); err != nil {
  568. return err
  569. }
  570. }
  571. return nil
  572. }
  573. tinfo, err := getTypeInfo(typ)
  574. if err != nil {
  575. return err
  576. }
  577. // Create start element.
  578. // Precedence for the XML element name is:
  579. // 0. startTemplate
  580. // 1. XMLName field in underlying struct;
  581. // 2. field name/tag in the struct field; and
  582. // 3. type name
  583. var start StartElement
  584. // explicitNS records whether the element's name space has been
  585. // explicitly set (for example an XMLName field).
  586. explicitNS := false
  587. if startTemplate != nil {
  588. start.Name = startTemplate.Name
  589. explicitNS = true
  590. start.Attr = append(start.Attr, startTemplate.Attr...)
  591. } else if tinfo.xmlname != nil {
  592. xmlname := tinfo.xmlname
  593. if xmlname.name != "" {
  594. start.Name.Space, start.Name.Local = xmlname.xmlns, xmlname.name
  595. } else if v, ok := xmlname.value(val).Interface().(Name); ok && v.Local != "" {
  596. start.Name = v
  597. }
  598. explicitNS = true
  599. }
  600. if start.Name.Local == "" && finfo != nil {
  601. start.Name.Local = finfo.name
  602. if finfo.xmlns != "" {
  603. start.Name.Space = finfo.xmlns
  604. explicitNS = true
  605. }
  606. }
  607. if start.Name.Local == "" {
  608. name := typ.Name()
  609. if name == "" {
  610. return &UnsupportedTypeError{typ}
  611. }
  612. start.Name.Local = name
  613. }
  614. // defaultNS records the default name space as set by a xmlns="..."
  615. // attribute. We don't set p.defaultNS because we want to let
  616. // the attribute writing code (in p.defineNS) be solely responsible
  617. // for maintaining that.
  618. defaultNS := p.defaultNS
  619. // Attributes
  620. for i := range tinfo.fields {
  621. finfo := &tinfo.fields[i]
  622. if finfo.flags&fAttr == 0 {
  623. continue
  624. }
  625. attr, err := p.fieldAttr(finfo, val)
  626. if err != nil {
  627. return err
  628. }
  629. if attr.Name.Local == "" {
  630. continue
  631. }
  632. start.Attr = append(start.Attr, attr)
  633. if attr.Name.Space == "" && attr.Name.Local == "xmlns" {
  634. defaultNS = attr.Value
  635. }
  636. }
  637. if !explicitNS {
  638. // Historic behavior: elements use the default name space
  639. // they are contained in by default.
  640. start.Name.Space = defaultNS
  641. }
  642. // Historic behaviour: an element that's in a namespace sets
  643. // the default namespace for all elements contained within it.
  644. start.setDefaultNamespace()
  645. if err := p.writeStart(&start); err != nil {
  646. return err
  647. }
  648. if val.Kind() == reflect.Struct {
  649. err = p.marshalStruct(tinfo, val)
  650. } else {
  651. s, b, err1 := p.marshalSimple(typ, val)
  652. if err1 != nil {
  653. err = err1
  654. } else if b != nil {
  655. EscapeText(p, b)
  656. } else {
  657. p.EscapeString(s)
  658. }
  659. }
  660. if err != nil {
  661. return err
  662. }
  663. if err := p.writeEnd(start.Name); err != nil {
  664. return err
  665. }
  666. return p.cachedWriteError()
  667. }
  668. // fieldAttr returns the attribute of the given field.
  669. // If the returned attribute has an empty Name.Local,
  670. // it should not be used.
  671. // The given value holds the value containing the field.
  672. func (p *printer) fieldAttr(finfo *fieldInfo, val reflect.Value) (Attr, error) {
  673. fv := finfo.value(val)
  674. name := Name{Space: finfo.xmlns, Local: finfo.name}
  675. if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) {
  676. return Attr{}, nil
  677. }
  678. if fv.Kind() == reflect.Interface && fv.IsNil() {
  679. return Attr{}, nil
  680. }
  681. if fv.CanInterface() && fv.Type().Implements(marshalerAttrType) {
  682. attr, err := fv.Interface().(MarshalerAttr).MarshalXMLAttr(name)
  683. return attr, err
  684. }
  685. if fv.CanAddr() {
  686. pv := fv.Addr()
  687. if pv.CanInterface() && pv.Type().Implements(marshalerAttrType) {
  688. attr, err := pv.Interface().(MarshalerAttr).MarshalXMLAttr(name)
  689. return attr, err
  690. }
  691. }
  692. if fv.CanInterface() && fv.Type().Implements(textMarshalerType) {
  693. text, err := fv.Interface().(encoding.TextMarshaler).MarshalText()
  694. if err != nil {
  695. return Attr{}, err
  696. }
  697. return Attr{name, string(text)}, nil
  698. }
  699. if fv.CanAddr() {
  700. pv := fv.Addr()
  701. if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
  702. text, err := pv.Interface().(encoding.TextMarshaler).MarshalText()
  703. if err != nil {
  704. return Attr{}, err
  705. }
  706. return Attr{name, string(text)}, nil
  707. }
  708. }
  709. // Dereference or skip nil pointer, interface values.
  710. switch fv.Kind() {
  711. case reflect.Ptr, reflect.Interface:
  712. if fv.IsNil() {
  713. return Attr{}, nil
  714. }
  715. fv = fv.Elem()
  716. }
  717. s, b, err := p.marshalSimple(fv.Type(), fv)
  718. if err != nil {
  719. return Attr{}, err
  720. }
  721. if b != nil {
  722. s = string(b)
  723. }
  724. return Attr{name, s}, nil
  725. }
  726. // defaultStart returns the default start element to use,
  727. // given the reflect type, field info, and start template.
  728. func (p *printer) defaultStart(typ reflect.Type, finfo *fieldInfo, startTemplate *StartElement) StartElement {
  729. var start StartElement
  730. // Precedence for the XML element name is as above,
  731. // except that we do not look inside structs for the first field.
  732. if startTemplate != nil {
  733. start.Name = startTemplate.Name
  734. start.Attr = append(start.Attr, startTemplate.Attr...)
  735. } else if finfo != nil && finfo.name != "" {
  736. start.Name.Local = finfo.name
  737. start.Name.Space = finfo.xmlns
  738. } else if typ.Name() != "" {
  739. start.Name.Local = typ.Name()
  740. } else {
  741. // Must be a pointer to a named type,
  742. // since it has the Marshaler methods.
  743. start.Name.Local = typ.Elem().Name()
  744. }
  745. // Historic behaviour: elements use the name space of
  746. // the element they are contained in by default.
  747. if start.Name.Space == "" {
  748. start.Name.Space = p.defaultNS
  749. }
  750. start.setDefaultNamespace()
  751. return start
  752. }
  753. // marshalInterface marshals a Marshaler interface value.
  754. func (p *printer) marshalInterface(val Marshaler, start StartElement) error {
  755. // Push a marker onto the tag stack so that MarshalXML
  756. // cannot close the XML tags that it did not open.
  757. p.tags = append(p.tags, Name{})
  758. n := len(p.tags)
  759. err := val.MarshalXML(p.encoder, start)
  760. if err != nil {
  761. return err
  762. }
  763. // Make sure MarshalXML closed all its tags. p.tags[n-1] is the mark.
  764. if len(p.tags) > n {
  765. return fmt.Errorf("xml: %s.MarshalXML wrote invalid XML: <%s> not closed", receiverType(val), p.tags[len(p.tags)-1].Local)
  766. }
  767. p.tags = p.tags[:n-1]
  768. return nil
  769. }
  770. // marshalTextInterface marshals a TextMarshaler interface value.
  771. func (p *printer) marshalTextInterface(val encoding.TextMarshaler, start StartElement) error {
  772. if err := p.writeStart(&start); err != nil {
  773. return err
  774. }
  775. text, err := val.MarshalText()
  776. if err != nil {
  777. return err
  778. }
  779. EscapeText(p, text)
  780. return p.writeEnd(start.Name)
  781. }
  782. // writeStart writes the given start element.
  783. func (p *printer) writeStart(start *StartElement) error {
  784. if start.Name.Local == "" {
  785. return fmt.Errorf("xml: start tag with no name")
  786. }
  787. p.tags = append(p.tags, start.Name)
  788. p.markPrefix()
  789. // Define any name spaces explicitly declared in the attributes.
  790. // We do this as a separate pass so that explicitly declared prefixes
  791. // will take precedence over implicitly declared prefixes
  792. // regardless of the order of the attributes.
  793. ignoreNonEmptyDefault := start.Name.Space == ""
  794. for _, attr := range start.Attr {
  795. if err := p.defineNS(attr, ignoreNonEmptyDefault); err != nil {
  796. return err
  797. }
  798. }
  799. // Define any new name spaces implied by the attributes.
  800. for _, attr := range start.Attr {
  801. name := attr.Name
  802. // From http://www.w3.org/TR/xml-names11/#defaulting
  803. // "Default namespace declarations do not apply directly
  804. // to attribute names; the interpretation of unprefixed
  805. // attributes is determined by the element on which they
  806. // appear."
  807. // This means we don't need to create a new namespace
  808. // when an attribute name space is empty.
  809. if name.Space != "" && !name.isNamespace() {
  810. p.createNSPrefix(name.Space, true)
  811. }
  812. }
  813. p.createNSPrefix(start.Name.Space, false)
  814. p.writeIndent(1)
  815. p.WriteByte('<')
  816. p.writeName(start.Name, false)
  817. p.writeNamespaces()
  818. for _, attr := range start.Attr {
  819. name := attr.Name
  820. if name.Local == "" || name.isNamespace() {
  821. // Namespaces have already been written by writeNamespaces above.
  822. continue
  823. }
  824. p.WriteByte(' ')
  825. p.writeName(name, true)
  826. p.WriteString(`="`)
  827. p.EscapeString(attr.Value)
  828. p.WriteByte('"')
  829. }
  830. p.WriteByte('>')
  831. return nil
  832. }
  833. // writeName writes the given name. It assumes
  834. // that p.createNSPrefix(name) has already been called.
  835. func (p *printer) writeName(name Name, isAttr bool) {
  836. if prefix := p.prefixForNS(name.Space, isAttr); prefix != "" {
  837. p.WriteString(prefix)
  838. p.WriteByte(':')
  839. }
  840. p.WriteString(name.Local)
  841. }
  842. func (p *printer) writeEnd(name Name) error {
  843. if name.Local == "" {
  844. return fmt.Errorf("xml: end tag with no name")
  845. }
  846. if len(p.tags) == 0 || p.tags[len(p.tags)-1].Local == "" {
  847. return fmt.Errorf("xml: end tag </%s> without start tag", name.Local)
  848. }
  849. if top := p.tags[len(p.tags)-1]; top != name {
  850. if top.Local != name.Local {
  851. return fmt.Errorf("xml: end tag </%s> does not match start tag <%s>", name.Local, top.Local)
  852. }
  853. 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)
  854. }
  855. p.tags = p.tags[:len(p.tags)-1]
  856. p.writeIndent(-1)
  857. p.WriteByte('<')
  858. p.WriteByte('/')
  859. p.writeName(name, false)
  860. p.WriteByte('>')
  861. p.popPrefix()
  862. return nil
  863. }
  864. func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) (string, []byte, error) {
  865. switch val.Kind() {
  866. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  867. return strconv.FormatInt(val.Int(), 10), nil, nil
  868. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  869. return strconv.FormatUint(val.Uint(), 10), nil, nil
  870. case reflect.Float32, reflect.Float64:
  871. return strconv.FormatFloat(val.Float(), 'g', -1, val.Type().Bits()), nil, nil
  872. case reflect.String:
  873. return val.String(), nil, nil
  874. case reflect.Bool:
  875. return strconv.FormatBool(val.Bool()), nil, nil
  876. case reflect.Array:
  877. if typ.Elem().Kind() != reflect.Uint8 {
  878. break
  879. }
  880. // [...]byte
  881. var bytes []byte
  882. if val.CanAddr() {
  883. bytes = val.Slice(0, val.Len()).Bytes()
  884. } else {
  885. bytes = make([]byte, val.Len())
  886. reflect.Copy(reflect.ValueOf(bytes), val)
  887. }
  888. return "", bytes, nil
  889. case reflect.Slice:
  890. if typ.Elem().Kind() != reflect.Uint8 {
  891. break
  892. }
  893. // []byte
  894. return "", val.Bytes(), nil
  895. }
  896. return "", nil, &UnsupportedTypeError{typ}
  897. }
  898. var ddBytes = []byte("--")
  899. func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
  900. s := parentStack{p: p}
  901. for i := range tinfo.fields {
  902. finfo := &tinfo.fields[i]
  903. if finfo.flags&fAttr != 0 {
  904. continue
  905. }
  906. vf := finfo.value(val)
  907. // Dereference or skip nil pointer, interface values.
  908. switch vf.Kind() {
  909. case reflect.Ptr, reflect.Interface:
  910. if !vf.IsNil() {
  911. vf = vf.Elem()
  912. }
  913. }
  914. switch finfo.flags & fMode {
  915. case fCharData:
  916. if err := s.setParents(&noField, reflect.Value{}); err != nil {
  917. return err
  918. }
  919. if vf.CanInterface() && vf.Type().Implements(textMarshalerType) {
  920. data, err := vf.Interface().(encoding.TextMarshaler).MarshalText()
  921. if err != nil {
  922. return err
  923. }
  924. Escape(p, data)
  925. continue
  926. }
  927. if vf.CanAddr() {
  928. pv := vf.Addr()
  929. if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
  930. data, err := pv.Interface().(encoding.TextMarshaler).MarshalText()
  931. if err != nil {
  932. return err
  933. }
  934. Escape(p, data)
  935. continue
  936. }
  937. }
  938. var scratch [64]byte
  939. switch vf.Kind() {
  940. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  941. Escape(p, strconv.AppendInt(scratch[:0], vf.Int(), 10))
  942. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  943. Escape(p, strconv.AppendUint(scratch[:0], vf.Uint(), 10))
  944. case reflect.Float32, reflect.Float64:
  945. Escape(p, strconv.AppendFloat(scratch[:0], vf.Float(), 'g', -1, vf.Type().Bits()))
  946. case reflect.Bool:
  947. Escape(p, strconv.AppendBool(scratch[:0], vf.Bool()))
  948. case reflect.String:
  949. if err := EscapeText(p, []byte(vf.String())); err != nil {
  950. return err
  951. }
  952. case reflect.Slice:
  953. if elem, ok := vf.Interface().([]byte); ok {
  954. if err := EscapeText(p, elem); err != nil {
  955. return err
  956. }
  957. }
  958. }
  959. continue
  960. case fComment:
  961. if err := s.setParents(&noField, reflect.Value{}); err != nil {
  962. return err
  963. }
  964. k := vf.Kind()
  965. if !(k == reflect.String || k == reflect.Slice && vf.Type().Elem().Kind() == reflect.Uint8) {
  966. return fmt.Errorf("xml: bad type for comment field of %s", val.Type())
  967. }
  968. if vf.Len() == 0 {
  969. continue
  970. }
  971. p.writeIndent(0)
  972. p.WriteString("<!--")
  973. dashDash := false
  974. dashLast := false
  975. switch k {
  976. case reflect.String:
  977. s := vf.String()
  978. dashDash = strings.Index(s, "--") >= 0
  979. dashLast = s[len(s)-1] == '-'
  980. if !dashDash {
  981. p.WriteString(s)
  982. }
  983. case reflect.Slice:
  984. b := vf.Bytes()
  985. dashDash = bytes.Index(b, ddBytes) >= 0
  986. dashLast = b[len(b)-1] == '-'
  987. if !dashDash {
  988. p.Write(b)
  989. }
  990. default:
  991. panic("can't happen")
  992. }
  993. if dashDash {
  994. return fmt.Errorf(`xml: comments must not contain "--"`)
  995. }
  996. if dashLast {
  997. // "--->" is invalid grammar. Make it "- -->"
  998. p.WriteByte(' ')
  999. }
  1000. p.WriteString("-->")
  1001. continue
  1002. case fInnerXml:
  1003. iface := vf.Interface()
  1004. switch raw := iface.(type) {
  1005. case []byte:
  1006. p.Write(raw)
  1007. continue
  1008. case string:
  1009. p.WriteString(raw)
  1010. continue
  1011. }
  1012. case fElement, fElement | fAny:
  1013. if err := s.setParents(finfo, vf); err != nil {
  1014. return err
  1015. }
  1016. }
  1017. if err := p.marshalValue(vf, finfo, nil); err != nil {
  1018. return err
  1019. }
  1020. }
  1021. if err := s.setParents(&noField, reflect.Value{}); err != nil {
  1022. return err
  1023. }
  1024. return p.cachedWriteError()
  1025. }
  1026. var noField fieldInfo
  1027. // return the bufio Writer's cached write error
  1028. func (p *printer) cachedWriteError() error {
  1029. _, err := p.Write(nil)
  1030. return err
  1031. }
  1032. func (p *printer) writeIndent(depthDelta int) {
  1033. if len(p.prefix) == 0 && len(p.indent) == 0 {
  1034. return
  1035. }
  1036. if depthDelta < 0 {
  1037. p.depth--
  1038. if p.indentedIn {
  1039. p.indentedIn = false
  1040. return
  1041. }
  1042. p.indentedIn = false
  1043. }
  1044. if p.putNewline {
  1045. p.WriteByte('\n')
  1046. } else {
  1047. p.putNewline = true
  1048. }
  1049. if len(p.prefix) > 0 {
  1050. p.WriteString(p.prefix)
  1051. }
  1052. if len(p.indent) > 0 {
  1053. for i := 0; i < p.depth; i++ {
  1054. p.WriteString(p.indent)
  1055. }
  1056. }
  1057. if depthDelta > 0 {
  1058. p.depth++
  1059. p.indentedIn = true
  1060. }
  1061. }
  1062. type parentStack struct {
  1063. p *printer
  1064. xmlns string
  1065. parents []string
  1066. }
  1067. // setParents sets the stack of current parents to those found in finfo.
  1068. // It only writes the start elements if vf holds a non-nil value.
  1069. // If finfo is &noField, it pops all elements.
  1070. func (s *parentStack) setParents(finfo *fieldInfo, vf reflect.Value) error {
  1071. xmlns := s.p.defaultNS
  1072. if finfo.xmlns != "" {
  1073. xmlns = finfo.xmlns
  1074. }
  1075. commonParents := 0
  1076. if xmlns == s.xmlns {
  1077. for ; commonParents < len(finfo.parents) && commonParents < len(s.parents); commonParents++ {
  1078. if finfo.parents[commonParents] != s.parents[commonParents] {
  1079. break
  1080. }
  1081. }
  1082. }
  1083. // Pop off any parents that aren't in common with the previous field.
  1084. for i := len(s.parents) - 1; i >= commonParents; i-- {
  1085. if err := s.p.writeEnd(Name{
  1086. Space: s.xmlns,
  1087. Local: s.parents[i],
  1088. }); err != nil {
  1089. return err
  1090. }
  1091. }
  1092. s.parents = finfo.parents
  1093. s.xmlns = xmlns
  1094. if commonParents >= len(s.parents) {
  1095. // No new elements to push.
  1096. return nil
  1097. }
  1098. if (vf.Kind() == reflect.Ptr || vf.Kind() == reflect.Interface) && vf.IsNil() {
  1099. // The element is nil, so no need for the start elements.
  1100. s.parents = s.parents[:commonParents]
  1101. return nil
  1102. }
  1103. // Push any new parents required.
  1104. for _, name := range s.parents[commonParents:] {
  1105. start := &StartElement{
  1106. Name: Name{
  1107. Space: s.xmlns,
  1108. Local: name,
  1109. },
  1110. }
  1111. // Set the default name space for parent elements
  1112. // to match what we do with other elements.
  1113. if s.xmlns != s.p.defaultNS {
  1114. start.setDefaultNamespace()
  1115. }
  1116. if err := s.p.writeStart(start); err != nil {
  1117. return err
  1118. }
  1119. }
  1120. return nil
  1121. }
  1122. // A MarshalXMLError is returned when Marshal encounters a type
  1123. // that cannot be converted into XML.
  1124. type UnsupportedTypeError struct {
  1125. Type reflect.Type
  1126. }
  1127. func (e *UnsupportedTypeError) Error() string {
  1128. return "xml: unsupported type: " + e.Type.String()
  1129. }
  1130. func isEmptyValue(v reflect.Value) bool {
  1131. switch v.Kind() {
  1132. case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
  1133. return v.Len() == 0
  1134. case reflect.Bool:
  1135. return !v.Bool()
  1136. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1137. return v.Int() == 0
  1138. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1139. return v.Uint() == 0
  1140. case reflect.Float32, reflect.Float64:
  1141. return v.Float() == 0
  1142. case reflect.Interface, reflect.Ptr:
  1143. return v.IsNil()
  1144. }
  1145. return false
  1146. }