Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop json.Marshal from escaping < and >?

Tags:

go

package main  import "fmt" import "encoding/json"  type Track struct {     XmlRequest string `json:"xmlRequest"` }  func main() {     message := new(Track)     message.XmlRequest = "<car><mirror>XML</mirror></car>"     fmt.Println("Before Marshal", message)     messageJSON, _ := json.Marshal(message)     fmt.Println("After marshal", string(messageJSON)) } 

Is it possible to make json.Marshal not escape < and >? I currently get:

{"xmlRequest":"\u003ccar\u003e\u003cmirror\u003eXML\u003c/mirror\u003e\u003c/car\u003e"} 

but I am looking for something like this:

{"xmlRequest":"<car><mirror>XML</mirror></car>"} 
like image 785
Carlos Andrés García Avatar asked Feb 18 '15 23:02

Carlos Andrés García


1 Answers

As of Go 1.7, you still cannot do this with json.Marshal(). The source code for json.Marshal shows:

> err := e.marshal(v, encOpts{escapeHTML: true}) 

The reason json.Marshal always does this is:

String values encode as JSON strings coerced to valid UTF-8, replacing invalid bytes with the Unicode replacement rune. The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" to keep some browsers from misinterpreting JSON output as HTML. Ampersand "&" is also escaped to "\u0026" for the same reason.

This means you cannot even do it by writing a custom func (t *Track) MarshalJSON(), you have to use something that does not satisfy the json.Marshaler interface.

So, the workaround, is to write your own function:

func (t *Track) JSON() ([]byte, error) {     buffer := &bytes.Buffer{}     encoder := json.NewEncoder(buffer)     encoder.SetEscapeHTML(false)     err := encoder.Encode(t)     return buffer.Bytes(), err } 

https://play.golang.org/p/FAH-XS-QMC

If you want a generic solution for any struct, you could do:

func JSONMarshal(t interface{}) ([]byte, error) {     buffer := &bytes.Buffer{}     encoder := json.NewEncoder(buffer)     encoder.SetEscapeHTML(false)     err := encoder.Encode(t)     return buffer.Bytes(), err } 

https://play.golang.org/p/bdqv3TUGr3

like image 57
dave Avatar answered Oct 16 '22 04:10

dave