如何在Kotlin中用GSON解析这样的json?

rbpvctlc  于 2022-12-04  发布在  Kotlin
关注(0)|答案(2)|浏览(172)

我有这样JSON对象

{
"codemap":{
"codeOfItem1":"titleOfItem1",
"codeOfItem2":"titleOfItem2",
"codeOfItem3":"titleOfItem3",
"codeOfItem4":"titleOfItem4"
},
"items":{
"titleOfItem1":{
"attribute1":"value1",
"atttribute2":{
"subattr1":"value1_of_subattr1_for_item1",
"subattr2":"value1_of_subattr2_for_item1"
}
},
"titleOfItem2":{
"attribute1":"value2",
"atttribute2":{
"subattr1":"value1_of_subattr1_for_item2",
"subattr2":"value1_of_subattr2_for_item2"
}
},
"titleOfItem3":{
"attribute1":"value2",
"atttribute2":{
"subattr1":"value1_of_subattr1_for_item3",
"subattr2":"value1_of_subattr2_for_item3"
}
},
"titleOfItem4":{
"attribute1":"value2",
"atttribute2":{
"subattr1":"value1_of_subattr1_for_item4",
"subattr2":"value1_of_subattr2_for_item4"
}
}
}
}

如何在Kotlin中使用GSON解析它?(问题是像titleOfItemXXX这样的字符串在codemapMap中既是值,又是itemsMap中的键名
我不太喜欢像How to parse this Json with no object name那样完全手动方式
更新:我不想得到这样的方案(这是从Kotlin-to-JSON Android Studio插件)

import com.google.gson.annotations.SerializedName

data class x1(
    @SerializedName("codemap")
    val codemap: Codemap,
    @SerializedName("items")
    val items: Items
) {
    data class Codemap(
        @SerializedName("codeOfItem1")
        val codeOfItem1: String, // titleOfItem1
        @SerializedName("codeOfItem2")
        val codeOfItem2: String, // titleOfItem2
        @SerializedName("codeOfItem3")
        val codeOfItem3: String, // titleOfItem3
        @SerializedName("codeOfItem4")
        val codeOfItem4: String // titleOfItem4
    )

    data class Items(
        @SerializedName("titleOfItem1")
        val titleOfItem1: TitleOfItem1,
        @SerializedName("titleOfItem2")
        val titleOfItem2: TitleOfItem2,
        @SerializedName("titleOfItem3")
        val titleOfItem3: TitleOfItem3,
        @SerializedName("titleOfItem4")
        val titleOfItem4: TitleOfItem4
    ) {
        data class TitleOfItem1(
            @SerializedName("attribute1")
            val attribute1: String, // value1
            @SerializedName("atttribute2")
            val atttribute2: Atttribute2
        ) {
            data class Atttribute2(
                @SerializedName("subattr1")
                val subattr1: String, // value1_of_subattr1_for_item1
                @SerializedName("subattr2")
                val subattr2: String // value1_of_subattr2_for_item1
            )
        }

        data class TitleOfItem2(
            @SerializedName("attribute1")
            val attribute1: String, // value2
            @SerializedName("atttribute2")
            val atttribute2: Atttribute2
        ) {
            data class Atttribute2(
                @SerializedName("subattr1")
                val subattr1: String, // value1_of_subattr1_for_item2
                @SerializedName("subattr2")
                val subattr2: String // value1_of_subattr2_for_item2
            )
        }

        data class TitleOfItem3(
            @SerializedName("attribute1")
            val attribute1: String, // value2
            @SerializedName("atttribute2")
            val atttribute2: Atttribute2
        ) {
            data class Atttribute2(
                @SerializedName("subattr1")
                val subattr1: String, // value1_of_subattr1_for_item3
                @SerializedName("subattr2")
                val subattr2: String // value1_of_subattr2_for_item3
            )
        }

        data class TitleOfItem4(
            @SerializedName("attribute1")
            val attribute1: String, // value2
            @SerializedName("atttribute2")
            val atttribute2: Atttribute2
        ) {
            data class Atttribute2(
                @SerializedName("subattr1")
                val subattr1: String, // value1_of_subattr1_for_item4
                @SerializedName("subattr2")
                val subattr2: String // value1_of_subattr2_for_item4
            )
        }
    }
}

因为我并不真正知道我将拥有多少项以及它们在生产中将使用哪些名称。

hc2pp10m

hc2pp10m1#

我认为您希望在模式中使用动态命名的属性。在本例中,将其声明为Map

data class Schema(val codemap: Map<String, String>, val items: Map<String, Item>) {
    data class Item(val attribute1: String, val atttribute2: Attr2) {
        data class Attr2(val subattr1: String, val subattr2: String)
    }
}

fun gsonDemo() {
    val json = """
        {
        "codemap":{
        "codeOfItem1":"titleOfItem1",
        "codeOfItem2":"titleOfItem2",
        "codeOfItem3":"titleOfItem3",
        "codeOfItem4":"titleOfItem4"
        },
        "items":{
        "titleOfItem1":{
        "attribute1":"value1",
        "atttribute2":{
        "subattr1":"value1_of_subattr1_for_item1",
        "subattr2":"value1_of_subattr2_for_item1"
        }
        },
        "titleOfItem2":{
        "attribute1":"value2",
        "atttribute2":{
        "subattr1":"value1_of_subattr1_for_item2",
        "subattr2":"value1_of_subattr2_for_item2"
        }
        },
        "titleOfItem3":{
        "attribute1":"value2",
        "atttribute2":{
        "subattr1":"value1_of_subattr1_for_item3",
        "subattr2":"value1_of_subattr2_for_item3"
        }
        },
        "titleOfItem4":{
        "attribute1":"value2",
        "atttribute2":{
        "subattr1":"value1_of_subattr1_for_item4",
        "subattr2":"value1_of_subattr2_for_item4"
        }
        }
        }
        }
    """.trimIndent()

    val obj = Gson().fromJson(json, Schema::class.java)
    println(obj.items[obj.codemap["codeOfItem3"]]?.atttribute2?.subattr1) // print value1_of_subattr1_for_item3
}

请注意,如果缺少某些属性,Gson不会失败,因此所有属性的值都可以是null,尽管它们被声明为不可空

deyfvvtc

deyfvvtc2#

看起来我忘记了简单的方法:(
工作答案:

data class TopLevel (
    @SerializedName("codemap")
    val codemap: Map<String, String>,
    @SerializedName("items")
    val items: Map<String, Item>
)

data class Item (
    @SerializedName("attribute1")
    val attribute1: Attribute1,
    @SerializedName("attribute2")
    val attribute2: Attribute2
)

data class Attribute2 (
    @SerializedName("subattr1")
    val subattr1: String,
    @SerializedName("subattr2")
    val subattr1: String
)

enum class Attribute1 {
    @SerializedName("DarkSide")
    DarkSide,
    @SerializedName("LightSide")
    LightSide
}

var gson: Gson = Gson()

val str=... //string with source JSON
val result = gson.fromJson(str, TopLeve::class.java)

一切似乎都工作正常。

相关问题