当前位置: 首页 > news >正文

【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

构造函数

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字符串

源码如下:

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序列及反序列化

这个代码写的有点时间了&#xff0c;可能有点小bug&#xff0c;欢迎评论区反馈 作用是将Json文本转化成一个HarryNode类进行相关的Json对象处理或者读取&#xff0c;也可以将一个HarryNode对象用ToString变为Json文本。 举例&#xff1a; 1、读取节点数据 dim harryNode N…...

【Vue】vue2与netcore webapi跨越问题解决

系列文章 C#底层库–记录日志帮助类 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/124187709 文章目录 系列文章前言一、技术介绍二、问题描述三、问题解决3.1 方法一&#xff1a;前端Vue修改3.2 方法二&#xff1a;后端允许Cors跨越访问 四、资源…...

SpringSecurity + jwt + vue2 实现权限管理 , 前端Cookie.set() 设置jwt token无效问题(已解决)

问题描述 今天也是日常写程序的一天 , 还是那个熟悉的IDEA , 还是那个熟悉的Chrome浏览器 , 还是那个熟悉的网站 , 当我准备登录系统进行登录的时候 , 发现会直接重定向到登录页 , 后端也没有报错 , 前端也没有报错 , 于是我得脸上又多了一张痛苦面具 , 紧接着在前端疯狂debug…...

【21】c++设计模式——>装饰模式

装饰模式的定义 装饰模式也可以称为封装模式&#xff0c;所谓的封装就是在原有行为之上进行扩展&#xff0c;并不会改变该行为&#xff1b; 例如网络通信&#xff1a; 在进行网络通信的时候&#xff0c;数据是基于IOS七层或四层网络模型&#xff08;某些层合并之后就是四层模型…...

【博客707】模版化拆解并获取victoriametrics的metricsql各个元素

golang解析victoriametrics的metricsql 场景&#xff1a; 需要拆解metricsql中的部分元素&#xff0c;比如&#xff1a;rollup function&#xff0c;label filter等需要对语法合法性进行判断&#xff0c;同时拒绝某些查询函数我们需要拆解metricsql并进行改造 使用victoriam…...

nodejs + express 实现 http文件下载服务程序

nodejs express 实现 http文件下载服务程序&#xff0c; 主要包括两个功能&#xff1a;指定目录的文件列表&#xff0c;某个文件的下载。 假设已经安装好 nodejs ; cd /js/node_js ; 安装在当前目录的 node_modules/ npm install express --save npm install express-gene…...

Qt多文本编辑器项目实战

0x00 引言 本文将详细讲解如何使用Qt实现一个多文本编辑器。涉及的话题包括&#xff1a;Qt框架基础、窗体布局、文本编辑、拓展功能等等。 在阅读本文之前&#xff0c;你需要掌握基本的C编程知识和Qt框架的使用方法。 0x01 新建Qt项目 在Qt Creator中&#xff0c;新建一个Q…...

CVE-2017-7529 Nginx越界读取内存漏洞

漏洞概述 当使用Nginx标准模块时&#xff0c;攻击者可以通过发送包含恶意构造range域的header请求&#xff0c;来获取响应中的缓存文件头部信息。在某些配置中&#xff0c;缓存文件头可能包含后端服务器的IP地址或其它敏感信息&#xff0c;从而导致信息泄露。 影响版本 Ngin…...

力扣每日一题136:只出现一次的数字

题目描述&#xff1a; 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法来解决此问题&#xff0c;且该算法只使用常量额外空间。 示例 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 当比较直方图时&#xff0c;使用欧氏距离通常比卡方距离或Hellinger核时的性能…...

ChatGPT角色扮演教程,Prompt词分享

使用指南 1、可直复制使用 2、可以前往已经添加好Prompt预设的AI系统测试使用 https://ai.idcyli.comhttps://ai.idcyli.com 雅思写作考官 我希望你假定自己是雅思写作考官&#xff0c;根据雅思评判标准&#xff0c;按我给你的雅思考题和对应答案给我评分&#xff0c;并且按…...

zabbix监控——自定义监控内容

目录 自定义监控项步骤 案例 1、明确需要执行的命令 2、创建 zabbix 的监控项配置文件&#xff0c;用于自定义 key&#xff0c;并重启zabbix-agent2 3、.在服务端验证新建的监控项 4、在 Web 页面创建自定义监控项模板 1&#xff09;创建模板 2&#xff09;创建监控项 …...

中断机制-中断协商机制、中断方法

4.1 线程中断机制 4.1.1 从阿里蚂蚁金服面试题讲起 Java.lang.Thread下的三个方法: 4.1.2 什么是中断机制 首先&#xff0c;一个线程不应该由其他线程来强制中断或停止&#xff0c;而是应该由线程自己自行停止&#xff0c;自己来决定自己的命运&#xff0c;所以&#xff0c;…...

three.js入门 —— 实现第一个3D案例

前言&#xff1a; three.js入门&#xff0c;根据文档实现第一个3D案例 效果图&#xff1a; 代码实现&#xff1a; const scene new THREE.Scene();//创建一个长方体几何对象Geometryconst geometry new THREE.BoxGeometry(100, 100, 100);//创建一个网络基础材质的材质对象…...

《动手学深度学习 Pytorch版》 8.4 循环神经网络

8.4.1 无隐状态的神经网络 对于无隐藏装态的神经网络来说&#xff0c;给定一个小批量样本 X ∈ R n d \boldsymbol{X}\in\mathbb{R}^{n\times d} X∈Rnd&#xff0c;则隐藏层的输出 H ∈ R n h \boldsymbol{H}\in\mathbb{R}^{n\times h} H∈Rnh 通过下式计算&#xff1a; …...

