package xmlimport ()// Value represents an XML Value type// XML Value types: Object, Array, Map, String, Number, Boolean.typeValuestruct {wwriterscratch *[]byte// xml start element is the associated start element for the ValuestartElementStartElement// indicates if the Value represents a flattened shapeisFlattenedbool}// newFlattenedValue returns a Value encoder. newFlattenedValue does NOT write the start element tagfunc ( writer, *[]byte, StartElement) Value {returnValue{w: ,scratch: ,startElement: , }}// newValue writes the start element xml tag and returns a Valuefunc ( writer, *[]byte, StartElement) Value {writeStartElement(, )returnValue{w: , scratch: , startElement: }}// writeStartElement takes in a start element and writes it.// It handles namespace, attributes in start element.func ( writer, StartElement) error {if .isZero() {returnfmt.Errorf("xml start element cannot be nil") } .WriteRune(leftAngleBracket)iflen(.Name.Space) != 0 {escapeString(, .Name.Space) .WriteRune(colon) }escapeString(, .Name.Local)for , := range .Attr { .WriteRune(' ')writeAttribute(, &) } .WriteRune(rightAngleBracket)returnnil}// writeAttribute writes an attribute from a provided Attribute// For a namespace attribute, the attr.Name.Space must be defined as "xmlns".// https://www.w3.org/TR/REC-xml-names/#NT-DefaultAttNamefunc ( writer, *Attr) {// if local, space both are not emptyiflen(.Name.Space) != 0 && len(.Name.Local) != 0 {escapeString(, .Name.Space) .WriteRune(colon) }// if prefix is empty, the default `xmlns` space should be used as prefix.iflen(.Name.Local) == 0 { .Name.Local = .Name.Space }escapeString(, .Name.Local) .WriteRune(equals) .WriteRune(quote)escapeString(, .Value) .WriteRune(quote)}// writeEndElement takes in a end element and writes it.func ( writer, EndElement) error {if .isZero() {returnfmt.Errorf("xml end element cannot be nil") } .WriteRune(leftAngleBracket) .WriteRune(forwardSlash)iflen(.Name.Space) != 0 {escapeString(, .Name.Space) .WriteRune(colon) }escapeString(, .Name.Local) .WriteRune(rightAngleBracket)returnnil}// String encodes v as a XML string.// It will auto close the parent xml element tag.func ( Value) ( string) {escapeString(.w, ) .Close()}// Byte encodes v as a XML number.// It will auto close the parent xml element tag.func ( Value) ( int8) { .Long(int64())}// Short encodes v as a XML number.// It will auto close the parent xml element tag.func ( Value) ( int16) { .Long(int64())}// Integer encodes v as a XML number.// It will auto close the parent xml element tag.func ( Value) ( int32) { .Long(int64())}// Long encodes v as a XML number.// It will auto close the parent xml element tag.func ( Value) ( int64) { *.scratch = strconv.AppendInt((*.scratch)[:0], , 10) .w.Write(*.scratch) .Close()}// Float encodes v as a XML number.// It will auto close the parent xml element tag.func ( Value) ( float32) { .float(float64(), 32) .Close()}// Double encodes v as a XML number.// It will auto close the parent xml element tag.func ( Value) ( float64) { .float(, 64) .Close()}func ( Value) ( float64, int) { *.scratch = encoding.EncodeFloat((*.scratch)[:0], , ) .w.Write(*.scratch)}// Boolean encodes v as a XML boolean.// It will auto close the parent xml element tag.func ( Value) ( bool) { *.scratch = strconv.AppendBool((*.scratch)[:0], ) .w.Write(*.scratch) .Close()}// Base64EncodeBytes writes v as a base64 value in XML string.// It will auto close the parent xml element tag.func ( Value) ( []byte) {encodeByteSlice(.w, (*.scratch)[:0], ) .Close()}// BigInteger encodes v big.Int as XML value.// It will auto close the parent xml element tag.func ( Value) ( *big.Int) { .w.Write([]byte(.Text(10))) .Close()}// BigDecimal encodes v big.Float as XML value.// It will auto close the parent xml element tag.func ( Value) ( *big.Float) {if , := .Int64(); == big.Exact { .Long()return } .w.Write([]byte(.Text('e', -1))) .Close()}// Write writes v directly to the xml document// if escapeXMLText is set to true, write will escape text.// It will auto close the parent xml element tag.func ( Value) ( []byte, bool) {// escape and write xml textif {escapeText(.w, ) } else {// write xml directly .w.Write() } .Close()}// MemberElement does member element encoding. It returns a Value.// Member Element method should be used for all shapes except flattened shapes.//// A call to MemberElement will write nested element tags directly using the// provided start element. The value returned by MemberElement should be closed.func ( Value) ( StartElement) Value {returnnewValue(.w, .scratch, )}// FlattenedElement returns flattened element encoding. It returns a Value.// This method should be used for flattened shapes.//// Unlike MemberElement, flattened element will NOT write element tags// directly for the associated start element.//// The value returned by the FlattenedElement does not need to be closed.func ( Value) ( StartElement) Value { := newFlattenedValue(.w, .scratch, ) .isFlattened = truereturn}// Array returns an array encoder. By default, the members of array are// wrapped with `<member>` element tag.// If value is marked as flattened, the start element is used to wrap the members instead of// the `<member>` element.func ( Value) () *Array {returnnewArray(.w, .scratch, arrayMemberWrapper, .startElement, .isFlattened)}/*ArrayWithCustomName returns an array encoder.It takes named start element as an argument, the named start element will used to wrap xml array entries.for eg, `<someList><customName>entry1</customName></someList>`Here `customName` named start element will be wrapped on each array member.*/func ( Value) ( StartElement) *Array {returnnewArray(.w, .scratch, , .startElement, .isFlattened)}/*Map returns a map encoder. By default, the map entries arewrapped with `<entry>` element tag.If value is marked as flattened, the start element is used to wrap the entry instead ofthe `<member>` element.*/func ( Value) () *Map {// flattened mapif .isFlattened {returnnewFlattenedMap(.w, .scratch, .startElement) }// un-flattened mapreturnnewMap(.w, .scratch)}// encodeByteSlice is modified copy of json encoder's encodeByteSlice.// It is used to base64 encode a byte slice.func ( writer, []byte, []byte) {if == nil {return } := base64.StdEncoding.EncodedLen(len())if <= len() {// If the encoded bytes fit in e.scratch, avoid an extra // allocation and use the cheaper Encoding.Encode. := [:]base64.StdEncoding.Encode(, ) .Write() } elseif <= 1024 {// The encoded bytes are short enough to allocate for, and // Encoding.Encode is still cheaper. := make([]byte, )base64.StdEncoding.Encode(, ) .Write() } else {// The encoded bytes are too long to cheaply allocate, and // Encoding.Encode is no longer noticeably cheaper. := base64.NewEncoder(base64.StdEncoding, ) .Write() .Close() }}// IsFlattened returns true if value is for flattened shape.func ( Value) () bool {return .isFlattened}// Close closes the value.func ( Value) () {writeEndElement(.w, .startElement.End())}
The pages are generated with Goldsv0.4.9. (GOOS=linux GOARCH=amd64)