JSON data is also a valid
Prolog term, and the declarative programming language Prolog is ideally suited for handling tree-shaped data.
Using for example Scryer Prolog, we can conveniently relate the data to a flat list of items with Prolog's built-in grammar mechanism, definite clause grammars (DCGs):
flat_json(JSON) -->
{ JSON = {A,B,C,D,E,F,_:Cs} },
[{A,B,C,D,E,F}],
flat_items(Cs).
flat_items([]) --> [].
flat_items([I|Is]) -->
{ I = {(A,B,C,D,E,_:Cs)} },
[{A,B,C,D,E}],
flat_items(Cs),
flat_items(Is).
Sample query, using the example JSON data from the article:
?- JSON = {
"id": 27941108,
"created_at": "2021-07-24T14:15:05.000Z",
"type": "story",
"author": "edward",
"title": "Fun with Unix domain sockets",
"url": "https://simonwillison.net/2021/Jul/13/unix-domain-sockets/",
"children": [
{
"id": 27942287,
"created_at": "2021-07-24T16:31:18.000Z",
"type": "comment",
"author": "DesiLurker",
"text": "one lesser known...",
"children": []
},
{
"id": 27944615,
"created_at": "2021-07-24T21:26:33.000Z",
"type": "comment",
"author": "galaxyLogic",
"text": "
I read this from Wikipedia...",
"children": [
{
"id": 27944746,
"created_at": "2021-07-24T21:49:07.000Z",
"type": "comment",
"author": "hughrr",
"text": "
Yes although I ...",
"children": []
}
]
}
]
},
phrase(flat_json(JSON), Cs),
maplist(portray_clause, Cs).
yielding the flat list of entries, as desired:
[{("id":27941108,"created_at":"2021-07-24T14:15:05.000Z","type":"story","author":"edward",...)},
{("id":27942287,"created_at":"2021-07-24T16:31:18.000Z","type":"comment",...)},
{("id":27944615,"created_at":"2021-07-24T21:26:33.000Z","type":"comment",...)},
{("id":27944746,"created_at":"2021-07-24T21:49:07.000Z","type":"comment",...)}]