package server import ( `encoding/xml` `errors` `io` ) /* MarshalXML encodes an XmlHeaders as XML in the following format: ()
SomeValue
Foo Bar
(
) For the above example, the field should be specified as `xml:"headers"`. However, the parent element name may be whatever you wish. */ func (x XmlHeaders) MarshalXML(e *xml.Encoder, start xml.StartElement) (err error) { var curKey string var vals []string var val string var hdr xml.StartElement var child xml.StartElement // TODO: Does xml.EncodeElement properly escape? // var escKBuf *bytes.Buffer // var escVBuf *bytes.Buffer // All values are []string, so we don't need any fancy parsing or switching or the like. // We do need to make sure we escape, though. if err = e.EncodeToken(start); err != nil { return } if x != nil && len(x) > 0 { // escKBuf = new(bytes.Buffer) // escVBuf = new(bytes.Buffer) for curKey, vals = range x { // escKBuf.Reset() // if err = xml.EscapeText(escKBuf, []byte(curKey)); err != nil { // return // } hdr = xml.StartElement{ Name: xml.Name{ Local: xmlHdrElem, }, Attr: []xml.Attr{ xml.Attr{ Name: xml.Name{ Local: xmlHdrElemName, }, // Value: escKBuf.String(), Value: curKey, }, }, } if err = e.EncodeToken(hdr); err != nil { return } for _, val = range vals { // escVBuf.Reset() // if err = xml.EscapeText(escVBuf, []byte(val)); err != nil { // return // } child = xml.StartElement{ Name: xml.Name{ Local: xmlHdrVal, }, } // if err = e.EncodeElement(escVBuf.String(), child); err != nil { if err = e.EncodeElement(val, child); err != nil { return } } if err = e.EncodeToken(hdr.End()); err != nil { return } } } if err = e.EncodeToken(start.End()); err != nil { return } return } // UnmarshalXML populates an XMLHeaders from an XML representation. See MarshalXML for example XML. func (x *XmlHeaders) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) { var tok xml.Token var xm XmlHeaders var hdrNm string var vals []string var val *string var nameFound bool for { if tok, err = d.Token(); err != nil { if errors.Is(err, io.EOF) { err = nil break } else { return } } switch elem := tok.(type) { case xml.StartElement: switch elem.Name.Local { case xmlHdrElem: nameFound = false vals = nil for _, a := range elem.Attr { if a.Name.Local == xmlHdrElemName { nameFound = true hdrNm = a.Value break } } if !nameFound { continue } case xmlHdrVal: if !nameFound { continue } if vals == nil { vals = make([]string, 0, 1) } val = new(string) if err = d.DecodeElement(val, &elem); err != nil { return } vals = append(vals, *val) } case xml.EndElement: if elem.Name.Local != xmlHdrElem { continue } if xm == nil { xm = make(XmlHeaders) } xm[hdrNm] = vals } } if xm != nil { *x = xm } return }