1

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": {}

そして、ここに私のクラスがあります:

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
...
4

1 に答える 1

1

あなたが説明しているように、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、ニーズに合わせて関数を変更できます。

お役に立てれば。

于 2013-09-25T03:02:22.887 に答える