使用 VBscript 访问 JSON 数据中的所有值

2023-12-02

我必须做一些 vbscript 来处理来自网络服务器的 json 格式的输出。我正在使用我发现的一个名为“aspJSON”的旧 vbscript 代码片段 - 我认为它来自 www.aspjson.com,但该网站不再可用。

我有这个 JSON 文件:

{
"VAT":12678967.543233,
"buyInfo":{
    "maximumBuyAmount":100,
    "minimumBuyAmount":1,
},
"prices":[{
    "unitPrice":12.50
    "specialOfferPrice":8.75,
    "period":{
        "endDate":"\/Date(928142400000+0200)\/",
        "startDate":"\/Date(928142400000+0200)\/",
    },
}],
}

使用 aspJSON 代码,我可以从数据中获取一些值。这两个可以正常工作:

Msgbox oJSON.data("VAT")

MsgBox oJSON.data("buyInfo").item("maximumBuyAmount")

但我似乎无法访问的值prices:

[{"unitPrice":12.50}] 

and period:

[{"period":{"endDate":"xxx"}}]

我如何访问这些值?

这是 aspJSON 代码:

'Februari 2014 - Version 1.17 by Gerrit van Kuipers
Class aspJSON
Public data
Private p_JSONstring
private aj_in_string, aj_in_escape, aj_i_tmp, aj_char_tmp, aj_s_tmp, aj_line_tmp, aj_line, aj_lines, aj_currentlevel, aj_currentkey, aj_currentvalue, aj_newlabel, aj_XmlHttp, aj_RegExp, aj_colonfound

Private Sub Class_Initialize()
    Set data = Collection()

    Set aj_RegExp = new regexp
    aj_RegExp.Pattern = "\s{0,}(\S{1}[\s,\S]*\S{1})\s{0,}"
    aj_RegExp.Global = False
    aj_RegExp.IgnoreCase = True
    aj_RegExp.Multiline = True
End Sub

Private Sub Class_Terminate()
    Set data = Nothing
    Set aj_RegExp = Nothing
End Sub

Public Sub loadJSON(inputsource)
    inputsource = aj_MultilineTrim(inputsource)
    If Len(inputsource) = 0 Then Err.Raise 1, "loadJSON Error", "No data to load."

    select case Left(inputsource, 1)
        case "{", "["
        case else
            Set aj_XmlHttp = CreateObject("Msxml2.ServerXMLHTTP")
            aj_XmlHttp.open "GET", inputsource, False
            aj_XmlHttp.setRequestHeader "Content-Type", "text/json"
            aj_XmlHttp.setRequestHeader "CharSet", "UTF-8"
            aj_XmlHttp.Send
            inputsource = aj_XmlHttp.responseText
            set aj_XmlHttp = Nothing
    end select

    p_JSONstring = CleanUpJSONstring(inputsource)
    aj_lines = Split(p_JSONstring, Chr(13) & Chr(10))

    Dim level(99)
    aj_currentlevel = 1
    Set level(aj_currentlevel) = data
    For Each aj_line In aj_lines
        aj_currentkey = ""
        aj_currentvalue = ""
        If Instr(aj_line, ":") > 0 Then
            aj_in_string = False
            aj_in_escape = False
            aj_colonfound = False
            For aj_i_tmp = 1 To Len(aj_line)
                If aj_in_escape Then
                    aj_in_escape = False
                Else
                    Select Case Mid(aj_line, aj_i_tmp, 1)
                        Case """"
                            aj_in_string = Not aj_in_string
                        Case ":"
                            If Not aj_in_escape And Not aj_in_string Then
                                aj_currentkey = Left(aj_line, aj_i_tmp - 1)
                                aj_currentvalue = Mid(aj_line, aj_i_tmp + 1)
                                aj_colonfound = True
                                Exit For
                            End If
                        Case "\"
                            aj_in_escape = True
                    End Select
                End If
            Next
            if aj_colonfound then
                aj_currentkey = aj_Strip(aj_JSONDecode(aj_currentkey), """")
                If Not level(aj_currentlevel).exists(aj_currentkey) Then level(aj_currentlevel).Add aj_currentkey, ""
            end if
        End If
        If right(aj_line,1) = "{" Or right(aj_line,1) = "[" Then
            If Len(aj_currentkey) = 0 Then aj_currentkey = level(aj_currentlevel).Count
            Set level(aj_currentlevel).Item(aj_currentkey) = Collection()
            Set level(aj_currentlevel + 1) = level(aj_currentlevel).Item(aj_currentkey)
            aj_currentlevel = aj_currentlevel + 1
            aj_currentkey = ""
        ElseIf right(aj_line,1) = "}" Or right(aj_line,1) = "]" or right(aj_line,2) = "}," Or right(aj_line,2) = "]," Then
            aj_currentlevel = aj_currentlevel - 1
        ElseIf Len(Trim(aj_line)) > 0 Then
            if Len(aj_currentvalue) = 0 Then aj_currentvalue = aj_line
            aj_currentvalue = getJSONValue(aj_currentvalue)

            If Len(aj_currentkey) = 0 Then aj_currentkey = level(aj_currentlevel).Count
            level(aj_currentlevel).Item(aj_currentkey) = aj_currentvalue
        End If
    Next