什么是物联网阀控水表?

物联网阀控水表是一种新型的水表&#xff0c;结合了物联网技术和传统水表的功能&#xff0c;可以实现对水的计量、控制和管理。随着人们对水资源的日益重视&#xff0c;物联网阀控水表的应用越来越广泛&#xff0c;为水资源的合理利用和管理提供了有效手段。 物联网阀控水表是由…...

Kafka 开启SASL/SCRAM认证 及 ACL授权(一)认证

Kafka 开启SASL/SCRAM认证 及 ACL授权(一)认证。 kafka安全涉及3部份:传输加密,用户认证与授权,ZK开启ACL(Zookeeper存储了kafka的元数据以及用户信息,默认不开启acl所有用户可改,内网环境机器不对外开放可考虑使用默认不开启ZK ACL)。 官网地址:https://kafka.ap…...

关于智能控制领域中模糊控制算法的概述

智能控制领域中的模糊控制算法是一种基于模糊逻辑的控制策略&#xff0c;它通过对模糊集合的刻画来处理模糊信息&#xff0c;从而获得模糊输出并进行控制。模糊控制算法在实际控制工程中具有良好的应用前景&#xff0c;它不但具有较强的鲁棒性和适应性&#xff0c;而且可以为复…...

两个日期到底差几天?

两个日期到底差几天&#xff1f; 网上搜「两个日期相差几天」&#xff0c;底下问题五花八门&#xff1a;合同从签字日到到期日算不算头尾、请假单跨了周末怎么填、租房从 3 月 1 住到 6 月 30 一共多少天、项目里程碑隔了几年 2 月会不会踩闰年……本质都是一件事&#xff1a;…...

动态光照技术在视觉触觉传感器中的应用与优化

1. 视觉触觉传感器技术概述 视觉触觉传感器&#xff08;Vision-Based Tactile Sensors, VBTS&#xff09;是机器人触觉感知领域的重要技术突破。这类传感器通过光学成像方式捕捉弹性体接触面的微观变形&#xff0c;将机械接触转化为可视化数据。与传统力传感器相比&#xff0c;…...

别再为WinPcap头疼了!手把手教你用SOEM 1.3.1在Windows上搞定EtherCAT主站开发环境

告别WinPcap困扰&#xff1a;SOEM 1.3.1在Windows下的EtherCAT主站开发全攻略 当第一次接触EtherCAT主站开发时&#xff0c;许多工程师都会遇到一个共同的"拦路虎"——WinPcap环境配置。这个看似简单的网络抓包工具&#xff0c;在实际开发中却可能耗费数小时甚至数天…...

开源智能体技术解析:从LangChain到自主抓取,构建自动化工作流

1. 项目概述&#xff1a;从“Awesome”列表看开源智能体生态的演进 最近在梳理一些前沿的自动化工具链时&#xff0c;又翻到了 mergisi/awesome-openclaw-agents 这个仓库。对于长期关注AI Agent&#xff08;智能体&#xff09;和自动化工作流开发的同行来说&#xff0c;这类…...

将HermesAgent项目接入Taotoken的详细配置步骤与注意事项

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 将HermesAgent项目接入Taotoken的详细配置步骤与注意事项 本文旨在为开发者提供一份清晰的指南&#xff0c;帮助你将HermesAgent项…...

手把手教你用三菱FX3U PLC的RS指令和RS2指令与电脑串口调试助手‘对话’

三菱FX3U PLC串口通信实战&#xff1a;从零搭建RS485数据收发系统 第一次接触工业控制系统的串口通信时&#xff0c;我被那些密密麻麻的接线和晦涩的协议参数弄得晕头转向。直到在自动化生产线上亲眼看到PLC通过两根电线与十几台设备稳定通信&#xff0c;才意识到串口技术的精妙…...

XHS-Downloader:小红书内容采集与管理的全栈解决方案

XHS-Downloader&#xff1a;小红书内容采集与管理的全栈解决方案 【免费下载链接】XHS-Downloader 小红书&#xff08;XiaoHongShu、RedNote&#xff09;链接提取/作品采集工具&#xff1a;提取账号发布、收藏、点赞、专辑作品链接&#xff1b;提取搜索结果作品、用户链接&…...

合宙Air153C看门狗芯片:嵌入式系统可靠性的硬件守护方案

1. 项目概述&#xff1a;一颗“小而美”的国产看门狗芯片最近在做一个低功耗的户外监测设备项目&#xff0c;主控用的就是合宙的Air系列MCU。在调试过程中&#xff0c;最让我头疼的就是系统偶尔的“死机”问题。设备部署在野外&#xff0c;不可能每次都跑过去手动重启。正当我琢…...

OpenClaw 小龙虾智能体联动 DeepSeek 大模型部署实操攻略

前置准备 获取小龙虾open claw一键安装包&#xff08;www.totom.top&#xff09;并安装电脑端已成功安装并正常启动OpenClaw&#xff0c;右上角 Gateway 状态显示在线设备网络通畅&#xff0c;可正常访问 DeepSeek 开放平台拥有可接收验证码的手机号 / 微信&#xff0c;用于平…...

基于GitHub Pages与Jekyll的静态博客搭建与深度定制指南

1. 项目概述&#xff1a;一个静态博客的诞生与演进如果你对搭建个人博客感兴趣&#xff0c;或者正在寻找一个轻量、高效、完全可控的线上空间&#xff0c;那么“RyansGhost/RyansGhost.github.io”这个项目仓库&#xff0c;很可能就是你一直在寻找的答案。这不仅仅是一个托管在…...