Несмотря на длину приведенного ниже примера кода, довольно просто проверить, к какому объекту вы обращаетесь при поиске «субъекта» (или любого другого блока JSON). Вам просто нужно терпеливо проверить возможности.
Я настоятельно рекомендую создавать промежуточные переменные / объекты для работы и доступа к структурированным данным в JSON. Длинная сложенная ссылка может сбить с толку и легко потерять представление о том, где вы находитесь в структуре. Например,
Json("@graph")(1)("subject")(j)("@value")
имеет несколько уровней иерархических ссылок для чтения, в то время как если вы сделаете это
Dim graphData As Collection
Set graphData = json("@graph")
Dim graphSubject As Object
Set graphSubject = graphData.Item(1)("subject")
graphSubject(j)("@value")
, я лично думаю, что легче читать и сохранять разные типы объектов в иерархия, чем непрерывные ссылки в стеке.
Я создал три временных файла JSON для ваших ссылок выше и соответствующим образом проанализировал их, как показано в примере ниже.
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
Этот пример код выдает результат
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