Despite the length of the code example below, it's relatively straightforward to check what kind of object you're accessing when looking for the "subject" (or any other JSON block). You just need to patiently check the possibilities.
I highly reccommend creating intermediate variables/objects to deal with and access the structured data in JSON. A long, stacked reference can be confusing to read and easy to lose track of where you are in the structure. For example
Json("@graph")(1)("subject")(j)("@value")
has several levels of hierarchical references to read, whereas if you do this
Dim graphData As Collection
Set graphData = json("@graph")
Dim graphSubject As Object
Set graphSubject = graphData.Item(1)("subject")
graphSubject(j)("@value")
I personally think it's easier to read and keep straight the different types of objects in the hierarchy than the continual stacked references.
I created three temporary JSON files, per your links above and parsed them accordingly, as shown in the example below.
Option Explicit
Sub ParseMyJSON()
Dim jsonFilenames As Variant
jsonFilenames = Array("json-subject1", "json-subject2", "json-subject3")
Dim jsonFilename As Variant
For Each jsonFilename In jsonFilenames
Dim thisFilename As String
thisFilename = "C:\Temp\" & jsonFilename & ".json"
Dim json As Object
Set json = GetJSON(thisFilename)
Dim graphData As Collection
Set graphData = json("@graph")
'--- each of the two items in the graphData collection is
' a Dictionary, so check if the subject exists
Debug.Print "processing " & thisFilename & ")"
If graphData.Item(1).Exists("subject") Then
Dim graphSubject As Object
Set graphSubject = graphData.Item(1)("subject")
If TypeName(graphSubject) = "Dictionary" Then
Debug.Print vbTab & "language: " & graphSubject("@language")
Debug.Print vbTab & " value: " & graphSubject("@value")
Else
'--- this is a Collection, so there are multiple subjects
Dim i As Long
For i = 1 To graphSubject.Count
Debug.Print vbTab & "language(" & i & "): " & graphSubject(i)("@language")
Debug.Print vbTab & " value(" & i & "): " & graphSubject(i)("@value")
Next i
End If
Else
Debug.Print vbTab & "subject does not exist in this graph!"
End If
Debug.Print ""
Next jsonFilename
End Sub
Private Function GetJSON(ByVal filepath As String) As Object
Dim jsonText As String
Dim theFile As Long
theFile = FreeFile
Open filepath For Input As theFile
jsonText = Input(LOF(theFile), theFile)
Close theFile
Set GetJSON = JsonConverter.ParseJson(jsonText)
End Function
Function HasKey(ByRef coll As Collection, ByVal strKey As String) As Boolean
'--- from: https://stackoverflow.com/a/38040635/4717755
Dim var As Variant
On Error Resume Next
var = coll(strKey)
HasKey = (Err.Number = 0)
Err.Clear
End Function
This example code produces the results output
processing C:\Temp\json-subject1.json)
subject does not exist in this graph!
processing C:\Temp\json-subject2.json)
language: por
value: Pintura portuguesa, Séc. 20
processing C:\Temp\json-subject3.json)
language(1): por
value(1): Indústria de lanifÃcios, Portugal, Séc. 19
language(2): por
value(2): Indústria, Portugal, Séc. 19
language(3): por
value(3): Ãndústria de lanificios, Alentejo (Portugal), Séc. 19