2015-02-18 15 views
9
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)) 
} 

Czy można usunąć z numeru < i >? Obecnie otrzymujemy:Jak zatrzymać json.Marshal przed ucieczką < and >?

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

ale szukam czegoś takiego:

{"xmlRequest":"<car><mirror>XML</mirror></car>"} 
+2

Obie formy są równoważne JSON: ucieka powinny być interpretowane przez co parser wysłaniu do JSON, więc ta różnica powinna być przejrzysta. –

+0

Podobne pytanie z tą samą odpowiedzią: http://stackoverflow.com/questions/24656624/golang-display-character-not-ascii-like-not-0026/24657016#24657016 –

Odpowiedz

9

Od Go 1.7, nadal nie można tego zrobić z json.Marshal(). W source code for json.Marshal pokazuje:

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

Powodem json.Marshal zawsze robi to:

wartości String zakodować jako ciągi JSON zmuszany do ważnego UTF-8, zastąpienie nieprawidłowych bajtów z wymianą runy Unicode. Nawiasy kątowe "<" i ">" są przekształcane w znaki "\ u003c" i "\ u003e" , aby niektóre przeglądarki źle interpretowały wynik JSON jako HTML. Ampersand "&" również uciekł do "\ u0026" z tego samego powodu.

Oznacza to, że nie można nawet zrobić pisząc zwyczaj func (t *Track) MarshalJSON(), trzeba użyć czegoś, co nie spełnia interfejs json.Marshaler.

Tak, obejście, to napisać własną funkcję:

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

Jeśli chcesz rodzajowe rozwiązanie dla każdej struktury, można zrobić:

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

+0

https://github.com/golang/go/issues/8592 Wymiana strun w drugim przebiegu jest nieskutecznym i uciążliwym rozwiązaniem. – Codefor

+0

Dziękuję za szczegółowe opisanie tego. To bardzo zaskakujące. Wpadłem na to, gdy otrzymałem zaskakujące błędy podczas ustawiania wartości w JSONB dla PostgreSQL. – carbocation

+1

Ostatnią niespodzianką (chociaż jest dobrze udokumentowana) jest to, że Encode() dodaje znak nowej linii (\ n) na końcu. Tak więc, aby ukończyć to podejście normalizacyjne, możesz rozważyć łańcuchy. TrimRight (t, "\ n"). – carbocation

10

W Go1.7 the have added nowa opcja to naprawić:

kodowania/json: add Encoder.DisableHTMLEscaping ten to sposób, aby wyłączyć cytowanie <,>, i & w ciągi JSON.

odpowiednia funkcja jest

func (*Encoder) SetEscapeHTML 

To powinno być stosowane do Encoder.

enc := json.NewEncoder(os.Stdout) 
enc.SetEscapeHTML(false) 

Prosty przykład: https://play.golang.org/p/SJM3KLkYW-

Powiązane problemy