|
楼主 |
发表于 2016-9-28 11:03
|
显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用 · 内置多项VBA编程加强工具 ★ 免费下载 ★ ★ 使用手册★
本帖最后由 liu-aguang 于 2016-11-11 10:54 编辑
4. 数组和对象自身嵌套或相互嵌套的Json/Jsonp实例
通过上面的讨论,我们明白了json的概念和一般解析方法与技巧。现在我们如果要用json文件来存放2个或多个成员的姓名/性别/年龄信息该怎样做呢?这时可以将通过数组或对象的嵌套来实现:
(1)如果用数组则表示为:
[[‘张三’,’男’,23],[’李四’,’女’,20],[’王五’,’男’,22]]
它的形式是:[[],[],[]],解析方法:
Sub a1()
Set oDom = CreateObject("htmlfile")
Set oWindow = oDom.parentWindow
strHtml = "[['张三','男',23],['李四','女',20],['王五','男',22]]"
oWindow.execScript "a=" & strHtml
MsgBox oWindow.eval("a[0][0]") '第一个成员的姓名
End Sub
讨论:
<1>用execScript获得数组a, “a[0]”是第一个成员,它还是一个数组,所以”a[0][0]”是第一个成员的第一项元素值。读者可以自己去研究遍历方法。
<2>在实际应用中,我们看到的是由很多数值元素构成的数组,那么每一个位置上的数据代表的是什么呢?这是json编制者自定义的,我们要结合网页显示去判断。
<3>这种情况下,也可不用数组嵌套来表示, 而表示为:
["张三,男,23","李四,女,20","王五,男,22"]
它用双(或单)引号来限定一个数组元素. 此时,a[0]表示第一个元素, 其值为"张三,男,23", 这是一个字符串.
(2)如果用对象来表示则为:
[{‘name’:’张三’,’sex’:’男’,’age’:23}, {‘name’:’李四’,’sex’:’女’,’age’:20}, {‘name’:’王五’,’sex’:’男’,’age’:22}]
这是数组与对象的嵌套,解法:
Sub ao()
Set oDom = CreateObject("htmlfile")
Set oWindow = oDom.parentWindow
strHtml = "[{'name':'张三','sex':'男','age':23}, {'name':'李四','sex':'女','age':20}, {'name':'王五','sex':'男','age':22}]"
oWindow.execScript "a=" & strHtml
MsgBox oWindow.eval("a[0].name") '第一个成员的姓名
MsgBox oWindow.eval("a[2].age") '第三个成员的年龄
End Sub
讨论:每个数组元素是对象,所以先得到数组元素,再根据对象方法读取值。
(3)假如上面只是某公司的一个小组成员,现在希望用json文件同时存放公司名称和每一工作组成员以及公司总人数, 又该如何呢?
可以这样处理:
{‘dw’:’宇宙公司’,’zb1’: [{'name':'张三','sex':'男','age':23}, {'name':'李四','sex':'女','age':20}, {'name':'王五','sex':'男','age':22}],‘zb2’:[{'name':'刘六','sex':'男','age':24}, {'name':'风车车','sex':'女','age':18}, {'name':'汪麻','sex':'男','age':21}],’total’:6}
这个json存放了公司名称,总人数,公司的两个工作组及组内成员信息。可以通过execScript解析后,访问任意内容:
解析方法如下:
Sub ao()
Set oDom = CreateObject("htmlfile")
Set oWindow = oDom.parentWindow
strHtml = "{'dw':'宇宙公司','zb1': [{'name':'张三','sex':'男','age':23}, {'name':'李四','sex':'女','age':20}, {'name':'王五','sex':'男','age':22}],'zb2':[{'name':'刘六','sex':'男','age':24}, {'name':'风车车','sex':'女','age':18}, {'name':'汪麻','sex':'男','age':21}],'total':6}"
oWindow.execScript "a=" & strHtml
Debug.Print oWindow.a.dw '公司名称
Debug.Print oWindow.eval("a.total") '公司总人数. 想想为什么不用上一句方式读取total值呢?
Debug.Print oWindow.eval("a.zb1[0].name") '第一工作组的第一位成员姓名
Debug.Print oWindow.eval("a.zb2[2].age") '第二工作组的第三位成员年龄
End Sub
讨论:
(1)当execScript解析strHtml后,zb1和zb2是对象a的名称(健名)。但是zb1和zb2的值是数组,所以我们可以用zb1[0]这样的方式表示数组的第一个元素;不过这些数组元素又是对象,所以zb1[0].name就是点号法读取;zb1[0]对象属于对象a下面的一个子对象,于是读取第一工作组的第一位成员姓名的表达式就为:a.zb1[0].name
(2)根据实际提取哪些数据的要求,可以遍历。方法就是用变量来替换方括号内的数值,读者可以自己去尝试。
(3)Json语法小结:
JSON 语法是 JavaScript 对象表示法语法的子集。
• 数据在名称/值对中
• 数据由逗号分隔
• 花括号保存对象
• 方括号保存数组
最后用几个在论坛上的回复实例来结束Json解析部分。
例1
http://club.excelhome.net/forum.php?mod=viewthread&tid=1297966
例2
http://club.excelhome.net/forum.php?mod=viewthread&tid=1299461
例3
http://club.excelhome.net/thread-1301123-3-1.html
例4
http://club.excelhome.net/thread-1298157-2-1.html
Sub js()
Dim arr(1 To 100, 1 To 5)
sURL = "http://comment.10jqka.com.cn/tzrl/getTzrlData.php?callback=callback_dt&type=data&date=201608"
Set oDom = CreateObject("HTMLFILE")
Set oWindow = oDom.parentWindow
Set oHtml = CreateObject("MSXML2.XMLHTTP")
oHtml.Open "GET", sURL, False
oHtml.send
oWindow.execScript oHtml.responseText & ";function callback_dt(o){oj=o};n=oj.data.length"
For i = 0 To oWindow.n - 1
r = r + 1
arr(r, 1) = oWindow.eval("var oi=oj.data[" & i & "]; oi.date+oi.week;")
imt = oWindow.eval("s=0;for(x in oi){s+=1;if(s==3){imt=oi[x]}};imt")
arr(r, 2) = String(imt, "★")
For j = 0 To oWindow.eval("oi.events.length") - 1
arr(r, 3) = oWindow.eval("oi.events[" & j & "][0]")
For Each u In Array("field", "concept")
arr(r, 4) = arr(r, 4) & "," & oWindow.eval("ar=[];k=oi." & u & "[" & j & "];for(x in k){ar.push(k[x].name);ar}")
Next
arr(r, 4) = Trim(Replace(arr(r, 4), ",", " "))
arr(r, 5) = oWindow.eval("ar=[]'';k=oi.stocks[" & j & "];for(x in k){ar.push(k[x].name);ar}")
arr(r, 5) = Replace(arr(r, 5), ",", " ")
r = r + 1
Next
r = r - 1
Next
Range("a2").Resize(r, 5) = arr
End Sub
说明:代码中有一句:imt = oWindow.eval("s=0;for(x in oi){s+=1;if(s==3){imt=oi[x]}};imt")
目的是为了访问名称:import的值。采取这种特别的方式读取,是因为json编制者”误用”了javaScript关键字import作为名称。用点号法访问这个值会发生错误。
修正: 可以用另一种语法直接读取import的值. 即:
imt=oWindow.eval("oi['import']")
|
评分
-
3
查看全部评分
-
|