【vb.net】轻量JSON序列及反序列化
这个代码写的有点时间了,可能有点小bug,欢迎评论区反馈
作用是将Json文本转化成一个HarryNode类进行相关的Json对象处理或者读取,也可以将一个HarryNode对象用ToString变为Json文本。
举例:
1、读取节点数据
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)
2、创建新Json节点,写入数据并输出文本
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!""}")
文档
1、方法和函数
New
构造函数
| name | String | 节点的名字(对于根节点此项没啥意义) |
| json | String | 要解析构造的JSON串 |
| parent | HarryNode | 实例的父节点 |
| name | String | 节点的名字(对于根节点此项没啥意义) |
| nodeValue | Object | 节点VB.NET对象值 |
| type | NodeTypeEnum | 节点值的类型 |
| parent | HarryNode | 实例的父节点 |
GetAtt
获得指定路径的VB.NET对象
| path | String | 节点路径 |
| defaultValue | Object | 没有获取到返回的值,默认Nothing |
SetAtt
根据指定路径设置节点值
| path | String | 节点路径 |
| newValue | Object | 节点的值(VB.NET对象) |
| newValueType | NodeTypeEnum | 值的类型 |
| path | String | 节点路径 |
| json | String | 节点的值(JSON字符串) |
ReName
重命名某个节点
| path | String | 节点路径 |
| newName | String | 新名字 |
ToJson
返回JSON字符串,与ToString()等价
GetNode
获得指定路径的HarryNode对象
| path | String | 节点路径 |
AddNode
添加子节点
| path | String | 节点路径 |
| nodeName | String | 子节点名 |
| nodeJson | String | 子节点JSON串 |
Del
删除指定路径的节点
| path | String | 节点路径 |
Merge
合并两个字典节点;
| node | HarryNode | 要合并的节点 |
GetChildPath
返回一个当前节点子节点名的列表
Add
指定某个节点的数据加一个值
| path | String | 节点路径 |
| addValue | Single | 加数 |
ConAdd
指定某个节点的数据加一个值,但是限制了数的范围
| path | String | 节点路径 |
| addValue | Single | 加数 |
| maxValue | Single | 最大值 |
| minValue | Single | 最小值,默认0 |
Mul
指定某个节点的数据乘一个值
| path | String | 节点路径 |
| addValue | Single | 乘数 |
Power
指定某个节点的数据求次幂
| path | String | 节点路径 |
| addValue | Single | 幂 |
2、属性
Value
当前节点的VB.NET类型值
3、事件
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 HarryNodePublic Shared pathSeparator As String = "."Public Shared outputFormat As Boolean = TruePublic Shared formatRetraction As Integer = 2Public Shared Function MulReplace(source As String, ParamArray args() As String) As StringIf args.Length Mod 2 <> 0 ThenReturn sourceEnd IfFor i As Integer = 0 To UBound(args) Step 2source = Replace(source, args(i), args(i + 1))NextReturn sourceEnd FunctionPublic Shared Function ToEscape(source As String) As StringReturn MulReplace(source, "\", "\\", vbCrLf, "\n", vbTab, "\t", """", "\""", Chr(8), "\b", Chr(12), "\f")End FunctionPublic Enum NodeTypeEnumisNull = 0isString = 1isSingle = 2isDict = 3isList = 4isBool = 5End EnumPublic nodeType As NodeTypeEnumPublic nodeName As StringPublic parentNode As HarryNodePrivate stringValue As StringPrivate singleValue As SinglePrivate boolValue As BooleanPrivate 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 ThenFor i = 0 To node.childNode.Count - 1Dim key = node.childNode.Keys(i)If childNode.ContainsKey(key) ThenchildNode(key).Merge(node.childNode(key))ElsechildNode.Add(key, node.childNode(key))End IfNextEnd IfEnd SubPublic Function GetChildPath() As List(Of String)Dim result As New List(Of String)If nodeType = NodeTypeEnum.isDict Or nodeType = NodeTypeEnum.isList Thenresult.AddRange(childNode.Keys)Elseresult.Add(nodeName)End IfReturn resultEnd 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 FunctionPublic Sub Power(path As String, addValue As Single)SetAtt(path, GetAtt(path, 0) ^ addValue, 0)End SubPublic Sub Add(path As String, addValue As Single)SetAtt(path, GetAtt(path, 0) + addValue, 0)End SubPublic Sub ConAdd(path As String, addValue As Single, maxValue As Single, Optional minValue As Single = 0)Dim newValue As Single = GetAtt(path, 0) + addValueIf newValue > maxValue ThennewValue = maxValueEnd IfIf newValue < minValue ThennewValue = minValueEnd IfSetAtt(path, newValue, 0)End SubPublic Sub Mul(path As String, addValue As Single)SetAtt(path, GetAtt(path, 0) * addValue, 0)End SubPublic Sub AddNode(path As String, nodeName As String, nodeJson As String)Dim paths() As String = path.Split(pathSeparator)Dim p As StringDim node As HarryNode = MeFor i As Integer = 0 To UBound(paths) - 1p = paths(i)Select Case node.nodeTypeCase NodeTypeEnum.isDict, NodeTypeEnum.isListIf node.nodeType = NodeTypeEnum.isList Thenp = Int(Val(p))End IfIf Not node.childNode.ContainsKey(p) Thennode.childNode.Add(p, New HarryNode(p, "{}", Me))End IfCase Elsenode.nodeType = NodeTypeEnum.isDictnode.childNode = New Dictionary(Of String, HarryNode)If Not node.childNode.ContainsKey(p) Thennode.childNode.Add(p, New HarryNode(p, "{}", Me))End IfEnd Selectnode = node.childNode(p)Nextp = paths.LastSelect Case node.nodeTypeCase NodeTypeEnum.isDict, NodeTypeEnum.isListIf node.nodeType = NodeTypeEnum.isList Thenp = Int(Val(p))End IfIf Not node.childNode.ContainsKey(p) Thennode.childNode.Add(p, New HarryNode(p, "{}", Me))End IfCase Elsenode.nodeType = NodeTypeEnum.isDictnode.childNode = New Dictionary(Of String, HarryNode)If Not node.childNode.ContainsKey(p) Thennode.childNode.Add(p, New HarryNode(p, "{}", Me))End IfEnd SelectIf Not node.childNode.ContainsKey(p) Thennode.childNode.Add(p, New HarryNode(nodeName, nodeJson, Me))Elsenode.childNode(p) = New HarryNode(nodeName, nodeJson, Me)End IfEnd SubPublic Sub Del(path As String)Dim paths() As String = path.Split(pathSeparator)Dim p As StringDim node As HarryNode = MeFor i As Integer = 0 To UBound(paths) - 1p = paths(i)Select Case node.nodeTypeCase NodeTypeEnum.isDict, NodeTypeEnum.isListIf node.nodeType = NodeTypeEnum.isList Thenp = Int(Val(p))End IfIf Not node.childNode.ContainsKey(p) ThenReturnEnd IfCase Elsenode.nodeType = NodeTypeEnum.isDictnode.childNode = New Dictionary(Of String, HarryNode)If Not node.childNode.ContainsKey(p) ThenReturnEnd IfEnd Selectnode = node.childNode(p)Nextp = paths.LastSelect Case node.nodeTypeCase NodeTypeEnum.isDict, NodeTypeEnum.isListIf node.nodeType = NodeTypeEnum.isList Thenp = Int(Val(p))End IfIf Not node.childNode.ContainsKey(p) ThenReturnEnd IfCase Elsenode.nodeType = NodeTypeEnum.isDictnode.childNode = New Dictionary(Of String, HarryNode)If Not node.childNode.ContainsKey(p) ThenReturnEnd IfEnd Selectnode.childNode.Remove(p)End SubPublic Function GetAtt(path As String, Optional defaultValue As Object = Nothing) As ObjectIf path = "" ThenReturn ValueEnd IfDim paths() As String = path.Split(pathSeparator)Dim node As HarryNode = MeFor Each p As String In pathsSelect Case node.nodeTypeCase NodeTypeEnum.isDict, NodeTypeEnum.isListIf node.childNode.ContainsKey(p) Thennode = node.childNode(p)ElseReturn defaultValueEnd IfCase ElseReturn defaultValueEnd SelectNextReturn node.ValueEnd FunctionPublic Function GetNode(path As String) As HarryNodeIf path = "" ThenReturn MeEnd IfDim p As StringDim paths() As String = path.Split(pathSeparator)Dim node As HarryNode = MeFor i As Integer = 0 To UBound(paths) - 1p = paths(i)Select Case node.nodeTypeCase NodeTypeEnum.isDict, NodeTypeEnum.isListIf node.childNode.ContainsKey(p) Thennode = node.childNode(p)ElseReturn New HarryNode("", "", Me)End IfCase ElseReturn New HarryNode("", "", Me)End SelectNextIf node.childNode IsNot Nothing AndAlso node.childNode.ContainsKey(paths.Last) ThenReturn node.childNode(paths.Last)End IfReturn New HarryNode(paths.Last, String.Format("""{0}""", paths.Last), Me)End FunctionPublic 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 StringDim node As HarryNode = MeFor i As Integer = 0 To UBound(paths) - 1p = paths(i)Select Case node.nodeTypeCase NodeTypeEnum.isDict, NodeTypeEnum.isListIf node.nodeType = NodeTypeEnum.isList Thenp = Int(Val(p))End IfIf Not node.childNode.ContainsKey(p) Thennode.childNode.Add(p, New HarryNode(p, "{}", Me))End IfCase Elsenode.nodeType = NodeTypeEnum.isDictnode.childNode = New Dictionary(Of String, HarryNode)If Not node.childNode.ContainsKey(p) Thennode.childNode.Add(p, New HarryNode(p, "{}", Me))End IfEnd Selectnode = node.childNode(p)Nextp = paths.LastSelect Case node.nodeTypeCase NodeTypeEnum.isDict, NodeTypeEnum.isListIf node.nodeType = NodeTypeEnum.isList Thenp = Int(Val(p))End IfIf Not node.childNode.ContainsKey(p) Thennode.childNode.Add(p, New HarryNode(p, newValue, newValueType, Me))End IfCase Elsenode.nodeType = NodeTypeEnum.isDictnode.childNode = New Dictionary(Of String, HarryNode)If Not node.childNode.ContainsKey(p) Thennode.childNode.Add(p, New HarryNode(p, newValue, newValueType, Me))End IfEnd Selectnode.childNode(p).Value = newValueRaiseEvent NodeContentChangeLater(path, node.childNode(p).Value, node.nodeType)End SubPublic Sub ReName(path As String, newName As String)Dim paths() As String = path.Split(pathSeparator)Dim p As StringDim node As HarryNode = MeFor i As Integer = 0 To UBound(paths) - 1p = paths(i)Select Case node.nodeTypeCase NodeTypeEnum.isDict, NodeTypeEnum.isListIf node.nodeType = NodeTypeEnum.isList Thenp = Int(Val(p))End IfIf Not node.childNode.ContainsKey(p) Thennode.childNode.Add(p, New HarryNode(p, "{}", Me))End IfCase Elsenode.nodeType = NodeTypeEnum.isDictnode.childNode = New Dictionary(Of String, HarryNode)If Not node.childNode.ContainsKey(p) Thennode.childNode.Add(p, New HarryNode(p, "{}", Me))End IfEnd Selectnode = node.childNode(p)Nextp = paths.LastSelect Case node.nodeTypeCase NodeTypeEnum.isDict, NodeTypeEnum.isListIf node.nodeType = NodeTypeEnum.isList Thenp = Int(Val(p))End IfIf node.childNode.ContainsKey(p) Then' 修改node.childNode.Add(newName, New HarryNode(newName, node.childNode(p).ToJson, Me))node.childNode.Remove(p)End IfCase Elsenode.nodeType = NodeTypeEnum.isDictnode.childNode = New Dictionary(Of String, HarryNode)If node.childNode.ContainsKey(p) Thennode.childNode.Add(newName, New HarryNode(newName, node.childNode(p).ToJson, Me))node.childNode.Remove(p)End IfEnd SelectEnd SubPublic Sub SetAtt(path As String, json As String)RaiseEvent NodeContentChangeBeforeFromJson(path, json)Dim paths() As String = path.Split(pathSeparator)Dim p As StringDim node As HarryNode = MeFor i As Integer = 0 To UBound(paths) - 1p = paths(i)Select Case node.nodeTypeCase NodeTypeEnum.isDict, NodeTypeEnum.isListIf node.nodeType = NodeTypeEnum.isList Thenp = Int(Val(p))End IfIf Not node.childNode.ContainsKey(p) Thennode.childNode.Add(p, New HarryNode(p, "{}", Me))End IfCase Elsenode.nodeType = NodeTypeEnum.isDictnode.childNode = New Dictionary(Of String, HarryNode)If Not node.childNode.ContainsKey(p) Thennode.childNode.Add(p, New HarryNode(p, "{}", Me))End IfEnd Selectnode = node.childNode(p)Nextp = paths.LastSelect Case node.nodeTypeCase NodeTypeEnum.isDict, NodeTypeEnum.isListIf node.nodeType = NodeTypeEnum.isList Thenp = Int(Val(p))End IfIf Not node.childNode.ContainsKey(p) Thennode.childNode.Add(p, New HarryNode(p, "{}", Me))End IfCase Elsenode.nodeType = NodeTypeEnum.isDictnode.childNode = New Dictionary(Of String, HarryNode)If Not node.childNode.ContainsKey(p) Thennode.childNode.Add(p, New HarryNode(p, "{}", Me))End IfEnd Selectnode.childNode(p).JsonToValue(json)RaiseEvent NodeContentChangeLaterFromJson(path, json)End SubPublic Function ToJson(Optional deep As Integer = 1) As StringIf outputFormat ThenDim deepFormatRetraction = New String(" ", deep * formatRetraction)Dim deepFormatRetractionSub1 = New String(" ", (deep - 1) * formatRetraction)Select Case nodeTypeCase NodeTypeEnum.isStringReturn String.Format("""{0}""", ToEscape(stringValue))Case NodeTypeEnum.isBoolReturn boolValue.ToString.ToLowerCase NodeTypeEnum.isSingleReturn singleValueCase NodeTypeEnum.isDictDim result As New List(Of String)For i As Integer = 0 To childNode.Count - 1result.Add(String.Format(deepFormatRetraction & """{0}"": {1}", childNode.Keys(i), childNode.Values(i).ToJson(deep + 1)))NextReturn String.Format(Replace("{{\n{0}\n{1}}}", "\n", vbCrLf), Join(result.ToArray, "," & vbCrLf), deepFormatRetractionSub1)Case NodeTypeEnum.isListDim result As New List(Of String)For i As Integer = 0 To childNode.Count - 1result.Add(deepFormatRetraction & childNode.Values(i).ToJson(deep + 1))NextReturn String.Format(Replace("[\n{0}\n{1}]", "\n", vbCrLf), Join(result.ToArray, "," & vbCrLf), deepFormatRetractionSub1)Case ElseReturn ""End SelectEnd IfSelect Case nodeTypeCase NodeTypeEnum.isStringReturn String.Format("""{0}""", ToEscape(stringValue))Case NodeTypeEnum.isBoolReturn boolValueCase NodeTypeEnum.isSingleReturn singleValueCase NodeTypeEnum.isDictDim result As New List(Of String)For i As Integer = 0 To childNode.Count - 1result.Add(String.Format("""{0}"":{1}", childNode.Keys(i), childNode.Values(i).ToJson))NextReturn String.Format("{{{0}}}", Join(result.ToArray, ","))Case NodeTypeEnum.isListDim result As New List(Of String)For i As Integer = 0 To childNode.Count - 1result.Add(childNode.Values(i).ToJson)NextReturn String.Format("[{0}]", Join(result.ToArray, ","))Case ElseReturn ""End SelectEnd FunctionPublic Overloads Function ToString() As StringReturn ToJson()End FunctionPublic Property Value() As ObjectGetSelect Case nodeTypeCase NodeTypeEnum.isStringReturn stringValueCase NodeTypeEnum.isBoolReturn boolValueCase NodeTypeEnum.isSingleReturn singleValueCase NodeTypeEnum.isDictReturn childNodeCase NodeTypeEnum.isListReturn childNode.ValuesCase ElseReturn NothingEnd SelectEnd GetSet(value As Object)Select Case nodeTypeCase NodeTypeEnum.isStringstringValue = valueCase NodeTypeEnum.isBoolboolValue = valueCase NodeTypeEnum.isSinglesingleValue = valueCase NodeTypeEnum.isDictchildNode = valueCase NodeTypeEnum.isListDim valueList As List(Of HarryNode) = valuechildNode.Clear()For i As Integer = 0 To valueList.Count - 1childNode.Add(i, valueList(i))NextEnd SelectEnd SetEnd PropertyPublic Sub JsonToValue(json As String)If json Is Nothing ThenReturnEnd Ifjson = Regex.Match(json, "^\s*(.*?)\s*$", RegexOptions.Singleline).Groups(1).ValueIf Regex.IsMatch(json, "^"".*""$", RegexOptions.Singleline) Then'字符串nodeType = NodeTypeEnum.isStringstringValue = json.Substring(1, json.Length - 2)ElseIf Regex.IsMatch(json, "^{.*}$", RegexOptions.Singleline) Then'字典nodeType = NodeTypeEnum.isDictIf json = "{}" OrElse Regex.IsMatch(json, "^\s*\{\s*\}\s*$") ThenchildNode = New Dictionary(Of String, HarryNode)ElsechildNode = GetDict(json, Me)End IfElseIf Regex.IsMatch(json, "^\[.*\]$", RegexOptions.Singleline) Then'列表nodeType = NodeTypeEnum.isListIf json = "[]" OrElse Regex.IsMatch(json, "^\s*\[\s*\]\s*$") ThenchildNode = New Dictionary(Of String, HarryNode)ElsechildNode = GetList(json, Me)End IfElseIf Regex.IsMatch(json, "^[-]{0,1}[\d]*[\.]{0,1}[\d]*$", RegexOptions.Singleline) Then'数值nodeType = NodeTypeEnum.isSinglesingleValue = Val(json)Else'布尔值nodeType = NodeTypeEnum.isBoolboolValue = GetBool(json)End IfEnd SubPublic 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 IntegerDim colon As IntegerDim doubleQuotationMark As IntegerDim brackets As IntegerDim escape As IntegerDim stringContent As StringDim exegesis As IntegerFor 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 = "/" Thenexegesis += 1Continue ForElseIf exegesis = 1 Thentemp.Add("/")exegesis = 0End IfIf exegesis >= 2 ThenIf c = vbCr Or c = vbLf Thenexegesis = 0ElseContinue ForEnd IfEnd IfIf doubleQuotationMark = 0 Then'未在字符串内时Select Case cCase "{"bigBrackets += 1If bigBrackets > 1 OrElse brackets > 0 Then'子嵌套记忆temp.Add(c)End IfCase "}"bigBrackets -= 1If bigBrackets > 1 OrElse brackets > 0 OrElse (bigBrackets = 1 AndAlso brackets = 0) Thentemp.Add(c)End IfCase "["brackets += 1temp.Add(c)Case "]"brackets -= 1temp.Add(c)Case ":"If bigBrackets = 1 AndAlso brackets = 0 Then'第一层嵌套内colon += 1ElseIf bigBrackets > 1 OrElse brackets > 0 Thentemp.Add(c)End IfCase """"If bigBrackets = 1 AndAlso brackets = 0 Then'第一层嵌套内doubleQuotationMark += 1temp.Add(c)ElseIf bigBrackets > 1 OrElse brackets > 0 Thentemp.Add(c)End IfCase ","If colon > 0 AndAlso bigBrackets = 1 AndAlso brackets = 0 Then'非字符串If temp.Count > 0 ThenstringContent = Join(temp.ToArray, "")temp.Clear()node.Add(name, New HarryNode(name, stringContent, sourceNode))Else'nullnode.Add(name, New HarryNode(name, Nothing, sourceNode))End Ifcolon = 0Elsetemp.Add(c)End IfCase ElseIf bigBrackets > 1 Or Regex.IsMatch(c, "\S", RegexOptions.Singleline) Thentemp.Add(c)End IfEnd SelectElseIf bigBrackets = 1 AndAlso brackets = 0 Then'第一层嵌套内'在字符串内Select Case cCase """"temp.Add(c)If escape = 1 Then'转义"escape = 0ElsedoubleQuotationMark = 0If colon = 0 Then'节点名stringContent = Join(temp.ToArray, "")temp.Clear()name = stringContent.Substring(1, stringContent.Length - 2)End IfEnd IfCase "\"escape += 1If escape > 1 Then'转义\temp.Add(c)escape = 0End IfCase "n"If escape = 1 Then'转义换行temp.Add(vbCrLf)escape = 0Elsetemp.Add(c)End IfCase "b"If escape = 1 Thentemp.Add(Chr(8))escape = 0Elsetemp.Add(c)End IfCase "f"If escape = 1 Thentemp.Add(Chr(12))escape = 0Elsetemp.Add(c)End IfCase "t"If escape = 1 Thentemp.Add(vbTab)escape = 0Elsetemp.Add(c)End IfCase Elseescape = 0temp.Add(c)End SelectEnd IfNextIf temp.Count > 0 ThenstringContent = Join(temp.ToArray, "")temp.Clear()node.Add(name, New HarryNode(name, stringContent, sourceNode))Else'nullnode.Add(name, New HarryNode(name, Nothing, sourceNode))End IfReturn nodeEnd FunctionPublic 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 StringDim temp As New List(Of String)Dim bigBrackets As IntegerDim doubleQuotationMark As IntegerDim brackets As IntegerDim escape As IntegerDim comma As IntegerDim stringContent As StringFor Each c As String In jsonDim exegesis As IntegerIf c = "/" Thenexegesis += 1Continue ForElseIf exegesis = 1 Thentemp.Add("/")exegesis = 0End IfIf exegesis >= 2 ThenIf c = vbCr Or c = vbLf Thenexegesis = 0ElseContinue ForEnd IfEnd IfIf doubleQuotationMark = 0 Then'未在字符串内时Select Case cCase "["brackets += 1If brackets > 1 OrElse bigBrackets > 0 Then'子嵌套记忆temp.Add(c)End IfCase "]"brackets -= 1If brackets > 1 OrElse bigBrackets > 0 OrElse (brackets = 1 AndAlso bigBrackets = 0) Thentemp.Add(c)End IfCase "{"bigBrackets += 1temp.Add(c)Case "}"bigBrackets -= 1temp.Add(c)Case """"If brackets = 1 AndAlso bigBrackets = 0 Then'第一层嵌套内doubleQuotationMark += 1temp.Add(c)ElseIf brackets > 1 OrElse bigBrackets > 0 Thentemp.Add(c)End IfCase ","If bigBrackets = 0 AndAlso brackets = 1 Thenname = commacomma += 1If temp.Count > 0 ThenstringContent = Join(temp.ToArray, "")temp.Clear()node.Add(name, New HarryNode(name, stringContent, sourceNode))Else'nullnode.Add(name, New HarryNode(name, Nothing, sourceNode))End IfElsetemp.Add(c)End IfCase ElseIf bigBrackets > 1 Or Regex.IsMatch(c, "\S", RegexOptions.Singleline) Thentemp.Add(c)End IfEnd SelectElseIf brackets = 1 AndAlso bigBrackets = 0 Then'第一层嵌套内'在字符串内Select Case cCase """"temp.Add(c)If escape = 1 Then'转义"escape = 0ElsedoubleQuotationMark = 0End IfCase "\"escape += 1If escape > 1 Then'转义\temp.Add(c)escape = 0End IfCase "n"If escape = 1 Then'转义换行temp.Add(vbCrLf)escape = 0Elsetemp.Add(c)End IfCase "b"If escape = 1 Thentemp.Add(Chr(8))escape = 0Elsetemp.Add(c)End IfCase "f"If escape = 1 Thentemp.Add(Chr(12))escape = 0Elsetemp.Add(c)End IfCase "t"If escape = 1 Thentemp.Add(vbTab)escape = 0Elsetemp.Add(c)End IfCase Elseescape = 0temp.Add(c)End SelectEnd IfNextname = commaIf temp.Count > 0 Then'非字符串stringContent = Join(temp.ToArray, "")temp.Clear()node.Add(name, New HarryNode(name, stringContent, sourceNode))Else'nullnode.Add(name, New HarryNode(name, Nothing, sourceNode))End IfReturn nodeEnd FunctionPublic Shared Function GetBool(value As String) As BooleanIf value.ToLower = "false" OrElse value = "0" ThenReturn FalseEnd IfReturn TrueEnd FunctionPublic Sub New(name As String, json As String, Optional parent As HarryNode = Nothing)nodeName = nameparentNode = parentJsonToValue(json)End SubPublic Sub New(name As String, nodeValue As Object, type As NodeTypeEnum, Optional parent As HarryNode = Nothing)nodeName = namenodeType = typeparentNode = parentValue = nodeValueEnd Sub
End Class
相关文章:
【vb.net】轻量JSON序列及反序列化
这个代码写的有点时间了,可能有点小bug,欢迎评论区反馈 作用是将Json文本转化成一个HarryNode类进行相关的Json对象处理或者读取,也可以将一个HarryNode对象用ToString变为Json文本。 举例: 1、读取节点数据 dim harryNode N…...
【Vue】vue2与netcore webapi跨越问题解决
系列文章 C#底层库–记录日志帮助类 本文链接:https://blog.csdn.net/youcheng_ge/article/details/124187709 文章目录 系列文章前言一、技术介绍二、问题描述三、问题解决3.1 方法一:前端Vue修改3.2 方法二:后端允许Cors跨越访问 四、资源…...
SpringSecurity + jwt + vue2 实现权限管理 , 前端Cookie.set() 设置jwt token无效问题(已解决)
问题描述 今天也是日常写程序的一天 , 还是那个熟悉的IDEA , 还是那个熟悉的Chrome浏览器 , 还是那个熟悉的网站 , 当我准备登录系统进行登录的时候 , 发现会直接重定向到登录页 , 后端也没有报错 , 前端也没有报错 , 于是我得脸上又多了一张痛苦面具 , 紧接着在前端疯狂debug…...
【21】c++设计模式——>装饰模式
装饰模式的定义 装饰模式也可以称为封装模式,所谓的封装就是在原有行为之上进行扩展,并不会改变该行为; 例如网络通信: 在进行网络通信的时候,数据是基于IOS七层或四层网络模型(某些层合并之后就是四层模型…...
【博客707】模版化拆解并获取victoriametrics的metricsql各个元素
golang解析victoriametrics的metricsql 场景: 需要拆解metricsql中的部分元素,比如:rollup function,label filter等需要对语法合法性进行判断,同时拒绝某些查询函数我们需要拆解metricsql并进行改造 使用victoriam…...
nodejs + express 实现 http文件下载服务程序
nodejs express 实现 http文件下载服务程序, 主要包括两个功能:指定目录的文件列表,某个文件的下载。 假设已经安装好 nodejs ; cd /js/node_js ; 安装在当前目录的 node_modules/ npm install express --save npm install express-gene…...
Qt多文本编辑器项目实战
0x00 引言 本文将详细讲解如何使用Qt实现一个多文本编辑器。涉及的话题包括:Qt框架基础、窗体布局、文本编辑、拓展功能等等。 在阅读本文之前,你需要掌握基本的C编程知识和Qt框架的使用方法。 0x01 新建Qt项目 在Qt Creator中,新建一个Q…...
CVE-2017-7529 Nginx越界读取内存漏洞
漏洞概述 当使用Nginx标准模块时,攻击者可以通过发送包含恶意构造range域的header请求,来获取响应中的缓存文件头部信息。在某些配置中,缓存文件头可能包含后端服务器的IP地址或其它敏感信息,从而导致信息泄露。 影响版本 Ngin…...
力扣每日一题136:只出现一次的数字
题目描述: 给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。 示例 1 &#…...
导航栏参考代码
导航栏参考代码 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>导航栏参考代码</title> </head> <body> <table width"858" border"0" align"center"><tr&g…...
区块链(11):java区块链项目之页面部分实现
addPeer.html <!DOCTYPE html> <html> <head><meta charset="utf-8"> <title>java区块链</title><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="styles…...
RootSIFT---SIFT图像特征的扩展
RootSIFT是论文 Three things everyone should know to improve object retrieval - 2012所提出的 A Comparative Analysis of RootSIFT and SIFT Methods for Drowsy Features Extraction - 2020 当比较直方图时,使用欧氏距离通常比卡方距离或Hellinger核时的性能…...
ChatGPT角色扮演教程,Prompt词分享
使用指南 1、可直复制使用 2、可以前往已经添加好Prompt预设的AI系统测试使用 https://ai.idcyli.comhttps://ai.idcyli.com 雅思写作考官 我希望你假定自己是雅思写作考官,根据雅思评判标准,按我给你的雅思考题和对应答案给我评分,并且按…...
zabbix监控——自定义监控内容
目录 自定义监控项步骤 案例 1、明确需要执行的命令 2、创建 zabbix 的监控项配置文件,用于自定义 key,并重启zabbix-agent2 3、.在服务端验证新建的监控项 4、在 Web 页面创建自定义监控项模板 1)创建模板 2)创建监控项 …...
中断机制-中断协商机制、中断方法
4.1 线程中断机制 4.1.1 从阿里蚂蚁金服面试题讲起 Java.lang.Thread下的三个方法: 4.1.2 什么是中断机制 首先,一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止,自己来决定自己的命运,所以,…...
three.js入门 —— 实现第一个3D案例
前言: three.js入门,根据文档实现第一个3D案例 效果图: 代码实现: const scene new THREE.Scene();//创建一个长方体几何对象Geometryconst geometry new THREE.BoxGeometry(100, 100, 100);//创建一个网络基础材质的材质对象…...
《动手学深度学习 Pytorch版》 8.4 循环神经网络
8.4.1 无隐状态的神经网络 对于无隐藏装态的神经网络来说,给定一个小批量样本 X ∈ R n d \boldsymbol{X}\in\mathbb{R}^{n\times d} X∈Rnd,则隐藏层的输出 H ∈ R n h \boldsymbol{H}\in\mathbb{R}^{n\times h} H∈Rnh 通过下式计算: …...
什么是物联网阀控水表?
物联网阀控水表是一种新型的水表,结合了物联网技术和传统水表的功能,可以实现对水的计量、控制和管理。随着人们对水资源的日益重视,物联网阀控水表的应用越来越广泛,为水资源的合理利用和管理提供了有效手段。 物联网阀控水表是由…...
Kafka 开启SASL/SCRAM认证 及 ACL授权(一)认证
Kafka 开启SASL/SCRAM认证 及 ACL授权(一)认证。 kafka安全涉及3部份:传输加密,用户认证与授权,ZK开启ACL(Zookeeper存储了kafka的元数据以及用户信息,默认不开启acl所有用户可改,内网环境机器不对外开放可考虑使用默认不开启ZK ACL)。 官网地址:https://kafka.ap…...
关于智能控制领域中模糊控制算法的概述
智能控制领域中的模糊控制算法是一种基于模糊逻辑的控制策略,它通过对模糊集合的刻画来处理模糊信息,从而获得模糊输出并进行控制。模糊控制算法在实际控制工程中具有良好的应用前景,它不但具有较强的鲁棒性和适应性,而且可以为复…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...
