Traverse is a go
language utility for 'traversing' a block of JSON encoded text
and returning a selected piece of content.
Starting with a go
RawMessage,
traverse subdivides RawMessage
s until we have the one we want.
We specify the traversal using the Builder Pattern. The ZeroLog logger also makes excellent use of this pattern.
A traversal is composed of a chain chain of components. It must start with Start
and
end with End
. Otherwise you can snap the components together in whatever order fits the JSON
text.
Start
- initiize the traversl stateEnd
- extract the traversal state, or report errorObjectKey
- pull an item out of a JSON Object, and make that the new stateArraySingleton
- select the only item in a 1 item JSON Array and make that the new stateArraySlice
- select a JSON array as a slice and make that the new stateArrayPredicate
- select an item from a JSON Array based on a predicate function and make that the new stateSelector
- use a selector function to select whatever you want from the current state and make that the new state
An error that occurs anywhere in the traversal chain will be reported as the return value from End
Traversal components use helper functions to manipulate json.RawMessage
objects. These are available to you so you can write
your own components.
GetStringFromRawMessage
GetBoolFromRawMessage
GetInt32FromRawMessage
GetSliceFromRawMessage
GetMapFromRawMessage
GetMsgFromRawMessage
example copied from w3schools.com
{
"name":"John",
"age":30,
"cars": [
{ "name":"Ford", "models":[ "Fiesta", "Focus", "Mustang" ] },
{ "name":"BMW", "models":[ "320", "X3", "X5" ] },
{ "name":"Fiat", "models":[ "500", "Panda" ] }
]
}
We want to extract an Array of the BMW models which John owns.
predicate := func(r json.RawMessage) bool {
m, err := traversal.GetMapFromRawMessage(r)
if err != nil {
return false
}
n, err := traversal.GetStringFromRawMessage(m["name"])
if err != nil {
return false
}
return n == "BMW"
}
traversal.Start([]byte(data)).
ObjectKey("cars").
ArrayPredicate(predicate).
ObjectKey("models").
End(os.stdout)
This example prints to stdout:
[ "320", "X3", "X5" ]