End Sub

Public Function Collection()
    set Collection = CreateObject("Scripting.Dictionary")
End Function

Public Function AddToCollection(dictobj)
    if TypeName(dictobj) <> "Dictionary" then Err.Raise 1, "AddToCollection Error", "Not a collection."
    aj_newlabel = dictobj.Count
    dictobj.Add aj_newlabel, Collection()
    set AddToCollection = dictobj.item(aj_newlabel)
end function

Private Function CleanUpJSONstring(aj_originalstring)
    aj_originalstring = Replace(aj_originalstring, Chr(13) & Chr(10), "")
    aj_originalstring = Mid(aj_originalstring, 2, Len(aj_originalstring) - 2)
    aj_in_string = False : aj_in_escape = False : aj_s_tmp = ""
    For aj_i_tmp = 1 To Len(aj_originalstring)
        aj_char_tmp = Mid(aj_originalstring, aj_i_tmp, 1)
        If aj_in_escape Then
            aj_in_escape = False
            aj_s_tmp = aj_s_tmp & aj_char_tmp
        Else
            Select Case aj_char_tmp
                Case "\" : aj_s_tmp = aj_s_tmp & aj_char_tmp : aj_in_escape = True
                Case """" : aj_s_tmp = aj_s_tmp & aj_char_tmp : aj_in_string = Not aj_in_string
                Case "{", "["
                    aj_s_tmp = aj_s_tmp & aj_char_tmp & aj_InlineIf(aj_in_string, "", Chr(13) & Chr(10))
                Case "}", "]"
                    aj_s_tmp = aj_s_tmp & aj_InlineIf(aj_in_string, "", Chr(13) & Chr(10)) & aj_char_tmp
                Case "," : aj_s_tmp = aj_s_tmp & aj_char_tmp & aj_InlineIf(aj_in_string, "", Chr(13) & Chr(10))
                Case Else : aj_s_tmp = aj_s_tmp & aj_char_tmp
            End Select
        End If
    Next

    CleanUpJSONstring = ""
    aj_s_tmp = split(aj_s_tmp, Chr(13) & Chr(10))
    For Each aj_line_tmp In aj_s_tmp
        aj_line_tmp = replace(replace(aj_line_tmp, chr(10), ""), chr(13), "")
        CleanUpJSONstring = CleanUpJSONstring & aj_Trim(aj_line_tmp) & Chr(13) & Chr(10)

    Next


    End Function

Private Function getJSONValue(ByVal val)
    val = Trim(val)
    If Left(val,1) = ":"  Then val = Mid(val, 2)
    If Right(val,1) = "," Then val = Left(val, Len(val) - 1)
    val = Trim(val)

    Select Case val
        Case "true"  : getJSONValue = True
        Case "false" : getJSONValue = False
        Case "null" : getJSONValue = Null
        Case Else
            If (Instr(val, """") = 0) Then
                If IsNumeric(val) Then
                    getJSONValue = CDbl(val)
                Else
                    getJSONValue = val
                End If
            Else
                If Left(val,1) = """" Then val = Mid(val, 2)
                If Right(val,1) = """" Then val = Left(val, Len(val) - 1)
                getJSONValue = aj_JSONDecode(Trim(val))
            End If
    End Select
