这个代码写的有点时间了,可能有点小bug,欢迎评论区反馈
作用是将Json文本转化成一个HarryNode类进行相关的Json对象处理或者读取,也可以将一个HarryNode对象用ToString变为Json文本。
- dim harryNode = New HarryNode("", "{""msg"":""hello world!""}")
- msgbox(harryNode.GetAtt("msg")) '弹窗显示hello world!
-
-
- '下面展示更复杂的嵌套读取
- dim harryNode = New HarryNode("", "{""node1"": {""msg"":""hello world!""}}")
- msgbox(harryNode.GetAtt("node1.msg")) '弹窗显示hello world! 没错,用“.”作为路径连接符进行寻址
-
- '如果json的键里包含“.”可以将源码里的“.”替换成其它字符,也可以这样进行取值
- msgbox(harryNode.GetAtt("node1")("msg").value
- '这里的harryNode.GetAtt("node1")返回的是一个字典对象(String, HarryNode)
- Dim harryNode = New HarryNode("", "{}")
- harryNode.SetAtt("msg", """hello world!""")
- MsgBox(harryNode.ToString)
-
- '可以看到SetAtt方法的第二个参数输入的字符串需要是json字符串格式,因此字符串本身需要加双引号
- '下面可以用SetAtt的另一种重载方法,与上面代码的结果相同
- harryNode.SetAtt("msg", "hello world!", NodeTypeEnum.isString)
- MsgBox(harryNode.ToString)
-
- '同样,对嵌套的复杂json对象,可以如下
- harryNode.SetAtt("node1.msg", "hello world!", NodeTypeEnum.isString)
- '下面这样写也是可以的
- harryNode.SetAtt("node1", "{""msg"": ""hello world!""}")
构造函数
| name | String | 节点的名字(对于根节点此项没啥意义) |
| json | String | 要解析构造的JSON串 |
| parent | HarryNode | 实例的父节点 |
| name | String | 节点的名字(对于根节点此项没啥意义) |
| nodeValue | Object | 节点VB.NET对象值 |
| type | NodeTypeEnum | 节点值的类型 |
| parent | HarryNode | 实例的父节点 |
获得指定路径的VB.NET对象
| path | String | 节点路径 |
| defaultValue | Object | 没有获取到返回的值,默认Nothing |
根据指定路径设置节点值
| path | String | 节点路径 |
| newValue | Object | 节点的值(VB.NET对象) |
| newValueType | NodeTypeEnum | 值的类型 |
| path | String | 节点路径 |
| json | String | 节点的值(JSON字符串) |
重命名某个节点
| path | String | 节点路径 |
| newName | String | 新名字 |
返回JSON字符串,与ToString()等价
获得指定路径的HarryNode对象
| path | String | 节点路径 |
AddNode
添加子节点
| path | String | 节点路径 |
| nodeName | String | 子节点名 |
| nodeJson | String | 子节点JSON串 |
删除指定路径的节点
| path | String | 节点路径 |
合并两个字典节点;
| node | HarryNode | 要合并的节点 |
返回一个当前节点子节点名的列表
指定某个节点的数据加一个值
| path | String | 节点路径 |
| addValue | Single | 加数 |
指定某个节点的数据加一个值,但是限制了数的范围
| path | String | 节点路径 |
| addValue | Single | 加数 |
| maxValue | Single | 最大值 |
| minValue | Single | 最小值,默认0 |
指定某个节点的数据乘一个值
| path | String | 节点路径 |
| addValue | Single | 乘数 |
指定某个节点的数据求次幂
| path | String | 节点路径 |
| addValue | Single | 幂 |
Value
当前节点的VB.NET类型值
NodeContentChangeBefore
节点内容改变之前
| path | String | 节点路径 |
| newValue | Object | 即将变成的值 |
| newValueType | NodeTypeEnum | 即将变成值的类型 |
NodeContentChangeBeforeFromJson
节点内容改变之前(通过JSON解释)
| path | String | 节点路径 |
| json | String | 即将变成的值的JSON字符串 |
NodeContentChangeLater
节点内容改变之后
| path | String | 节点路径 |
| newValue | Object | 变成的值 |
| newValueType | NodeTypeEnum | 变成值的类型 |
NodeContentChangeLaterFromJson
节点内容改变之后(通过JSON解释)
| path | String | 节点路径 |
| json | String | 变成的值的JSON字符串 |
- Imports System.Text.RegularExpressions
- Public Class HarryNode
- Public Shared pathSeparator As String = "."
- Public Shared outputFormat As Boolean = True
- Public Shared formatRetraction As Integer = 2
- Public Shared Function MulReplace(source As String, ParamArray args() As String) As String
- If args.Length Mod 2 <> 0 Then
- Return source
- End If
- For i As Integer = 0 To UBound(args) Step 2
- source = Replace(source, args(i), args(i + 1))
- Next
- Return source
- End Function
- Public Shared Function ToEscape(source As String) As String
- Return MulReplace(source, "\", "\\", vbCrLf, "\n", vbTab, "\t", """", "\""", Chr(8), "\b", Chr(12), "\f")
- End Function
- Public Enum NodeTypeEnum
- isNull = 0
- isString = 1
- isSingle = 2
- isDict = 3
- isList = 4
- isBool = 5
- End Enum
- Public nodeType As NodeTypeEnum
- Public nodeName As String
- Public parentNode As HarryNode
-
- Private stringValue As String
- Private singleValue As Single
- Private boolValue As Boolean
- Private childNode As Dictionary(Of String, HarryNode)
-
- Public Event NodeContentChangeBefore(ByRef path As String, ByRef newValue As Object, ByRef newValueType As String)
- Public Event NodeContentChangeBeforeFromJson(ByRef path As String, ByRef json As String)
-
- Public Event NodeContentChangeLater(path As String, ByRef nowValue As Object, ByRef newValueType As NodeTypeEnum)
- Public Event NodeContentChangeLaterFromJson(path As String, nowJson As String)
- Public Sub Merge(node As HarryNode)
- If nodeType = node.nodeType And nodeType = NodeTypeEnum.isDict Then
- For i = 0 To node.childNode.Count - 1
- Dim key = node.childNode.Keys(i)
- If childNode.ContainsKey(key) Then
- childNode(key).Merge(node.childNode(key))
- Else
- childNode.Add(key, node.childNode(key))
- End If
- Next
- End If
- End Sub
- Public Function GetChildPath() As List(Of String)
- Dim result As New List(Of String)
- If nodeType = NodeTypeEnum.isDict Or nodeType = NodeTypeEnum.isList Then
- result.AddRange(childNode.Keys)
- Else
- result.Add(nodeName)
- End If
- Return result
- End Function
- 'Public Function GetTreeNode(interpreter As 解释器) As TreeNode
- ' Dim rootNode As New TreeNode(nodeName & interpreter.Search(nodeName))
- ' If nodeType = NodeTypeEnum.isDict Or nodeType = NodeTypeEnum.isList Then
- ' For Each cNode In childNode
- ' rootNode.Nodes.Add(cNode.Value.GetTreeNode(interpreter))
- ' Next
- ' Else
- ' rootNode.Nodes.Add(Value & interpreter.Search(Value))
- ' End If
- ' Return rootNode
- 'End Function
- Public Sub Power(path As String, addValue As Single)
- SetAtt(path, GetAtt(path, 0) ^ addValue, 0)
- End Sub
- Public Sub Add(path As String, addValue As Single)
- SetAtt(path, GetAtt(path, 0) + addValue, 0)
- End Sub
- Public Sub ConAdd(path As String, addValue As Single, maxValue As Single, Optional minValue As Single = 0)
- Dim newValue As Single = GetAtt(path, 0) + addValue
- If newValue > maxValue Then
- newValue = maxValue
- End If
- If newValue < minValue Then
- newValue = minValue
- End If
- SetAtt(path, newValue, 0)
- End Sub
- Public Sub Mul(path As String, addValue As Single)
- SetAtt(path, GetAtt(path, 0) * addValue, 0)
- End Sub
- Public Sub AddNode(path As String, nodeName As String, nodeJson As String)
- Dim paths() As String = path.Split(pathSeparator)
- Dim p As String
- Dim node As HarryNode = Me
- For i As Integer = 0 To UBound(paths) - 1
- p = paths(i)
- Select Case node.nodeType
- Case NodeTypeEnum.isDict, NodeTypeEnum.isList
- If node.nodeType = NodeTypeEnum.isList Then
- p = Int(Val(p))
- End If
- If Not node.childNode.ContainsKey(p) Then
- node.childNode.Add(p, New HarryNode(p, "{}", Me))
- End If
- Case Else
- node.nodeType = NodeTypeEnum.isDict
- node.childNode = New Dictionary(Of String, HarryNode)
- If Not node.childNode.ContainsKey(p) Then
- node.childNode.Add(p, New HarryNode(p, "{}", Me))
- End If
- End Select
- node = node.childNode(p)
- Next
- p = paths.Last
- Select Case node.nodeType
- Case NodeTypeEnum.isDict, NodeTypeEnum.isList
- If node.nodeType = NodeTypeEnum.isList Then
- p = Int(Val(p))
- End If
- If Not node.childNode.ContainsKey(p) Then
- node.childNode.Add(p, New HarryNode(p, "{}", Me))
- End If
- Case Else
- node.nodeType = NodeTypeEnum.isDict
- node.childNode = New Dictionary(Of String, HarryNode)
- If Not node.childNode.ContainsKey(p) Then
- node.childNode.Add(p, New HarryNode(p, "{}", Me))
- End If
- End Select
- If Not node.childNode.ContainsKey(p) Then
- node.childNode.Add(p, New HarryNode(nodeName, nodeJson, Me))
- Else
- node.childNode(p) = New HarryNode(nodeName, nodeJson, Me)
- End If
- End Sub
- Public Sub Del(path As String)
- Dim paths() As String = path.Split(pathSeparator)
- Dim p As String
- Dim node As HarryNode = Me
- For i As Integer = 0 To UBound(paths) - 1
- p = paths(i)
- Select Case node.nodeType
- Case NodeTypeEnum.isDict, NodeTypeEnum.isList
- If node.nodeType = NodeTypeEnum.isList Then
- p = Int(Val(p))
- End If
- If Not node.childNode.ContainsKey(p) Then
- Return
- End If
- Case Else
- node.nodeType = NodeTypeEnum.isDict
- node.childNode = New Dictionary(Of String, HarryNode)
- If Not node.childNode.ContainsKey(p) Then
- Return
- End If
- End Select
- node = node.childNode(p)
- Next
- p = paths.Last
- Select Case node.nodeType
- Case NodeTypeEnum.isDict, NodeTypeEnum.isList
- If node.nodeType = NodeTypeEnum.isList Then
- p = Int(Val(p))
- End If
- If Not node.childNode.ContainsKey(p) Then
- Return
- End If
- Case Else
- node.nodeType = NodeTypeEnum.isDict
- node.childNode = New Dictionary(Of String, HarryNode)
- If Not node.childNode.ContainsKey(p) Then
- Return
- End If
- End Select
- node.childNode.Remove(p)
- End Sub
- Public Function GetAtt(path As String, Optional defaultValue As Object = Nothing) As Object
- If path = "" Then
- Return Value
- End If
- Dim paths() As String = path.Split(pathSeparator)
- Dim node As HarryNode = Me
- For Each p As String In paths
- Select Case node.nodeType
- Case NodeTypeEnum.isDict, NodeTypeEnum.isList
- If node.childNode.ContainsKey(p) Then
- node = node.childNode(p)
- Else
- Return defaultValue
- End If
- Case Else
- Return defaultValue
- End Select
- Next
- Return node.Value
- End Function
- Public Function GetNode(path As String) As HarryNode
- If path = "" Then
- Return Me
- End If
- Dim p As String
- Dim paths() As String = path.Split(pathSeparator)
- Dim node As HarryNode = Me
- For i As Integer = 0 To UBound(paths) - 1
- p = paths(i)
- Select Case node.nodeType
- Case NodeTypeEnum.isDict, NodeTypeEnum.isList
- If node.childNode.ContainsKey(p) Then
- node = node.childNode(p)
- Else
- Return New HarryNode("", "", Me)
- End If
- Case Else
- Return New HarryNode("", "", Me)
- End Select
- Next
- If node.childNode IsNot Nothing AndAlso node.childNode.ContainsKey(paths.Last) Then
- Return node.childNode(paths.Last)
- End If
- Return New HarryNode(paths.Last, String.Format("""{0}""", paths.Last), Me)
- End Function
- Public Sub SetAtt(path As String, newValue As Object, newValueType As String)
- RaiseEvent NodeContentChangeBefore(path, newValue, newValueType)
- Dim paths() As String = path.Split(pathSeparator)
- Dim p As String
- Dim node As HarryNode = Me
- For i As Integer = 0 To UBound(paths) - 1
- p = paths(i)
- Select Case node.nodeType
- Case NodeTypeEnum.isDict, NodeTypeEnum.isList
- If node.nodeType = NodeTypeEnum.isList Then
- p = Int(Val(p))
- End If
- If Not node.childNode.ContainsKey(p) Then
- node.childNode.Add(p, New HarryNode(p, "{}", Me))
- End If
- Case Else
- node.nodeType = NodeTypeEnum.isDict
- node.childNode = New Dictionary(Of String, HarryNode)
- If Not node.childNode.ContainsKey(p) Then
- node.childNode.Add(p, New HarryNode(p, "{}", Me))
- End If
- End Select
- node = node.childNode(p)
- Next
- p = paths.Last
- Select Case node.nodeType
- Case NodeTypeEnum.isDict, NodeTypeEnum.isList
- If node.nodeType = NodeTypeEnum.isList Then
- p = Int(Val(p))
- End If
- If Not node.childNode.ContainsKey(p) Then
- node.childNode.Add(p, New HarryNode(p, newValue, newValueType, Me))
- End If
- Case Else
- node.nodeType = NodeTypeEnum.isDict
- node.childNode = New Dictionary(Of String, HarryNode)
- If Not node.childNode.ContainsKey(p) Then
- node.childNode.Add(p, New HarryNode(p, newValue, newValueType, Me))
- End If
- End Select
- node.childNode(p).Value = newValue
- RaiseEvent NodeContentChangeLater(path, node.childNode(p).Value, node.nodeType)
- End Sub
- Public Sub ReName(path As String, newName As String)
- Dim paths() As String = path.Split(pathSeparator)
- Dim p As String
- Dim node As HarryNode = Me
- For i As Integer = 0 To UBound(paths) - 1
- p = paths(i)
- Select Case node.nodeType
- Case NodeTypeEnum.isDict, NodeTypeEnum.isList
- If node.nodeType = NodeTypeEnum.isList Then
- p = Int(Val(p))
- End If
- If Not node.childNode.ContainsKey(p) Then
- node.childNode.Add(p, New HarryNode(p, "{}", Me))
- End If
- Case Else
- node.nodeType = NodeTypeEnum.isDict
- node.childNode = New Dictionary(Of String, HarryNode)
- If Not node.childNode.ContainsKey(p) Then
- node.childNode.Add(p, New HarryNode(p, "{}", Me))
- End If
- End Select
- node = node.childNode(p)
- Next
- p = paths.Last
- Select Case node.nodeType
- Case NodeTypeEnum.isDict, NodeTypeEnum.isList
- If node.nodeType = NodeTypeEnum.isList Then
- p = Int(Val(p))
- End If
- If node.childNode.ContainsKey(p) Then
- ' 修改
- node.childNode.Add(newName, New HarryNode(newName, node.childNode(p).ToJson, Me))
- node.childNode.Remove(p)
- End If
- Case Else
- node.nodeType = NodeTypeEnum.isDict
- node.childNode = New Dictionary(Of String, HarryNode)
- If node.childNode.ContainsKey(p) Then
- node.childNode.Add(newName, New HarryNode(newName, node.childNode(p).ToJson, Me))
- node.childNode.Remove(p)
- End If
- End Select
- End Sub
- Public Sub SetAtt(path As String, json As String)
- RaiseEvent NodeContentChangeBeforeFromJson(path, json)
- Dim paths() As String = path.Split(pathSeparator)
- Dim p As String
- Dim node As HarryNode = Me
- For i As Integer = 0 To UBound(paths) - 1
- p = paths(i)
- Select Case node.nodeType
- Case NodeTypeEnum.isDict, NodeTypeEnum.isList
- If node.nodeType = NodeTypeEnum.isList Then
- p = Int(Val(p))
- End If
- If Not node.childNode.ContainsKey(p) Then
- node.childNode.Add(p, New HarryNode(p, "{}", Me))
- End If
- Case Else
- node.nodeType = NodeTypeEnum.isDict
- node.childNode = New Dictionary(Of String, HarryNode)
- If Not node.childNode.ContainsKey(p) Then
- node.childNode.Add(p, New HarryNode(p, "{}", Me))
- End If
- End Select
- node = node.childNode(p)
- Next
- p = paths.Last
- Select Case node.nodeType
- Case NodeTypeEnum.isDict, NodeTypeEnum.isList
- If node.nodeType = NodeTypeEnum.isList Then
- p = Int(Val(p))
- End If
- If Not node.childNode.ContainsKey(p) Then
- node.childNode.Add(p, New HarryNode(p, "{}", Me))
- End If
- Case Else
- node.nodeType = NodeTypeEnum.isDict
- node.childNode = New Dictionary(Of String, HarryNode)
- If Not node.childNode.ContainsKey(p) Then
- node.childNode.Add(p, New HarryNode(p, "{}", Me))
- End If
- End Select
- node.childNode(p).JsonToValue(json)
- RaiseEvent NodeContentChangeLaterFromJson(path, json)
- End Sub
- Public Function ToJson(Optional deep As Integer = 1) As String
- If outputFormat Then
- Dim deepFormatRetraction = New String(" ", deep * formatRetraction)
- Dim deepFormatRetractionSub1 = New String(" ", (deep - 1) * formatRetraction)
- Select Case nodeType
- Case NodeTypeEnum.isString
- Return String.Format("""{0}""", ToEscape(stringValue))
- Case NodeTypeEnum.isBool
- Return boolValue.ToString.ToLower
- Case NodeTypeEnum.isSingle
- Return singleValue
- Case NodeTypeEnum.isDict
- Dim result As New List(Of String)
- For i As Integer = 0 To childNode.Count - 1
- result.Add(String.Format(deepFormatRetraction & """{0}"": {1}", childNode.Keys(i), childNode.Values(i).ToJson(deep + 1)))
- Next
- Return String.Format(Replace("{{\n{0}\n{1}}}", "\n", vbCrLf), Join(result.ToArray, "," & vbCrLf), deepFormatRetractionSub1)
- Case NodeTypeEnum.isList
- Dim result As New List(Of String)
- For i As Integer = 0 To childNode.Count - 1
- result.Add(deepFormatRetraction & childNode.Values(i).ToJson(deep + 1))
- Next
- Return String.Format(Replace("[\n{0}\n{1}]", "\n", vbCrLf), Join(result.ToArray, "," & vbCrLf), deepFormatRetractionSub1)
- Case Else
- Return ""
- End Select
- End If
- Select Case nodeType
- Case NodeTypeEnum.isString
- Return String.Format("""{0}""", ToEscape(stringValue))
- Case NodeTypeEnum.isBool
- Return boolValue
- Case NodeTypeEnum.isSingle
- Return singleValue
- Case NodeTypeEnum.isDict
- Dim result As New List(Of String)
- For i As Integer = 0 To childNode.Count - 1
- result.Add(String.Format("""{0}"":{1}", childNode.Keys(i), childNode.Values(i).ToJson))
- Next
- Return String.Format("{{{0}}}", Join(result.ToArray, ","))
- Case NodeTypeEnum.isList
- Dim result As New List(Of String)
- For i As Integer = 0 To childNode.Count - 1
- result.Add(childNode.Values(i).ToJson)
- Next
- Return String.Format("[{0}]", Join(result.ToArray, ","))
- Case Else
- Return ""
- End Select
- End Function
- Public Overloads Function ToString() As String
- Return ToJson()
- End Function
- Public Property Value() As Object
- Get
- Select Case nodeType
- Case NodeTypeEnum.isString
- Return stringValue
- Case NodeTypeEnum.isBool
- Return boolValue
- Case NodeTypeEnum.isSingle
- Return singleValue
- Case NodeTypeEnum.isDict
- Return childNode
- Case NodeTypeEnum.isList
- Return childNode.Values
- Case Else
- Return Nothing
- End Select
- End Get
- Set(value As Object)
- Select Case nodeType
- Case NodeTypeEnum.isString
- stringValue = value
- Case NodeTypeEnum.isBool
- boolValue = value
- Case NodeTypeEnum.isSingle
- singleValue = value
- Case NodeTypeEnum.isDict
- childNode = value
- Case NodeTypeEnum.isList
- Dim valueList As List(Of HarryNode) = value
- childNode.Clear()
- For i As Integer = 0 To valueList.Count - 1
- childNode.Add(i, valueList(i))
- Next
- End Select
- End Set
- End Property
- Public Sub JsonToValue(json As String)
- If json Is Nothing Then
- Return
- End If
- json = Regex.Match(json, "^\s*(.*?)\s*$", RegexOptions.Singleline).Groups(1).Value
- If Regex.IsMatch(json, "^"".*""$", RegexOptions.Singleline) Then
- '字符串
- nodeType = NodeTypeEnum.isString
- stringValue = json.Substring(1, json.Length - 2)
- ElseIf Regex.IsMatch(json, "^{.*}$", RegexOptions.Singleline) Then
- '字典
- nodeType = NodeTypeEnum.isDict
- If json = "{}" OrElse Regex.IsMatch(json, "^\s*\{\s*\}\s*$") Then
- childNode = New Dictionary(Of String, HarryNode)
- Else
- childNode = GetDict(json, Me)
- End If
- ElseIf Regex.IsMatch(json, "^\[.*\]$", RegexOptions.Singleline) Then
- '列表
- nodeType = NodeTypeEnum.isList
- If json = "[]" OrElse Regex.IsMatch(json, "^\s*\[\s*\]\s*$") Then
- childNode = New Dictionary(Of String, HarryNode)
- Else
- childNode = GetList(json, Me)
- End If
- ElseIf Regex.IsMatch(json, "^[-]{0,1}[\d]*[\.]{0,1}[\d]*$", RegexOptions.Singleline) Then
- '数值
- nodeType = NodeTypeEnum.isSingle
- singleValue = Val(json)
- Else
- '布尔值
- nodeType = NodeTypeEnum.isBool
- boolValue = GetBool(json)
- End If
- End Sub
- Public Shared Function GetDict(json As String, sourceNode As HarryNode) As Dictionary(Of String, HarryNode)
- 'Debug.WriteLine(String.Format("GetDict.json={0}", json))
- Dim node As New Dictionary(Of String, HarryNode)
- Dim name As String = ""
- Dim temp As New List(Of String)
- Dim bigBrackets As Integer
- Dim colon As Integer
- Dim doubleQuotationMark As Integer
- Dim brackets As Integer
- Dim escape As Integer
- Dim stringContent As String
- Dim exegesis As Integer
- For Each c As String In json
- 'Debug.WriteLine(Join(temp.ToArray, ""))
- 'Debug.WriteLine("doubleQuotationMark={0}", doubleQuotationMark)
- 'Debug.WriteLine("exegesis={0}", exegesis)
- 'Debug.WriteLine("bigBrackets={0}", bigBrackets)
- 'Debug.WriteLine("brackets={0}", brackets)
- 'Debug.WriteLine("")
- If c = "/" Then
- exegesis += 1
- Continue For
- ElseIf exegesis = 1 Then
- temp.Add("/")
- exegesis = 0
- End If
- If exegesis >= 2 Then
- If c = vbCr Or c = vbLf Then
- exegesis = 0
- Else
- Continue For
- End If
- End If
- If doubleQuotationMark = 0 Then
- '未在字符串内时
- Select Case c
- Case "{"
- bigBrackets += 1
- If bigBrackets > 1 OrElse brackets > 0 Then
- '子嵌套记忆
- temp.Add(c)
- End If
- Case "}"
- bigBrackets -= 1
- If bigBrackets > 1 OrElse brackets > 0 OrElse (bigBrackets = 1 AndAlso brackets = 0) Then
- temp.Add(c)
- End If
- Case "["
- brackets += 1
- temp.Add(c)
- Case "]"
- brackets -= 1
- temp.Add(c)
- Case ":"
- If bigBrackets = 1 AndAlso brackets = 0 Then
- '第一层嵌套内
- colon += 1
- ElseIf bigBrackets > 1 OrElse brackets > 0 Then
- temp.Add(c)
- End If
- Case """"
- If bigBrackets = 1 AndAlso brackets = 0 Then
- '第一层嵌套内
- doubleQuotationMark += 1
- temp.Add(c)
- ElseIf bigBrackets > 1 OrElse brackets > 0 Then
- temp.Add(c)
- End If
- Case ","
- If colon > 0 AndAlso bigBrackets = 1 AndAlso brackets = 0 Then
- '非字符串
- If temp.Count > 0 Then
- stringContent = Join(temp.ToArray, "")
- temp.Clear()
- node.Add(name, New HarryNode(name, stringContent, sourceNode))
- Else
- 'null
- node.Add(name, New HarryNode(name, Nothing, sourceNode))
- End If
- colon = 0
- Else
- temp.Add(c)
- End If
- Case Else
- If bigBrackets > 1 Or Regex.IsMatch(c, "\S", RegexOptions.Singleline) Then
- temp.Add(c)
- End If
- End Select
- ElseIf bigBrackets = 1 AndAlso brackets = 0 Then
- '第一层嵌套内
- '在字符串内
- Select Case c
- Case """"
- temp.Add(c)
- If escape = 1 Then
- '转义"
- escape = 0
- Else
- doubleQuotationMark = 0
- If colon = 0 Then
- '节点名
- stringContent = Join(temp.ToArray, "")
- temp.Clear()
- name = stringContent.Substring(1, stringContent.Length - 2)
- End If
- End If
- Case "\"
- escape += 1
- If escape > 1 Then
- '转义\
- temp.Add(c)
- escape = 0
- End If
- Case "n"
- If escape = 1 Then
- '转义换行
- temp.Add(vbCrLf)
- escape = 0
- Else
- temp.Add(c)
- End If
- Case "b"
- If escape = 1 Then
- temp.Add(Chr(8))
- escape = 0
- Else
- temp.Add(c)
- End If
- Case "f"
- If escape = 1 Then
- temp.Add(Chr(12))
- escape = 0
- Else
- temp.Add(c)
- End If
- Case "t"
- If escape = 1 Then
- temp.Add(vbTab)
- escape = 0
- Else
- temp.Add(c)
- End If
- Case Else
- escape = 0
- temp.Add(c)
- End Select
- End If
- Next
- If temp.Count > 0 Then
- stringContent = Join(temp.ToArray, "")
- temp.Clear()
- node.Add(name, New HarryNode(name, stringContent, sourceNode))
- Else
- 'null
- node.Add(name, New HarryNode(name, Nothing, sourceNode))
- End If
- Return node
- End Function
- Public Shared Function GetList(json As String, sourceNode As HarryNode) As Dictionary(Of String, HarryNode)
- 'Debug.WriteLine(String.Format("GetList.json={0}", json))
- Dim node As New Dictionary(Of String, HarryNode)
- Dim name As String
- Dim temp As New List(Of String)
- Dim bigBrackets As Integer
- Dim doubleQuotationMark As Integer
- Dim brackets As Integer
- Dim escape As Integer
- Dim comma As Integer
- Dim stringContent As String
- For Each c As String In json
- Dim exegesis As Integer
- If c = "/" Then
- exegesis += 1
- Continue For
- ElseIf exegesis = 1 Then
- temp.Add("/")
- exegesis = 0
- End If
- If exegesis >= 2 Then
- If c = vbCr Or c = vbLf Then
- exegesis = 0
- Else
- Continue For
- End If
- End If
- If doubleQuotationMark = 0 Then
- '未在字符串内时
- Select Case c
- Case "["
- brackets += 1
- If brackets > 1 OrElse bigBrackets > 0 Then
- '子嵌套记忆
- temp.Add(c)
- End If
- Case "]"
- brackets -= 1
- If brackets > 1 OrElse bigBrackets > 0 OrElse (brackets = 1 AndAlso bigBrackets = 0) Then
- temp.Add(c)
- End If
- Case "{"
- bigBrackets += 1
- temp.Add(c)
- Case "}"
- bigBrackets -= 1
- temp.Add(c)
- Case """"
- If brackets = 1 AndAlso bigBrackets = 0 Then
- '第一层嵌套内
- doubleQuotationMark += 1
- temp.Add(c)
- ElseIf brackets > 1 OrElse bigBrackets > 0 Then
- temp.Add(c)
- End If
- Case ","
- If bigBrackets = 0 AndAlso brackets = 1 Then
- name = comma
- comma += 1
- If temp.Count > 0 Then
- stringContent = Join(temp.ToArray, "")
- temp.Clear()
- node.Add(name, New HarryNode(name, stringContent, sourceNode))
- Else
- 'null
- node.Add(name, New HarryNode(name, Nothing, sourceNode))
- End If
- Else
- temp.Add(c)
- End If
- Case Else
- If bigBrackets > 1 Or Regex.IsMatch(c, "\S", RegexOptions.Singleline) Then
- temp.Add(c)
- End If
- End Select
- ElseIf brackets = 1 AndAlso bigBrackets = 0 Then
- '第一层嵌套内
- '在字符串内
- Select Case c
- Case """"
- temp.Add(c)
- If escape = 1 Then
- '转义"
- escape = 0
- Else
- doubleQuotationMark = 0
- End If
- Case "\"
- escape += 1
- If escape > 1 Then
- '转义\
- temp.Add(c)
- escape = 0
- End If
- Case "n"
- If escape = 1 Then
- '转义换行
- temp.Add(vbCrLf)
- escape = 0
- Else
- temp.Add(c)
- End If
- Case "b"
- If escape = 1 Then
- temp.Add(Chr(8))
- escape = 0
- Else
- temp.Add(c)
- End If
- Case "f"
- If escape = 1 Then
- temp.Add(Chr(12))
- escape = 0
- Else
- temp.Add(c)
- End If
- Case "t"
- If escape = 1 Then
- temp.Add(vbTab)
- escape = 0
- Else
- temp.Add(c)
- End If
- Case Else
- escape = 0
- temp.Add(c)
- End Select
- End If
- Next
- name = comma
- If temp.Count > 0 Then
- '非字符串
- stringContent = Join(temp.ToArray, "")
- temp.Clear()
- node.Add(name, New HarryNode(name, stringContent, sourceNode))
- Else
- 'null
- node.Add(name, New HarryNode(name, Nothing, sourceNode))
- End If
- Return node
- End Function
- Public Shared Function GetBool(value As String) As Boolean
- If value.ToLower = "false" OrElse value = "0" Then
- Return False
- End If
- Return True
- End Function
- Public Sub New(name As String, json As String, Optional parent As HarryNode = Nothing)
- nodeName = name
- parentNode = parent
- JsonToValue(json)
- End Sub
- Public Sub New(name As String, nodeValue As Object, type As NodeTypeEnum, Optional parent As HarryNode = Nothing)
- nodeName = name
- nodeType = type
- parentNode = parent
- Value = nodeValue
- End Sub
- End Class