aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/json/jsontext/example_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/encoding/json/jsontext/example_test.go')
-rw-r--r--src/encoding/json/jsontext/example_test.go130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/encoding/json/jsontext/example_test.go b/src/encoding/json/jsontext/example_test.go
new file mode 100644
index 0000000000..4bf6a7ae5a
--- /dev/null
+++ b/src/encoding/json/jsontext/example_test.go
@@ -0,0 +1,130 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build goexperiment.jsonv2
+
+package jsontext_test
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "log"
+ "strings"
+
+ "encoding/json/jsontext"
+ "encoding/json/v2"
+)
+
+// This example demonstrates the use of the [Encoder] and [Decoder] to
+// parse and modify JSON without unmarshaling it into a concrete Go type.
+func Example_stringReplace() {
+ // Example input with non-idiomatic use of "Golang" instead of "Go".
+ const input = `{
+ "title": "Golang version 1 is released",
+ "author": "Andrew Gerrand",
+ "date": "2012-03-28",
+ "text": "Today marks a major milestone in the development of the Golang programming language.",
+ "otherArticles": [
+ "Twelve Years of Golang",
+ "The Laws of Reflection",
+ "Learn Golang from your browser"
+ ]
+ }`
+
+ // Using a Decoder and Encoder, we can parse through every token,
+ // check and modify the token if necessary, and
+ // write the token to the output.
+ var replacements []jsontext.Pointer
+ in := strings.NewReader(input)
+ dec := jsontext.NewDecoder(in)
+ out := new(bytes.Buffer)
+ enc := jsontext.NewEncoder(out, jsontext.Multiline(true)) // expand for readability
+ for {
+ // Read a token from the input.
+ tok, err := dec.ReadToken()
+ if err != nil {
+ if err == io.EOF {
+ break
+ }
+ log.Fatal(err)
+ }
+
+ // Check whether the token contains the string "Golang" and
+ // replace each occurrence with "Go" instead.
+ if tok.Kind() == '"' && strings.Contains(tok.String(), "Golang") {
+ replacements = append(replacements, dec.StackPointer())
+ tok = jsontext.String(strings.ReplaceAll(tok.String(), "Golang", "Go"))
+ }
+
+ // Write the (possibly modified) token to the output.
+ if err := enc.WriteToken(tok); err != nil {
+ log.Fatal(err)
+ }
+ }
+
+ // Print the list of replacements and the adjusted JSON output.
+ if len(replacements) > 0 {
+ fmt.Println(`Replaced "Golang" with "Go" in:`)
+ for _, where := range replacements {
+ fmt.Println("\t" + where)
+ }
+ fmt.Println()
+ }
+ fmt.Println("Result:", out.String())
+
+ // Output:
+ // Replaced "Golang" with "Go" in:
+ // /title
+ // /text
+ // /otherArticles/0
+ // /otherArticles/2
+ //
+ // Result: {
+ // "title": "Go version 1 is released",
+ // "author": "Andrew Gerrand",
+ // "date": "2012-03-28",
+ // "text": "Today marks a major milestone in the development of the Go programming language.",
+ // "otherArticles": [
+ // "Twelve Years of Go",
+ // "The Laws of Reflection",
+ // "Learn Go from your browser"
+ // ]
+ // }
+}
+
+// Directly embedding JSON within HTML requires special handling for safety.
+// Escape certain runes to prevent JSON directly treated as HTML
+// from being able to perform <script> injection.
+//
+// This example shows how to obtain equivalent behavior provided by the
+// v1 [encoding/json] package that is no longer directly supported by this package.
+// Newly written code that intermix JSON and HTML should instead be using the
+// [github.com/google/safehtml] module for safety purposes.
+func ExampleEscapeForHTML() {
+ page := struct {
+ Title string
+ Body string
+ }{
+ Title: "Example Embedded Javascript",
+ Body: `<script> console.log("Hello, world!"); </script>`,
+ }
+
+ b, err := json.Marshal(&page,
+ // Escape certain runes within a JSON string so that
+ // JSON will be safe to directly embed inside HTML.
+ jsontext.EscapeForHTML(true),
+ jsontext.EscapeForJS(true),
+ jsontext.Multiline(true)) // expand for readability
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Println(string(b))
+
+ // Output:
+ // {
+ // "Title": "Example Embedded Javascript",
+ // "Body": "\u003cscript\u003e console.log(\"Hello, world!\"); \u003c/script\u003e"
+ // }
+}