循环使用特定符号的 JSON 文件

Posted

技术标签:

【中文标题】循环使用特定符号的 JSON 文件【英文标题】:Loop through JSON files with specific notation 【发布时间】:2020-01-12 22:05:07 【问题描述】:

我有三个 JSON 文件,我正在循环它们以从中获取一些数据。我对名为“主题”的 JSON 文件中的特定部分有疑问: 在第一个文件中,这个符号根本没有任何符号

在第二个文件中有一个这样的主题符号

在第三个文件中这样的主题符号

在我使用的代码中,我使用了循环以获得所有可能的结果

        For j = 1 To 11
            a(r, j + 47) = Json("@graph")(1)("subject")(j)("@value")
        Next j

它适用于第三种情况和第一种情况......但不适用于只有一个符号的情况

这是第一种情况的 URL http://jsoneditoronline.org/?id=8c218c6a21184e9e864f5b4b6090c509

这是第二种情况的 URL http://jsoneditoronline.org/?id=1f68983defef4ad9b4dccf335d15b1b2

这是第三种情况的 URL http://jsoneditoronline.org/?id=e6e12e0aa1be4484b877924ca5fe2e9c

【问题讨论】:

VBA 数组的索引从 0 开始。 谢谢。我如何将它应用到我的案例中? 您必须检测与"subject" 项目关联的数据结构类型。 This answer 是一个指南,表明带有花括号的对象是 Dictionary,方括号是 Collection。您还可以使用TypeName 函数来确定您拥有的对象类型,然后相应地处理数据。 非常感谢。如果可能的话,请给我这三种情况的简单例子。如果在 json 文件中根本找不到符号,并且它就像一个项目的字典,并且它是字典的集合 我已经更新了帖子并为每个案例添加了 URL 【参考方案1】:

尽管下面的代码示例很长,但在查找“主题”(或任何其他 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://***.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

【讨论】:

非常感谢。这是很棒的教程。我看到 HasKey UDF 但你没有使用它.. 它在这个问题上有用吗? 最初,我使用HasKey 来检查Collection 中是否存在某个部分(关键字)。但是此 JSON 层次结构中的 Collection 用作数组,因此您只需使用其索引访问集合中的每个项目。所以你真的不需要它(我应该从我的代码中删除它)。

以上是关于循环使用特定符号的 JSON 文件的主要内容,如果未能解决你的问题,请参考以下文章

如何防止特定符号被编译器/链接器剥离?

如何快速搜索项目中所有包含的头文件以查找特定符号?

如何告诉/强制 GNU ld 将部分/符号放在输出 ELF 文件的特定部分?

替换长json字符串中的新行符号[关闭]

有没有办法使用特定的 C 函数/符号作为 nm 的输出

如何制作一个从 .json 文件加载其元素的嵌入反应菜单?