• 【vb.net】轻量JSON序列及反序列化


    这个代码写的有点时间了,可能有点小bug,欢迎评论区反馈

    作用是将Json文本转化成一个HarryNode类进行相关的Json对象处理或者读取,也可以将一个HarryNode对象用ToString变为Json文本。

    举例:

    1、读取节点数据

    1. dim harryNode = New HarryNode("", "{""msg"":""hello world!""}")
    2. msgbox(harryNode.GetAtt("msg")) '弹窗显示hello world!
    3. '下面展示更复杂的嵌套读取
    4. dim harryNode = New HarryNode("", "{""node1"": {""msg"":""hello world!""}}")
    5. msgbox(harryNode.GetAtt("node1.msg")) '弹窗显示hello world! 没错,用“.”作为路径连接符进行寻址
    6. '如果json的键里包含“.”可以将源码里的“.”替换成其它字符,也可以这样进行取值
    7. msgbox(harryNode.GetAtt("node1")("msg").value
    8. '这里的harryNode.GetAtt("node1")返回的是一个字典对象(String, HarryNode)

    2、创建新Json节点,写入数据并输出文本

    1. Dim harryNode = New HarryNode("", "{}")
    2. harryNode.SetAtt("msg", """hello world!""")
    3. MsgBox(harryNode.ToString)
    4. '可以看到SetAtt方法的第二个参数输入的字符串需要是json字符串格式,因此字符串本身需要加双引号
    5. '下面可以用SetAtt的另一种重载方法,与上面代码的结果相同
    6. harryNode.SetAtt("msg", "hello world!", NodeTypeEnum.isString)
    7. MsgBox(harryNode.ToString)
    8. '同样,对嵌套的复杂json对象,可以如下
    9. harryNode.SetAtt("node1.msg", "hello world!", NodeTypeEnum.isString)
    10. '下面这样写也是可以的
    11. harryNode.SetAtt("node1", "{""msg"": ""hello world!""}")

    文档

    1、方法和函数

    New

    构造函数

    nameString节点的名字(对于根节点此项没啥意义)
    jsonString要解析构造的JSON串
    parentHarryNode实例的父节点
    nameString节点的名字(对于根节点此项没啥意义)
    nodeValueObject节点VB.NET对象值
    typeNodeTypeEnum节点值的类型
    parentHarryNode实例的父节点

    GetAtt

    获得指定路径的VB.NET对象

    pathString节点路径
    defaultValueObject没有获取到返回的值,默认Nothing

    SetAtt

    根据指定路径设置节点值

    pathString节点路径
    newValueObject节点的值(VB.NET对象)
    newValueTypeNodeTypeEnum值的类型

    pathString节点路径
    jsonString节点的值(JSON字符串)

    ReName

    重命名某个节点

    pathString节点路径
    newNameString新名字

    ToJson

    返回JSON字符串,与ToString()等价

    GetNode

    获得指定路径的HarryNode对象

    pathString节点路径

    AddNode

    添加子节点

    pathString节点路径
    nodeNameString子节点名
    nodeJsonString子节点JSON串

    Del

    删除指定路径的节点

    pathString节点路径

    Merge

    合并两个字典节点;

    nodeHarryNode要合并的节点

    GetChildPath

    返回一个当前节点子节点名的列表

    Add

    指定某个节点的数据加一个值

    pathString节点路径
    addValueSingle加数

    ConAdd

    指定某个节点的数据加一个值,但是限制了数的范围

    pathString节点路径
    addValueSingle加数
    maxValueSingle最大值
    minValueSingle最小值,默认0

    Mul

    指定某个节点的数据乘一个值

    pathString节点路径
    addValueSingle乘数

    Power

    指定某个节点的数据求次幂

    pathString节点路径
    addValueSingle

    2、属性

    Value

    当前节点的VB.NET类型值

    3、事件

    NodeContentChangeBefore

    节点内容改变之前

    pathString节点路径
    newValueObject即将变成的值
    newValueTypeNodeTypeEnum即将变成值的类型

    NodeContentChangeBeforeFromJson

    节点内容改变之前(通过JSON解释)

    pathString节点路径
    jsonString即将变成的值的JSON字符串

    NodeContentChangeLater

    节点内容改变之后

    pathString节点路径
    newValueObject变成的值
    newValueTypeNodeTypeEnum变成值的类型

    NodeContentChangeLaterFromJson

    节点内容改变之后(通过JSON解释)

    pathString节点路径
    jsonString变成的值的JSON字符串

    源码如下:

    1. Imports System.Text.RegularExpressions
    2. Public Class HarryNode
    3. Public Shared pathSeparator As String = "."
    4. Public Shared outputFormat As Boolean = True
    5. Public Shared formatRetraction As Integer = 2
    6. Public Shared Function MulReplace(source As String, ParamArray args() As String) As String
    7. If args.Length Mod 2 <> 0 Then
    8. Return source
    9. End If
    10. For i As Integer = 0 To UBound(args) Step 2
    11. source = Replace(source, args(i), args(i + 1))
    12. Next
    13. Return source
    14. End Function
    15. Public Shared Function ToEscape(source As String) As String
    16. Return MulReplace(source, "\", "\\", vbCrLf, "\n", vbTab, "\t", """", "\""", Chr(8), "\b", Chr(12), "\f")
    17. End Function
    18. Public Enum NodeTypeEnum
    19. isNull = 0
    20. isString = 1
    21. isSingle = 2
    22. isDict = 3
    23. isList = 4
    24. isBool = 5
    25. End Enum
    26. Public nodeType As NodeTypeEnum
    27. Public nodeName As String
    28. Public parentNode As HarryNode
    29. Private stringValue As String
    30. Private singleValue As Single
    31. Private boolValue As Boolean
    32. Private childNode As Dictionary(Of String, HarryNode)
    33. Public Event NodeContentChangeBefore(ByRef path As String, ByRef newValue As Object, ByRef newValueType As String)
    34. Public Event NodeContentChangeBeforeFromJson(ByRef path As String, ByRef json As String)
    35. Public Event NodeContentChangeLater(path As String, ByRef nowValue As Object, ByRef newValueType As NodeTypeEnum)
    36. Public Event NodeContentChangeLaterFromJson(path As String, nowJson As String)
    37. Public Sub Merge(node As HarryNode)
    38. If nodeType = node.nodeType And nodeType = NodeTypeEnum.isDict Then
    39. For i = 0 To node.childNode.Count - 1
    40. Dim key = node.childNode.Keys(i)
    41. If childNode.ContainsKey(key) Then
    42. childNode(key).Merge(node.childNode(key))
    43. Else
    44. childNode.Add(key, node.childNode(key))
    45. End If
    46. Next
    47. End If
    48. End Sub
    49. Public Function GetChildPath() As List(Of String)
    50. Dim result As New List(Of String)
    51. If nodeType = NodeTypeEnum.isDict Or nodeType = NodeTypeEnum.isList Then
    52. result.AddRange(childNode.Keys)
    53. Else
    54. result.Add(nodeName)
    55. End If
    56. Return result
    57. End Function
    58. 'Public Function GetTreeNode(interpreter As 解释器) As TreeNode
    59. ' Dim rootNode As New TreeNode(nodeName & interpreter.Search(nodeName))
    60. ' If nodeType = NodeTypeEnum.isDict Or nodeType = NodeTypeEnum.isList Then
    61. ' For Each cNode In childNode
    62. ' rootNode.Nodes.Add(cNode.Value.GetTreeNode(interpreter))
    63. ' Next
    64. ' Else
    65. ' rootNode.Nodes.Add(Value & interpreter.Search(Value))
    66. ' End If
    67. ' Return rootNode
    68. 'End Function
    69. Public Sub Power(path As String, addValue As Single)
    70. SetAtt(path, GetAtt(path, 0) ^ addValue, 0)
    71. End Sub
    72. Public Sub Add(path As String, addValue As Single)
    73. SetAtt(path, GetAtt(path, 0) + addValue, 0)
    74. End Sub
    75. Public Sub ConAdd(path As String, addValue As Single, maxValue As Single, Optional minValue As Single = 0)
    76. Dim newValue As Single = GetAtt(path, 0) + addValue
    77. If newValue > maxValue Then
    78. newValue = maxValue
    79. End If
    80. If newValue < minValue Then
    81. newValue = minValue
    82. End If
    83. SetAtt(path, newValue, 0)
    84. End Sub
    85. Public Sub Mul(path As String, addValue As Single)
    86. SetAtt(path, GetAtt(path, 0) * addValue, 0)
    87. End Sub
    88. Public Sub AddNode(path As String, nodeName As String, nodeJson As String)
    89. Dim paths() As String = path.Split(pathSeparator)
    90. Dim p As String
    91. Dim node As HarryNode = Me
    92. For i As Integer = 0 To UBound(paths) - 1
    93. p = paths(i)
    94. Select Case node.nodeType
    95. Case NodeTypeEnum.isDict, NodeTypeEnum.isList
    96. If node.nodeType = NodeTypeEnum.isList Then
    97. p = Int(Val(p))
    98. End If
    99. If Not node.childNode.ContainsKey(p) Then
    100. node.childNode.Add(p, New HarryNode(p, "{}", Me))
    101. End If
    102. Case Else
    103. node.nodeType = NodeTypeEnum.isDict
    104. node.childNode = New Dictionary(Of String, HarryNode)
    105. If Not node.childNode.ContainsKey(p) Then
    106. node.childNode.Add(p, New HarryNode(p, "{}", Me))
    107. End If
    108. End Select
    109. node = node.childNode(p)
    110. Next
    111. p = paths.Last
    112. Select Case node.nodeType
    113. Case NodeTypeEnum.isDict, NodeTypeEnum.isList
    114. If node.nodeType = NodeTypeEnum.isList Then
    115. p = Int(Val(p))
    116. End If
    117. If Not node.childNode.ContainsKey(p) Then
    118. node.childNode.Add(p, New HarryNode(p, "{}", Me))
    119. End If
    120. Case Else
    121. node.nodeType = NodeTypeEnum.isDict
    122. node.childNode = New Dictionary(Of String, HarryNode)
    123. If Not node.childNode.ContainsKey(p) Then
    124. node.childNode.Add(p, New HarryNode(p, "{}", Me))
    125. End If
    126. End Select
    127. If Not node.childNode.ContainsKey(p) Then
    128. node.childNode.Add(p, New HarryNode(nodeName, nodeJson, Me))
    129. Else
    130. node.childNode(p) = New HarryNode(nodeName, nodeJson, Me)
    131. End If
    132. End Sub
    133. Public Sub Del(path As String)
    134. Dim paths() As String = path.Split(pathSeparator)
    135. Dim p As String
    136. Dim node As HarryNode = Me
    137. For i As Integer = 0 To UBound(paths) - 1
    138. p = paths(i)
    139. Select Case node.nodeType
    140. Case NodeTypeEnum.isDict, NodeTypeEnum.isList
    141. If node.nodeType = NodeTypeEnum.isList Then
    142. p = Int(Val(p))
    143. End If
    144. If Not node.childNode.ContainsKey(p) Then
    145. Return
    146. End If
    147. Case Else
    148. node.nodeType = NodeTypeEnum.isDict
    149. node.childNode = New Dictionary(Of String, HarryNode)
    150. If Not node.childNode.ContainsKey(p) Then
    151. Return
    152. End If
    153. End Select
    154. node = node.childNode(p)
    155. Next
    156. p = paths.Last
    157. Select Case node.nodeType
    158. Case NodeTypeEnum.isDict, NodeTypeEnum.isList
    159. If node.nodeType = NodeTypeEnum.isList Then
    160. p = Int(Val(p))
    161. End If
    162. If Not node.childNode.ContainsKey(p) Then
    163. Return
    164. End If
    165. Case Else
    166. node.nodeType = NodeTypeEnum.isDict
    167. node.childNode = New Dictionary(Of String, HarryNode)
    168. If Not node.childNode.ContainsKey(p) Then
    169. Return
    170. End If
    171. End Select
    172. node.childNode.Remove(p)
    173. End Sub
    174. Public Function GetAtt(path As String, Optional defaultValue As Object = Nothing) As Object
    175. If path = "" Then
    176. Return Value
    177. End If
    178. Dim paths() As String = path.Split(pathSeparator)
    179. Dim node As HarryNode = Me
    180. For Each p As String In paths
    181. Select Case node.nodeType
    182. Case NodeTypeEnum.isDict, NodeTypeEnum.isList
    183. If node.childNode.ContainsKey(p) Then
    184. node = node.childNode(p)
    185. Else
    186. Return defaultValue
    187. End If
    188. Case Else
    189. Return defaultValue
    190. End Select
    191. Next
    192. Return node.Value
    193. End Function
    194. Public Function GetNode(path As String) As HarryNode
    195. If path = "" Then
    196. Return Me
    197. End If
    198. Dim p As String
    199. Dim paths() As String = path.Split(pathSeparator)
    200. Dim node As HarryNode = Me
    201. For i As Integer = 0 To UBound(paths) - 1
    202. p = paths(i)
    203. Select Case node.nodeType
    204. Case NodeTypeEnum.isDict, NodeTypeEnum.isList
    205. If node.childNode.ContainsKey(p) Then
    206. node = node.childNode(p)
    207. Else
    208. Return New HarryNode("", "", Me)
    209. End If
    210. Case Else
    211. Return New HarryNode("", "", Me)
    212. End Select
    213. Next
    214. If node.childNode IsNot Nothing AndAlso node.childNode.ContainsKey(paths.Last) Then
    215. Return node.childNode(paths.Last)
    216. End If
    217. Return New HarryNode(paths.Last, String.Format("""{0}""", paths.Last), Me)
    218. End Function
    219. Public Sub SetAtt(path As String, newValue As Object, newValueType As String)
    220. RaiseEvent NodeContentChangeBefore(path, newValue, newValueType)
    221. Dim paths() As String = path.Split(pathSeparator)
    222. Dim p As String
    223. Dim node As HarryNode = Me
    224. For i As Integer = 0 To UBound(paths) - 1
    225. p = paths(i)
    226. Select Case node.nodeType
    227. Case NodeTypeEnum.isDict, NodeTypeEnum.isList
    228. If node.nodeType = NodeTypeEnum.isList Then
    229. p = Int(Val(p))
    230. End If
    231. If Not node.childNode.ContainsKey(p) Then
    232. node.childNode.Add(p, New HarryNode(p, "{}", Me))
    233. End If
    234. Case Else
    235. node.nodeType = NodeTypeEnum.isDict
    236. node.childNode = New Dictionary(Of String, HarryNode)
    237. If Not node.childNode.ContainsKey(p) Then
    238. node.childNode.Add(p, New HarryNode(p, "{}", Me))
    239. End If
    240. End Select
    241. node = node.childNode(p)
    242. Next
    243. p = paths.Last
    244. Select Case node.nodeType
    245. Case NodeTypeEnum.isDict, NodeTypeEnum.isList
    246. If node.nodeType = NodeTypeEnum.isList Then
    247. p = Int(Val(p))
    248. End If
    249. If Not node.childNode.ContainsKey(p) Then
    250. node.childNode.Add(p, New HarryNode(p, newValue, newValueType, Me))
    251. End If
    252. Case Else
    253. node.nodeType = NodeTypeEnum.isDict
    254. node.childNode = New Dictionary(Of String, HarryNode)
    255. If Not node.childNode.ContainsKey(p) Then
    256. node.childNode.Add(p, New HarryNode(p, newValue, newValueType, Me))
    257. End If
    258. End Select
    259. node.childNode(p).Value = newValue
    260. RaiseEvent NodeContentChangeLater(path, node.childNode(p).Value, node.nodeType)
    261. End Sub
    262. Public Sub ReName(path As String, newName As String)
    263. Dim paths() As String = path.Split(pathSeparator)
    264. Dim p As String
    265. Dim node As HarryNode = Me
    266. For i As Integer = 0 To UBound(paths) - 1
    267. p = paths(i)
    268. Select Case node.nodeType
    269. Case NodeTypeEnum.isDict, NodeTypeEnum.isList
    270. If node.nodeType = NodeTypeEnum.isList Then
    271. p = Int(Val(p))
    272. End If
    273. If Not node.childNode.ContainsKey(p) Then
    274. node.childNode.Add(p, New HarryNode(p, "{}", Me))
    275. End If
    276. Case Else
    277. node.nodeType = NodeTypeEnum.isDict
    278. node.childNode = New Dictionary(Of String, HarryNode)
    279. If Not node.childNode.ContainsKey(p) Then
    280. node.childNode.Add(p, New HarryNode(p, "{}", Me))
    281. End If
    282. End Select
    283. node = node.childNode(p)
    284. Next
    285. p = paths.Last
    286. Select Case node.nodeType
    287. Case NodeTypeEnum.isDict, NodeTypeEnum.isList
    288. If node.nodeType = NodeTypeEnum.isList Then
    289. p = Int(Val(p))
    290. End If
    291. If node.childNode.ContainsKey(p) Then
    292. ' 修改
    293. node.childNode.Add(newName, New HarryNode(newName, node.childNode(p).ToJson, Me))
    294. node.childNode.Remove(p)
    295. End If
    296. Case Else
    297. node.nodeType = NodeTypeEnum.isDict
    298. node.childNode = New Dictionary(Of String, HarryNode)
    299. If node.childNode.ContainsKey(p) Then
    300. node.childNode.Add(newName, New HarryNode(newName, node.childNode(p).ToJson, Me))
    301. node.childNode.Remove(p)
    302. End If
    303. End Select
    304. End Sub
    305. Public Sub SetAtt(path As String, json As String)
    306. RaiseEvent NodeContentChangeBeforeFromJson(path, json)
    307. Dim paths() As String = path.Split(pathSeparator)
    308. Dim p As String
    309. Dim node As HarryNode = Me
    310. For i As Integer = 0 To UBound(paths) - 1
    311. p = paths(i)
    312. Select Case node.nodeType
    313. Case NodeTypeEnum.isDict, NodeTypeEnum.isList
    314. If node.nodeType = NodeTypeEnum.isList Then
    315. p = Int(Val(p))
    316. End If
    317. If Not node.childNode.ContainsKey(p) Then
    318. node.childNode.Add(p, New HarryNode(p, "{}", Me))
    319. End If
    320. Case Else
    321. node.nodeType = NodeTypeEnum.isDict
    322. node.childNode = New Dictionary(Of String, HarryNode)
    323. If Not node.childNode.ContainsKey(p) Then
    324. node.childNode.Add(p, New HarryNode(p, "{}", Me))
    325. End If
    326. End Select
    327. node = node.childNode(p)
    328. Next
    329. p = paths.Last
    330. Select Case node.nodeType
    331. Case NodeTypeEnum.isDict, NodeTypeEnum.isList
    332. If node.nodeType = NodeTypeEnum.isList Then
    333. p = Int(Val(p))
    334. End If
    335. If Not node.childNode.ContainsKey(p) Then
    336. node.childNode.Add(p, New HarryNode(p, "{}", Me))
    337. End If
    338. Case Else
    339. node.nodeType = NodeTypeEnum.isDict
    340. node.childNode = New Dictionary(Of String, HarryNode)
    341. If Not node.childNode.ContainsKey(p) Then
    342. node.childNode.Add(p, New HarryNode(p, "{}", Me))
    343. End If
    344. End Select
    345. node.childNode(p).JsonToValue(json)
    346. RaiseEvent NodeContentChangeLaterFromJson(path, json)
    347. End Sub
    348. Public Function ToJson(Optional deep As Integer = 1) As String
    349. If outputFormat Then
    350. Dim deepFormatRetraction = New String(" ", deep * formatRetraction)
    351. Dim deepFormatRetractionSub1 = New String(" ", (deep - 1) * formatRetraction)
    352. Select Case nodeType
    353. Case NodeTypeEnum.isString
    354. Return String.Format("""{0}""", ToEscape(stringValue))
    355. Case NodeTypeEnum.isBool
    356. Return boolValue.ToString.ToLower
    357. Case NodeTypeEnum.isSingle
    358. Return singleValue
    359. Case NodeTypeEnum.isDict
    360. Dim result As New List(Of String)
    361. For i As Integer = 0 To childNode.Count - 1
    362. result.Add(String.Format(deepFormatRetraction & """{0}"": {1}", childNode.Keys(i), childNode.Values(i).ToJson(deep + 1)))
    363. Next
    364. Return String.Format(Replace("{{\n{0}\n{1}}}", "\n", vbCrLf), Join(result.ToArray, "," & vbCrLf), deepFormatRetractionSub1)
    365. Case NodeTypeEnum.isList
    366. Dim result As New List(Of String)
    367. For i As Integer = 0 To childNode.Count - 1
    368. result.Add(deepFormatRetraction & childNode.Values(i).ToJson(deep + 1))
    369. Next
    370. Return String.Format(Replace("[\n{0}\n{1}]", "\n", vbCrLf), Join(result.ToArray, "," & vbCrLf), deepFormatRetractionSub1)
    371. Case Else
    372. Return ""
    373. End Select
    374. End If
    375. Select Case nodeType
    376. Case NodeTypeEnum.isString
    377. Return String.Format("""{0}""", ToEscape(stringValue))
    378. Case NodeTypeEnum.isBool
    379. Return boolValue
    380. Case NodeTypeEnum.isSingle
    381. Return singleValue
    382. Case NodeTypeEnum.isDict
    383. Dim result As New List(Of String)
    384. For i As Integer = 0 To childNode.Count - 1
    385. result.Add(String.Format("""{0}"":{1}", childNode.Keys(i), childNode.Values(i).ToJson))
    386. Next
    387. Return String.Format("{{{0}}}", Join(result.ToArray, ","))
    388. Case NodeTypeEnum.isList
    389. Dim result As New List(Of String)
    390. For i As Integer = 0 To childNode.Count - 1
    391. result.Add(childNode.Values(i).ToJson)
    392. Next
    393. Return String.Format("[{0}]", Join(result.ToArray, ","))
    394. Case Else
    395. Return ""
    396. End Select
    397. End Function
    398. Public Overloads Function ToString() As String
    399. Return ToJson()
    400. End Function
    401. Public Property Value() As Object
    402. Get
    403. Select Case nodeType
    404. Case NodeTypeEnum.isString
    405. Return stringValue
    406. Case NodeTypeEnum.isBool
    407. Return boolValue
    408. Case NodeTypeEnum.isSingle
    409. Return singleValue
    410. Case NodeTypeEnum.isDict
    411. Return childNode
    412. Case NodeTypeEnum.isList
    413. Return childNode.Values
    414. Case Else
    415. Return Nothing
    416. End Select
    417. End Get
    418. Set(value As Object)
    419. Select Case nodeType
    420. Case NodeTypeEnum.isString
    421. stringValue = value
    422. Case NodeTypeEnum.isBool
    423. boolValue = value
    424. Case NodeTypeEnum.isSingle
    425. singleValue = value
    426. Case NodeTypeEnum.isDict
    427. childNode = value
    428. Case NodeTypeEnum.isList
    429. Dim valueList As List(Of HarryNode) = value
    430. childNode.Clear()
    431. For i As Integer = 0 To valueList.Count - 1
    432. childNode.Add(i, valueList(i))
    433. Next
    434. End Select
    435. End Set
    436. End Property
    437. Public Sub JsonToValue(json As String)
    438. If json Is Nothing Then
    439. Return
    440. End If
    441. json = Regex.Match(json, "^\s*(.*?)\s*$", RegexOptions.Singleline).Groups(1).Value
    442. If Regex.IsMatch(json, "^"".*""$", RegexOptions.Singleline) Then
    443. '字符串
    444. nodeType = NodeTypeEnum.isString
    445. stringValue = json.Substring(1, json.Length - 2)
    446. ElseIf Regex.IsMatch(json, "^{.*}$", RegexOptions.Singleline) Then
    447. '字典
    448. nodeType = NodeTypeEnum.isDict
    449. If json = "{}" OrElse Regex.IsMatch(json, "^\s*\{\s*\}\s*$") Then
    450. childNode = New Dictionary(Of String, HarryNode)
    451. Else
    452. childNode = GetDict(json, Me)
    453. End If
    454. ElseIf Regex.IsMatch(json, "^\[.*\]$", RegexOptions.Singleline) Then
    455. '列表
    456. nodeType = NodeTypeEnum.isList
    457. If json = "[]" OrElse Regex.IsMatch(json, "^\s*\[\s*\]\s*$") Then
    458. childNode = New Dictionary(Of String, HarryNode)
    459. Else
    460. childNode = GetList(json, Me)
    461. End If
    462. ElseIf Regex.IsMatch(json, "^[-]{0,1}[\d]*[\.]{0,1}[\d]*$", RegexOptions.Singleline) Then
    463. '数值
    464. nodeType = NodeTypeEnum.isSingle
    465. singleValue = Val(json)
    466. Else
    467. '布尔值
    468. nodeType = NodeTypeEnum.isBool
    469. boolValue = GetBool(json)
    470. End If
    471. End Sub
    472. Public Shared Function GetDict(json As String, sourceNode As HarryNode) As Dictionary(Of String, HarryNode)
    473. 'Debug.WriteLine(String.Format("GetDict.json={0}", json))
    474. Dim node As New Dictionary(Of String, HarryNode)
    475. Dim name As String = ""
    476. Dim temp As New List(Of String)
    477. Dim bigBrackets As Integer
    478. Dim colon As Integer
    479. Dim doubleQuotationMark As Integer
    480. Dim brackets As Integer
    481. Dim escape As Integer
    482. Dim stringContent As String
    483. Dim exegesis As Integer
    484. For Each c As String In json
    485. 'Debug.WriteLine(Join(temp.ToArray, ""))
    486. 'Debug.WriteLine("doubleQuotationMark={0}", doubleQuotationMark)
    487. 'Debug.WriteLine("exegesis={0}", exegesis)
    488. 'Debug.WriteLine("bigBrackets={0}", bigBrackets)
    489. 'Debug.WriteLine("brackets={0}", brackets)
    490. 'Debug.WriteLine("")
    491. If c = "/" Then
    492. exegesis += 1
    493. Continue For
    494. ElseIf exegesis = 1 Then
    495. temp.Add("/")
    496. exegesis = 0
    497. End If
    498. If exegesis >= 2 Then
    499. If c = vbCr Or c = vbLf Then
    500. exegesis = 0
    501. Else
    502. Continue For
    503. End If
    504. End If
    505. If doubleQuotationMark = 0 Then
    506. '未在字符串内时
    507. Select Case c
    508. Case "{"
    509. bigBrackets += 1
    510. If bigBrackets > 1 OrElse brackets > 0 Then
    511. '子嵌套记忆
    512. temp.Add(c)
    513. End If
    514. Case "}"
    515. bigBrackets -= 1
    516. If bigBrackets > 1 OrElse brackets > 0 OrElse (bigBrackets = 1 AndAlso brackets = 0) Then
    517. temp.Add(c)
    518. End If
    519. Case "["
    520. brackets += 1
    521. temp.Add(c)
    522. Case "]"
    523. brackets -= 1
    524. temp.Add(c)
    525. Case ":"
    526. If bigBrackets = 1 AndAlso brackets = 0 Then
    527. '第一层嵌套内
    528. colon += 1
    529. ElseIf bigBrackets > 1 OrElse brackets > 0 Then
    530. temp.Add(c)
    531. End If
    532. Case """"
    533. If bigBrackets = 1 AndAlso brackets = 0 Then
    534. '第一层嵌套内
    535. doubleQuotationMark += 1
    536. temp.Add(c)
    537. ElseIf bigBrackets > 1 OrElse brackets > 0 Then
    538. temp.Add(c)
    539. End If
    540. Case ","
    541. If colon > 0 AndAlso bigBrackets = 1 AndAlso brackets = 0 Then
    542. '非字符串
    543. If temp.Count > 0 Then
    544. stringContent = Join(temp.ToArray, "")
    545. temp.Clear()
    546. node.Add(name, New HarryNode(name, stringContent, sourceNode))
    547. Else
    548. 'null
    549. node.Add(name, New HarryNode(name, Nothing, sourceNode))
    550. End If
    551. colon = 0
    552. Else
    553. temp.Add(c)
    554. End If
    555. Case Else
    556. If bigBrackets > 1 Or Regex.IsMatch(c, "\S", RegexOptions.Singleline) Then
    557. temp.Add(c)
    558. End If
    559. End Select
    560. ElseIf bigBrackets = 1 AndAlso brackets = 0 Then
    561. '第一层嵌套内
    562. '在字符串内
    563. Select Case c
    564. Case """"
    565. temp.Add(c)
    566. If escape = 1 Then
    567. '转义"
    568. escape = 0
    569. Else
    570. doubleQuotationMark = 0
    571. If colon = 0 Then
    572. '节点名
    573. stringContent = Join(temp.ToArray, "")
    574. temp.Clear()
    575. name = stringContent.Substring(1, stringContent.Length - 2)
    576. End If
    577. End If
    578. Case "\"
    579. escape += 1
    580. If escape > 1 Then
    581. '转义\
    582. temp.Add(c)
    583. escape = 0
    584. End If
    585. Case "n"
    586. If escape = 1 Then
    587. '转义换行
    588. temp.Add(vbCrLf)
    589. escape = 0
    590. Else
    591. temp.Add(c)
    592. End If
    593. Case "b"
    594. If escape = 1 Then
    595. temp.Add(Chr(8))
    596. escape = 0
    597. Else
    598. temp.Add(c)
    599. End If
    600. Case "f"
    601. If escape = 1 Then
    602. temp.Add(Chr(12))
    603. escape = 0
    604. Else
    605. temp.Add(c)
    606. End If
    607. Case "t"
    608. If escape = 1 Then
    609. temp.Add(vbTab)
    610. escape = 0
    611. Else
    612. temp.Add(c)
    613. End If
    614. Case Else
    615. escape = 0
    616. temp.Add(c)
    617. End Select
    618. End If
    619. Next
    620. If temp.Count > 0 Then
    621. stringContent = Join(temp.ToArray, "")
    622. temp.Clear()
    623. node.Add(name, New HarryNode(name, stringContent, sourceNode))
    624. Else
    625. 'null
    626. node.Add(name, New HarryNode(name, Nothing, sourceNode))
    627. End If
    628. Return node
    629. End Function
    630. Public Shared Function GetList(json As String, sourceNode As HarryNode) As Dictionary(Of String, HarryNode)
    631. 'Debug.WriteLine(String.Format("GetList.json={0}", json))
    632. Dim node As New Dictionary(Of String, HarryNode)
    633. Dim name As String
    634. Dim temp As New List(Of String)
    635. Dim bigBrackets As Integer
    636. Dim doubleQuotationMark As Integer
    637. Dim brackets As Integer
    638. Dim escape As Integer
    639. Dim comma As Integer
    640. Dim stringContent As String
    641. For Each c As String In json
    642. Dim exegesis As Integer
    643. If c = "/" Then
    644. exegesis += 1
    645. Continue For
    646. ElseIf exegesis = 1 Then
    647. temp.Add("/")
    648. exegesis = 0
    649. End If
    650. If exegesis >= 2 Then
    651. If c = vbCr Or c = vbLf Then
    652. exegesis = 0
    653. Else
    654. Continue For
    655. End If
    656. End If
    657. If doubleQuotationMark = 0 Then
    658. '未在字符串内时
    659. Select Case c
    660. Case "["
    661. brackets += 1
    662. If brackets > 1 OrElse bigBrackets > 0 Then
    663. '子嵌套记忆
    664. temp.Add(c)
    665. End If
    666. Case "]"
    667. brackets -= 1
    668. If brackets > 1 OrElse bigBrackets > 0 OrElse (brackets = 1 AndAlso bigBrackets = 0) Then
    669. temp.Add(c)
    670. End If
    671. Case "{"
    672. bigBrackets += 1
    673. temp.Add(c)
    674. Case "}"
    675. bigBrackets -= 1
    676. temp.Add(c)
    677. Case """"
    678. If brackets = 1 AndAlso bigBrackets = 0 Then
    679. '第一层嵌套内
    680. doubleQuotationMark += 1
    681. temp.Add(c)
    682. ElseIf brackets > 1 OrElse bigBrackets > 0 Then
    683. temp.Add(c)
    684. End If
    685. Case ","
    686. If bigBrackets = 0 AndAlso brackets = 1 Then
    687. name = comma
    688. comma += 1
    689. If temp.Count > 0 Then
    690. stringContent = Join(temp.ToArray, "")
    691. temp.Clear()
    692. node.Add(name, New HarryNode(name, stringContent, sourceNode))
    693. Else
    694. 'null
    695. node.Add(name, New HarryNode(name, Nothing, sourceNode))
    696. End If
    697. Else
    698. temp.Add(c)
    699. End If
    700. Case Else
    701. If bigBrackets > 1 Or Regex.IsMatch(c, "\S", RegexOptions.Singleline) Then
    702. temp.Add(c)
    703. End If
    704. End Select
    705. ElseIf brackets = 1 AndAlso bigBrackets = 0 Then
    706. '第一层嵌套内
    707. '在字符串内
    708. Select Case c
    709. Case """"
    710. temp.Add(c)
    711. If escape = 1 Then
    712. '转义"
    713. escape = 0
    714. Else
    715. doubleQuotationMark = 0
    716. End If
    717. Case "\"
    718. escape += 1
    719. If escape > 1 Then
    720. '转义\
    721. temp.Add(c)
    722. escape = 0
    723. End If
    724. Case "n"
    725. If escape = 1 Then
    726. '转义换行
    727. temp.Add(vbCrLf)
    728. escape = 0
    729. Else
    730. temp.Add(c)
    731. End If
    732. Case "b"
    733. If escape = 1 Then
    734. temp.Add(Chr(8))
    735. escape = 0
    736. Else
    737. temp.Add(c)
    738. End If
    739. Case "f"
    740. If escape = 1 Then
    741. temp.Add(Chr(12))
    742. escape = 0
    743. Else
    744. temp.Add(c)
    745. End If
    746. Case "t"
    747. If escape = 1 Then
    748. temp.Add(vbTab)
    749. escape = 0
    750. Else
    751. temp.Add(c)
    752. End If
    753. Case Else
    754. escape = 0
    755. temp.Add(c)
    756. End Select
    757. End If
    758. Next
    759. name = comma
    760. If temp.Count > 0 Then
    761. '非字符串
    762. stringContent = Join(temp.ToArray, "")
    763. temp.Clear()
    764. node.Add(name, New HarryNode(name, stringContent, sourceNode))
    765. Else
    766. 'null
    767. node.Add(name, New HarryNode(name, Nothing, sourceNode))
    768. End If
    769. Return node
    770. End Function
    771. Public Shared Function GetBool(value As String) As Boolean
    772. If value.ToLower = "false" OrElse value = "0" Then
    773. Return False
    774. End If
    775. Return True
    776. End Function
    777. Public Sub New(name As String, json As String, Optional parent As HarryNode = Nothing)
    778. nodeName = name
    779. parentNode = parent
    780. JsonToValue(json)
    781. End Sub
    782. Public Sub New(name As String, nodeValue As Object, type As NodeTypeEnum, Optional parent As HarryNode = Nothing)
    783. nodeName = name
    784. nodeType = type
    785. parentNode = parent
    786. Value = nodeValue
    787. End Sub
    788. End Class

  • 相关阅读:
    IO流框架,缓冲流
    【Hadoop】学习笔记(四)
    [MySQL] 表的增删查改(CURD)
    [python 刷题] 437 Path Sum III
    SpringBoot2.7.9 配置文件加载方式
    RFID汽车制造工业系统解决方案
    《分析模式》漫谈06-实例不是“一种”隔壁老王
    【博弈论】对冲:世界杯足球竞猜能稳赚不赔?
    【超好懂的比赛题解】HNCPC Multi-university Training Round3 比赛题解
    【正点原子FPGA连载】第二十五章 双路高速AD实验 摘自【正点原子】DFZU2EG/4EV MPSoC 之FPGA开发指南V1.0
  • 原文地址:https://blog.csdn.net/HarryXYC/article/details/133830989