【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…...
关于智能控制领域中模糊控制算法的概述
智能控制领域中的模糊控制算法是一种基于模糊逻辑的控制策略,它通过对模糊集合的刻画来处理模糊信息,从而获得模糊输出并进行控制。模糊控制算法在实际控制工程中具有良好的应用前景,它不但具有较强的鲁棒性和适应性,而且可以为复…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
