JSON通过特定的属性名提取所有数据

cgvd09ve  于 2023-11-20  发布在  其他
关注(0)|答案(1)|浏览(111)

我使用来自https://github.com/omegastripes/VBA-JSON-parser的VBA JSON解析器
我有以下json:

{
   "Porp1": {
      "Prop2": {
        "name": "test"
      },
   },
   "name": "test123",
   "other_prop": {
     "name": "specific name"
   }
}

字符串
我需要使用该工具从name字段中提取所有值。
现在我使用下面的代码:

Dim vJson As Object
Dim sState As String
JSON.Parse response, vJson, sState

'From here don't know to extract all `name` properties, no matter of level of nesting


如何做到这一点?

kr98yfug

kr98yfug1#

转换后的JSON是一个包含属性的Dictionary

  • 简单值(如字符串)
  • 字典里。
  • 数组(值数组或字典数组)

因此,遍历JSON最简单的方法是创建一个递归例程。
如果属性是简单值,请检查属性名称。如果属性名称= "name",请写入属性 value(或执行任何您要执行的动作)
如果属性是Dictionary,请递归呼叫常式。
如果属性是Array,则在该数组上循环,并检查成员是否再次为Dictionaries。如果是,则对每个成员进行递归调用。
下面的例程确实做到了这一点。我添加了一个“Prefix”参数,这样你就可以看到值是从哪里来的。

Sub findProperty(prefix As String, jsonDict As Variant, lookForProperty As String)

    Dim propertyName As Variant
    Dim childJsonDict As Dictionary
    
    For Each propertyName In jsonDict.Keys
        If isDictionary(jsonDict(propertyName)) Then
            Set childJsonDict = jsonDict(propertyName)
            findProperty prefix & IIf(prefix = "", "", ".") & propertyName, childJsonDict, lookForProperty
        ElseIf IsArray(jsonDict(propertyName)) Then
            Dim i As Long
            For i = LBound(jsonDict(propertyName)) To UBound(jsonDict(propertyName))
                If isDictionary(jsonDict(propertyName)(i)) Then
                    Set childJsonDict = jsonDict(propertyName)(i)
                    findProperty prefix & IIf(prefix = "", "", ".") & propertyName & "[" & i & "]", childJsonDict, lookForProperty
                End If
            Next i
        ElseIf LCase(propertyName) = LCase(lookForProperty) Then
            Debug.Print prefix & IIf(prefix = "", "", ".") & propertyName, jsonDict(propertyName)
        End If
    Next
End Sub

Function isDictionary(property As Variant) As Boolean
    If VarType(property) <> vbObject Then Exit Function
    isDictionary = TypeName(property) = "Dictionary"
End Function

字符串
您可以使用以下命令从代码中调用此函数

Dim vJson As Object
Dim sState As String
JSON.Parse response, vJson, sState
If TypeName(vJson) = "Dictionary" Then
    Call findProperty("", vJson, "Name")
Else
    MsgBox "Error parsing JSON"
End If


立即窗口中的输出为

Porp1.Prop2.name            test
name          test123
other_prop.name             specific name

更新

a)我的代码在处理数组时出现了一个问题(愚蠢的剪切和粘贴错误),已更正。
B)JSON转换器需要一个Variant作为结果变量(vJson)。如果您将其声明为Object或Dictionary,则当JSON代码无效时(因为您不能将Null之类的标量赋给Object),转换器将引发运行时错误。我相应地更改了代码。
c)如果最上面的元素是一个数组,这个代码将不起作用,它需要一个字典。希望这适合你,我既没有时间也没有有效的测试数据来重写它。

相关问题