mojatter
Posted on August 9, 2022
Introduction
Go can parse dynamic json/yaml using the standard map[string]interface{}, etc. However, nested interface{} tends to result in ugly code.
Tree is one solution to this problem.
Features
- Parses json/yaml of unknown structure to get to nodes with fluent interface.
- Syntax similar to Go standard and map and slice.
- Find function can be specified the query expression.
- Edit function can be specified the edit expression.
- Bundled 'tq' that is a portable command-line JSON/YAML processor.
Examples in Go
Marshal and Unmarshal
func ExampleMarshalJSON() {
group := tree.Map{
"ID": tree.ToValue(1),
"Name": tree.ToValue("Reds"),
"Colors": tree.ToArrayValues("Crimson", "Red", "Ruby", "Maroon"),
}
b, err := json.Marshal(group)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b))
// Output:
// {"Colors":["Crimson","Red","Ruby","Maroon"],"ID":1,"Name":"Reds"}
}
func ExampleUnmarshalJSON() {
data := []byte(`[
{"Name": "Platypus", "Order": "Monotremata"},
{"Name": "Quoll", "Order": "Dasyuromorphia"}
]`)
var animals tree.Array
err := json.Unmarshal(data, &animals)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", animals)
// Output:
// [map[Name:Platypus Order:Monotremata] map[Name:Quoll Order:Dasyuromorphia]]
}
Get
func ExampleGet() {
group := tree.Map{
"ID": tree.ToValue(1),
"Name": tree.ToValue("Reds"),
"Colors": tree.ToArrayValues("Crimson", "Red", "Ruby", "Maroon"),
"Nil": nil,
}
fmt.Println(group.Get("Colors").Get(1))
fmt.Println(group.Get("Colors", 2))
fmt.Println(group.Get("Colors").Get(5).IsNil())
fmt.Println(group.Get("Nil").IsNil())
// Output:
// Red
// Ruby
// true
// true
}
Find
func ExampleFind() {
group := tree.Map{
"ID": tree.ToValue(1),
"Name": tree.ToValue("Reds"),
"Colors": tree.ToArrayValues("Crimson", "Red", "Ruby", "Maroon"),
}
rs, err := group.Find(".Colors[1:3]")
if err != nil {
log.Fatal(err)
}
for _, r := range rs {
fmt.Println(r)
}
// Output:
// Red
// Ruby
}
Edit
func ExampleEdit() {
var group tree.Node = tree.Map{
"ID": tree.ToValue(1),
"Name": tree.ToValue("Reds"),
"Colors": tree.ToArrayValues("Crimson", "Red", "Ruby", "Maroon"),
}
if err := tree.Edit(&group, ".Colors += \"Pink\""); err != nil {
log.Fatal(err)
}
fmt.Printf("Append Pink to Colors:\n %+v\n", group)
if err := tree.Edit(&group, ".Name = \"Blue\""); err != nil {
log.Fatal(err)
}
fmt.Printf("Set Blue to Name:\n %+v\n", group)
if err := tree.Edit(&group, ".Colors ^?"); err != nil {
log.Fatal(err)
}
fmt.Printf("Delete Colors:\n %+v\n", group)
// Output:
// Append Pink to Colors:
// map[Colors:[Crimson Red Ruby Maroon Pink] ID:1 Name:Reds]
// Set Blue to Name:
// map[Colors:[Crimson Red Ruby Maroon Pink] ID:1 Name:Blue]
// Delete Colors:
// map[ID:1 Name:Blue]
}
tq
tq is a portable command-line JSON/YAML processor. For more information please refer to jarxorg/tree.
Usage
tq is a command-line JSON/YAML processor.
Usage:
tq [flags] [query] ([file...])
Flags:
-e, --edit stringArray edit expression
-x, --expand expand results
-h, --help help for tq
-U, --inplace update files, inplace
-i, --input-format string input format (json or yaml)
-O, --output string output file
-o, --output-format string output format (json or yaml, default json)
-r, --raw output raw strings
-s, --slurp slurp all results into an array
-t, --template string golang text/template string
-v, --version print version
Examples:
% echo '{"colors": ["red", "green", "blue"]}' | tq '.colors[0]'
"red"
% echo '{"users":[{"id":1,"name":"one"},{"id":2,"name":"two"}]}' | tq -x -t '{{.id}}: {{.name}}' '.users'
1: one
2: two
% echo '{}' | tq -e '.colors = ["red", "green"]' -e '.colors += "blue"' .
{
"colors": [
"red",
"green",
"blue"
]
}
💖 💪 🙅 🚩
mojatter
Posted on August 9, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.