jpt: see JSON differently

JSON is wonderfully efficient at encoding logical structure and hierarchy into a textual form, but sometimes our eyes and brains need some help making sense of that. Let’s see how jpt can help!

The Shape of JSON

JSON uses a small and simple palette of brackets and curly braces, to express nest-able structures like objects and arrays. However once inside those structures it’s hard to visualize the lineage of the members.

Using jpt however, one can get a better idea of what the shape of a JSON document is.

For example object-person.json:

{
  "person": {
    "name": "Lindsay Bassett",
    "nicknames": [
      "Lindy",
      "Linds"
    ],
    "heightInInches": 66,
    "head": {
      "hair": {
        "color": "light blond",
        "length": "short",
        "style": "A-line"
      },
      "eyes": "green"
    },
    "friendly":true
  }
}

Using jpt -L we can output what I am currently calling “JSONPath Object Literals”. With JPOL the entire path is spelled out for each item as well as it’s value expressed as a JSON object. You can also roundtrip JPOL right back into jpt and you’ll get the JSON again.

% jpt -L object-person.json
$={}
$["person"]={}
$["person"]["name"]="Lindsay Bassett"
$["person"]["nicknames"]=[]
$["person"]["nicknames"][0]="Lindy"
$["person"]["nicknames"][1]="Linds"
$["person"]["heightInInches"]=66
$["person"]["head"]={}
$["person"]["head"]["hair"]={}
$["person"]["head"]["hair"]["color"]="light blond"
$["person"]["head"]["hair"]["length"]="short"
$["person"]["head"]["hair"]["style"]="A-line"
$["person"]["head"]["eyes"]="green"
$["person"]["friendly"]=true

#roundtrip back into jpt (-i0 means zero indents/single line)
jpt -L object-person.json | jpt -i0
{"person":{"name":"Lindsay Bassett","nicknames":["Lindy","Linds"],"heightInInches":66,"head":{"hair":{"color":"light blond","length":"short","style":"A-line"},"eyes":"green"},"friendly":true}}

If you were to fire up jsc or some other JavaScript interpreter, declare $ as a variable using var $ and then copy and paste the output above and you will have this exact object.

Perhaps though you prefer single quotes? Add -q to use single quotes for the property names but values remain double quoted.

#-q will single quote JSONPath only, strings remain double quoted 

% jpt -qL object-person.json         
$={}
$['person']={}
$['person']['name']="Lindsay Bassett"
$['person']['nicknames']=[]
$['person']['nicknames'][0]="Lindy"
$['person']['nicknames'][1]="Linds"
$['person']['heightInInches']=66
$['person']['head']={}
$['person']['head']['hair']={}
$['person']['head']['hair']['color']="light blond"
$['person']['head']['hair']['length']="short"
$['person']['head']['hair']['style']="A-line"
$['person']['head']['eyes']="green"
$['person']['friendly']=true

#-Q will single quote both
% jpt -QL object-person.json
$={}
$['person']={}
$['person']['name']='Lindsay Bassett'
$['person']['nicknames']=[]
$['person']['nicknames'][0]='Lindy'
$['person']['nicknames'][1]='Linds'
$['person']['height in inches']=66
$['person']['head']={}
$['person']['head']['hair']={}
$['person']['head']['hair']['color']='light blond'
$['person']['head']['hair']['length']='short'
$['person']['head']['hair']['style']='A-line'
$['person']['head']['eyes']='green'
$['person']['friendly']=true

If you don’t like bracket notation use -d for dot notation (when the name permits). -Q will single quote both values and key names if using brackets. To save a few lines you can use -P to only print primitives (string, number, booleans, null) and will omit those empty object and array declarations. This too can roundtrip back into jpt, it will infer the structure type (object or array) based on the key type (string or number when in brackets).

% jpt -dQLP object-person.json       
$.person.name='Lindsay Bassett'
$.person.nicknames[0]='Lindy'
$.person.nicknames[1]='Linds'
$.person.heightInInches=66
$.person.head.hair.color='light blond'
$.person.head.hair.length='short'
$.person.head.hair.style='A-line'
$.person.head.eyes='green'
$.person.friendly=true

#roundtrip into jpt, structure types can be inferred
% jpt -dQLP object-person.json | jpt -i0    
{"person":{"name":"Lindsay Bassett","nicknames":["Lindy","Linds"],"heightInInches":66,"head":{"hair":{"color":"light blond","length":"short","style":"A-line"},"eyes":"green"},"friendly":true}}

Now perhaps we don’t care so much about the data but about the structure? Then we can use the -J (JSONPath) or -R (JSON Pointer) output combined with -K or -k for the key names only

#-K key names are double quoted
% jpt -JK /Users/brunerd/Documents/TestFiles/object-person.json
$
  "person"
    "name"
    "nicknames"
      0
      1
    "height in inches"
    "head"
      "hair"
        "color"
        "length"
        "style"
      "eyes"
    "friendly"

#-q/-Q can change the quoting to singles of course
#-C will show the constructor type of every element
% jpt -JKqC /Users/brunerd/Documents/TestFiles/object-person.json
$: Object
  'person': Object
    'name': String
    'nicknames': Array
      0: String
      1: String
    'height in inches': Number
    'head': Object
      'hair': Object
        'color': String
        'length': String
        'style': String
      'eyes': String
    'friendly': Boolean


#-k for unquotes key names, -C for constructor, -i1 for 1 space indents 

% jpt -JkC -i1 /Users/brunerd/Documents/TestFiles/object-person.json
$: Object
 person: Object
  name: String
  nicknames: Array
   0: String
   1: String
  height in inches: Number
  head: Object
   hair: Object
    color: String
    length: String
    style: String
   eyes: String
  friendly: Boolean

It’s been a lot of fun creating jpt and discovery new ways to express JSON using an emerging notation like JSONPath (which is going through the RFC process now). If you’d like to see JSON a different way download jpt and give it a try!