当前位置: 首页 > 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;而且可以为复…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...