如何从 JSON 字符串中删除空数组和空列表?
我使用 vb.net 和 json.net 来实现此目的,但 json.net 无法从 JSON 字符串中删除空数组。我的 JSON 字符串是这样的:
{
"jsonrpc": "2.0",
"id": 1,
"token": "tikenname",
"method": "task.run",
"params": {
"commandList": [{
"method": "Users.new",
"params": {
"userIds": "userid",
"details": {
"credentials": {
"userName": "user",
"password": "pass"
},
"data": {
"rights": {},
"quota": {
"daily": {
"limit": {}
},
"weekly": {
"limit": {}
},
"monthly": {
"limit": {}
}
},
"wwwFilter": {}
},
"autoLogin": {
"addresses": {},
"addressGroup": {}
},
"vpnAddress": {},
"groups": {}
}
}
},
{
"method": "set.save"
}
]
}
}
例如,我想从字符串中删除此部分
"data": {
"rights": {},
"quota": {
"daily": {
"limit": {}
},
"weekly": {
"limit": {}
},
"monthly": {
"limit": {}
}
},
"wwwFilter": {}
},
"autoLogin": {
"addresses": {},
"addressGroup": {}
},
"vpnAddress": {},
"groups": {}
这是我的类(class):
Public Class Account
Public Property jsonrpc As String
Public Property id As Integer
Public Property token As String
Public Property method As String
Public Property params As New AccountSetParams
End Class
Public Class AccountSetParams
Public Property commandList As New List(Of AccountSetCommandlist)
End Class
Public Class AccountSetCommandlist
Public Property method As String
Public Property params As New AccountSetUserDetails
End Class
Public Class AccountSetUserDetails
Public Property userIds() As String
Public Property details As New AccountSetDetails
Public Property domainId As String
End Class
Public Class AccountSetDetails
Public Property credentials As New AccountSetCredentials
Public Property fullName As String
Public Property data As New AccountSetData
Public Property autoLogin As New AccountSetAutologin
Public Property vpnAddress As New AccountSetVpnaddress
Public Property groups() As New AccountSetGroup
End Class
...
最佳答案
看起来 Json.Net 并没有提供一种简单的方法来排除您所描述的空列表或数组。从技术上讲,您要排除的大多数对象都不是空的:它们包含其他空的对象[包含其他对象...]。
因此,要实现此目的,您需要使用递归下降来过滤掉“无用”信息。我认为最好的方法可能是首先将对象图加载到 JObject
(或 JArray
)中,然后递归地将非空元素复制到新的 JObject
(或 JArray
),从最深的层次向上工作。然后,您可以序列化该副本以获得所需的精简 JSON。这种方法将允许您以通用方式处理任何对象结构。
这是一个可以解决问题的函数:
Function RemoveEmptyChildren(token As JToken) As JToken
If token.Type = JTokenType.Object Then
Dim copy As JObject = New JObject()
For Each prop As JProperty In token.Children(Of JProperty)()
Dim child As JToken = prop.Value
If child.HasValues Then
child = RemoveEmptyChildren(child)
End If
If Not IsEmpty(child) Then
copy.Add(prop.Name, child)
End If
Next
Return copy
ElseIf token.Type = JTokenType.Array Then
Dim copy As JArray = New JArray()
For Each child As JToken In token.Children()
If child.HasValues Then
child = RemoveEmptyChildren(child)
End If
If Not IsEmpty(child) Then
copy.Add(child)
End If
Next
Return copy
End If
Return token
End Function
Function IsEmpty(token As JToken) As Boolean
Return (token.Type = JTokenType.Array And Not token.HasValues) Or
(token.Type = JTokenType.Object And Not token.HasValues) Or
(token.Type = JTokenType.String And token.ToString() = String.Empty) Or
(token.Type = JTokenType.Null)
End Function
这是一个演示如何使用该函数的简短示例:
Dim jsonString As String = _
"{" + _
"""Int"" : 1," + _
"""String"" : ""Foo""," + _
"""EmptyString"" : """"," + _
"""EmptyArray"" : []," + _
"""EmptyObject"" : {}," + _
"""NullValue"" : null," + _
"""ArrayOfEmptyChildren"" : [ [], {}, """", null ]," + _
"""ChildObjectWithEmptyValues"" : {" + _
"""Array"" : []," + _
"""Object"" : {}," + _
"""Null"" : null," + _
"""String"" : """"" + _
"}," + _
"""Boolean"" : true" + _
"}"
Dim token As JToken = RemoveEmptyChildren(JToken.Parse(jsonString))
Console.WriteLine(token.ToString(Formatting.Indented))
这是上面示例的输出。请注意,仅保留非空信息。
{
"Int": 1,
"String": "Foo",
"Boolean": true
}
注意:如果您从对象而不是 JSON 字符串开始,您仍然可以使用此函数。只需将上面示例中的 JToken.Parse(jsonString)
替换为 JToken.FromObject(yourObject)
。
此外,如果您想更改从输出中删除或不删除的内容,您可以修改 IsEmpty
函数以满足您的需求。
希望这有帮助。
关于vb.net - 从 JSON 请求字符串中删除空数组/列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18939274/