End Function

Private JSONoutput_level
Public Function JSONoutput()
    dim wrap_dicttype, aj_label
    JSONoutput_level = 1
    wrap_dicttype = "[]"
    For Each aj_label In data
         If Not aj_IsInt(aj_label) Then wrap_dicttype = "{}"
    Next
    JSONoutput = Left(wrap_dicttype, 1) & Chr(13) & Chr(10) & GetDict(data) & Right(wrap_dicttype, 1)
End Function

Private Function GetDict(objDict)
    dim aj_item, aj_keyvals, aj_label, aj_dicttype
    For Each aj_item In objDict
        Select Case TypeName(objDict.Item(aj_item))
            Case "Dictionary"
                GetDict = GetDict & Space(JSONoutput_level * 4)

                aj_dicttype = "[]"
                For Each aj_label In objDict.Item(aj_item).Keys
                     If Not aj_IsInt(aj_label) Then aj_dicttype = "{}"
                Next
                If aj_IsInt(aj_item) Then
                    GetDict = GetDict & (Left(aj_dicttype,1) & Chr(13) & Chr(10))
                Else
                    GetDict = GetDict & ("""" & aj_JSONEncode(aj_item) & """" & ": " & Left(aj_dicttype,1) & Chr(13) & Chr(10))
                End If
                JSONoutput_level = JSONoutput_level + 1

                aj_keyvals = objDict.Keys
                GetDict = GetDict & (GetSubDict(objDict.Item(aj_item)) & Space(JSONoutput_level * 4) & Right(aj_dicttype,1) & aj_InlineIf(aj_item = aj_keyvals(objDict.Count - 1),"" , ",") & Chr(13) & Chr(10))
            Case Else
                aj_keyvals =  objDict.Keys
                GetDict = GetDict & (Space(JSONoutput_level * 4) & aj_InlineIf(aj_IsInt(aj_item), "", """" & aj_JSONEncode(aj_item) & """: ") & WriteValue(objDict.Item(aj_item)) & aj_InlineIf(aj_item = aj_keyvals(objDict.Count - 1),"" , ",") & Chr(13) & Chr(10))
        End Select
    Next
End Function

Private Function aj_IsInt(val)
    aj_IsInt = (TypeName(val) = "Integer" Or TypeName(val) = "Long")
End Function

Private Function GetSubDict(objSubDict)
    GetSubDict = GetDict(objSubDict)
    JSONoutput_level= JSONoutput_level -1
End Function

Private Function WriteValue(ByVal val)
    Select Case TypeName(val)
        Case "Double", "Integer", "Long": WriteValue = val
        Case "Null"                     : WriteValue = "null"
        Case "Boolean"                  : WriteValue = aj_InlineIf(val, "true", "false")
        Case Else                       : WriteValue = """" & aj_JSONEncode(val) & """"
    End Select
End Function

Private Function aj_JSONEncode(ByVal val)
    val = Replace(val, "\", "\\")
    val = Replace(val, """", "\""")
    'val = Replace(val, "/", "\/")
    val = Replace(val, Chr(8), "\b")
    val = Replace(val, Chr(12), "\f")
    val = Replace(val, Chr(10), "\n")
    val = Replace(val, Chr(13), "\r")
    val = Replace(val, Chr(9), "\t")
    aj_JSONEncode = Trim(val)
End Function

Private Function aj_JSONDecode(ByVal val)
    val = Replace(val, "\""", """")
    val = Replace(val, "\\", "\")
    val = Replace(val, "\/", "/")
    val = Replace(val, "\b", Chr(8))
    val = Replace(val, "\f", Chr(12))
    val = Replace(val, "\n", Chr(10))
    val = Replace(val, "\r", Chr(13))
    val = Replace(val, "\t", Chr(9))
    aj_JSONDecode = Trim(val)
End Function

Private Function aj_InlineIf(condition, returntrue, returnfalse)
    If condition Then aj_InlineIf = returntrue Else aj_InlineIf = returnfalse
End Function

Private Function aj_Strip(ByVal val, stripper)
    If Left(val, 1) = stripper Then val = Mid(val, 2)
    If Right(val, 1) = stripper Then val = Left(val, Len(val) - 1)
    aj_Strip = val
End Function

Private Function aj_MultilineTrim(TextData)
    aj_MultilineTrim = aj_RegExp.Replace(TextData, "$1")
End Function

private function aj_Trim(val)
    aj_Trim = Trim(val)
    Do While Left(aj_Trim, 1) = Chr(9) : aj_Trim = Mid(aj_Trim, 2) : Loop
    Do While Right(aj_Trim, 1) = Chr(9) : aj_Trim = Left(aj_Trim, Len(aj_Trim) - 1) : Loop
    aj_Trim = Trim(aj_Trim)
end function
End Class

Unlike VAT and buyInfo, prices是一个可以包含多个实例的集合(注意 JSON 结构的差异,prices用方括号括起来)。每当您处理集合时,都需要一个循环来迭代实例以获取其底层属性。

I'd recommend a For Each loop, like below. #

Dim key, price

'Iterating a Scripting.Dictionary using For Each returns the key.
For Each key In oJSON.data("prices")
  'Get the price instance by passing the key back into 
  'the Scripting.Dictionary.
  Set price = oJSON.data("prices")(key)
  MsgBox price.item("unitPrice")
  MsgBox price.item("specialOfferPrice")
  MsgBox price.item("period").item("endDate")
  MsgBox price.item("period").item("startDate")
  'Clear object before iterating the next instance.
  Set price = Nothing
Next

# Code provided untested


通过一些有用的讨论进一步研究这一点@omegastripes在评论中并浏览aspJSON类,您应该能够按序数访问集合/数组项,例如获取unitPrice你会使用;

oJSON("prices")(0).Item("unitPrice")

考虑到这一点,我们做了一个快速测试脚本,结果如​​下。

Option Explicit

Dim prices: Set prices = CreateObject("Scripting.Dictionary")
Dim price, period

With prices
    Set price = CreateObject("Scripting.Dictionary")
    With price
        Call .Add("unitPrice", 12.50)
        Call .Add("specialOfferPrice", 8.75)
        Set period = CreateObject("Scripting.Dictionary")
        With period
            Call .Add("endDate", "/Date(928142400000+0200)/")
        End With
        Call .Add("period", period)
    End With
    'Uses same method as the AddToCollection() in aspJSON to
    'assign the ordinal position when adding the child Dictionary.
    Call .Add(.Count, price)
End With

WScript.Echo prices(0).Item("unitPrice")
WScript.Echo prices(0).Item("period").Item("endDate")

Output:

12.5
/Date(928142400000+0200)/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 VBscript 访问 JSON 数据中的所有值 的相关文章

随机推荐

  • dplyr r:选择名称位于外部向量中的列[重复]

    这个问题在这里已经有答案了 Purpose 我可以使用选择列dplyr条件是列名位于外部向量中 我发现一些帖子解释了如何使用名称向量对数据框进行子集化 但当向量中的某些名称在数据框中不存在时 我找不到帖子 示例数据集 library tid
  • 如何停止张量流中张量某些条目的梯度

    我正在尝试实现一个嵌入层 将使用预先训练的手套嵌入来初始化嵌入 对于可以在手套中找到的单词 它将被修复 对于那些没有出现在手套中的单词 它会被随机初始化 并且是可训练的 我如何在张量流中做到这一点 我知道整个张量有一个 tf stop gr
  • 带有表达式不需要的结果的 C 宏

    我正在运行以下程序并得到结果为 9 7 我理解为什么输出是 9 但我不明白为什么我得到 7 作为输出 include
  • 从登录参数创建用户对象

    我试图在用户登录后创建一个包含所有用户字段的用户对象 以便我可以从用户的类中检索任何给定的属性 这是用户类 public class User private String username private String password
  • 运行时错误“9”下标超出条件格式代码范围

    我对 VBA 以及一般的任何类型的编程 非常陌生 所以我不确定如何继续 我猜我的错误与条件格式的重叠范围有关 因为当代码以不同的方式设置时 我也会遇到错误 一旦范围不再重叠 这些错误就会得到解决 这里的情况可能并非如此 但我认为了解一下会有
  • 自签名证书可以保护多个 CN / FQDN 吗?

    这是一个有点愚蠢的设置 但这就是我现在正在查看的内容 我正在学习 Kubernetes 我想将自定义代码推送到我的 Kubernetes 集群 这意味着该代码必须作为 Docker 映像提供 可从someDocker 存储库 默认为 Doc
  • 重复调用 Ng-Options 表达式

    我的设备有多个问题
  • 配置 Eclipse 以与 MSYS2 一起使用

    我使用 Eclipse Mars 和 MSYS2 Eclipse 无法识别我的 MSYS2 安装 它包含用于 32 位编译的 Mingw w64 我在互联网上找到的东西不起作用 我应该怎么办 好吧 聚会有点晚了 但看起来还有没什么特别的关于
  • ASP.NET-发送电子邮件

    我正在做一个航班预订系统 我想向用户发送一封电子邮件 其中包含他的旅行的电子机票 电子机票是使用从数据库中获取的预订 ID 以及前面页面中的其他详细信息 例如乘客姓名等 动态生成的 那么我怎样才能将动态生成的电子客票发送到他的电子邮件 ID
  • 与视频同步播放多个音轨之一

    我正在尝试在网络浏览器中播放视频 原始视频带有两个或多个音频流 每个音频流都采用不同的语言 我想让用户可以选择切换他们正在收听的音轨 我尝试使用audioTracks在视频元素上 但尽管说它在大多数浏览器中都支持在标志后面 至少在 Fire
  • req.body 是未定义的意思是应用程序

    我的应用程序有问题 告诉您问题所在的简单方法让我向您展示我的代码 var Meetup require models meetup module exports create function req res var meetup new
  • Mongodb和排序子数组

    不确定这是否可以做到 所以我想问一下 我有以下 mongodb s store abc offers spend 100 00 cashback 10 00 percentage 0 10 spend 50 00 cashback 5 00
  • 在运行时将环境变量传递到 Vue 应用程序

    如何访问 Vue 中的环境变量 这些变量在运行时而不是在构建期间传递给容器 堆栈如下 Vue CLI 3 0 5 Docker 库伯内斯 stackoverflow 和其他地方建议使用 env 文件传递 变量 和使用模式 的解决方案 但这是
  • 自定义域名映射到用户配置文件。

    目前 用户配置文件的格式为 website com username 这很好 然而 一些重度用户希望使用自定义域名 这与 Tumblr 类似 用户被授予 username tumblr com 的子域 但允许他们使用映射到该子域的外部域 我
  • MS Access SQL:聚合最小值但检索其他字段

    这可能是一个非常简单的问题 但我不知道如何在 MS Access 中解决它 以前可能已经回答过 但我没能找到 我有一个包含 3 列的表 col1 是对象 ID col2 和 col3 是测量值 我构建了一个查询 以便对于每个对象 我们都能在
  • 为什么我无法在 lambda 中捕获此按引用 ('&this')?

    我明白了正确的捕捉方式this 修改对象属性 在 lambda 中如下 auto f this 但我对我所看到的以下特点感到好奇 class C public void foo auto f this not captured auto f
  • Postgresql sqlalchemy 默认时间 now() 一遍又一遍地给出相同的时间

    我的表内有一个字段 即时间 time db Column db Time default datetime datetime now time nullable False 由于某种原因 它一直默认为同一时间而不是实际的系统时间 23 53
  • ExtJS 4 中的股票图表

    如何绘制数百点的股票图表或折线图 我在常规折线图中禁用了动画 但没有成功 而且仍然太重且太慢 我最近写了一篇关于在 Ext JS 4 中创建股票图表的博客文章 http www scottlogic co uk 2011 12 ext js
  • JPA 中的附加查询

    我有两节课InvitedPerson and Flight彼此之间具有一对一的关系 以下是它们的注释方式 public class InvitedTech OneToOne mappedBy invitedTech cascade Casc
  • 使用 VBscript 访问 JSON 数据中的所有值

    我必须做一些 vbscript 来处理来自网络服务器的 json 格式的输出 我正在使用我发现的一个名为 aspJSON 的旧 vbscript 代码片段 我认为它来自 www aspjson com 但该网站不再可用 我有这个 JSON