在 Kotlin 中创建表示嵌套 xml 的 class 的最佳方法是什么

what's best way to create a class representing nested xml in Kotlin

考虑以下 xml 文件

<Dataset>
    <Table1>
        <colA>AAA</colA>
        <colB>BBB</colB>
    </Table1>
    <Table1>
        <colA>aa</colA>
        <colB>bb</colB>
    </Table1>
    <Table2>
        <colX>xxx</colX>
    </Table1>
</Dataset>

构造一个 class 以保存该文件中的记录的最佳方法是什么(使用外部 class 的 ArrayList)?


我试过使用内部 classes,像这样:

class Dataset {
    inner class Table1 {
        var colA:String = ""
        var colB:String = ""
    }
    inner class Table2 {
        var colX:String = "x"
    }
}

问题是 - 当我创建数据集 class 的实例时,我无法在其中设置内部 classes 的属性,即使我可以读取它们(是因为它们没有实例化?) 换句话说,下面代码的输出是 xx 而不是 xOK

val dataset = Dataset()
print("${dataset.Table2().colX}")    //returns x as in the class declaration
dataset.Table2().colX = "OK"
print("${dataset.Table2().colX}")    //returns x, but I want it to return OK

我可以在外部 class 中实例化内部 classes 时设置属性 class:

class Dataset {
    val table1 = Table1()
    val table2 = Table2()
    inner class Table1 {
...

但正如我之前提到的,我使用 ArrayList

追加记录

这意味着(如果我理解正确的话),当我为 Table1 条目创建数据集然后将其附加到 ArrayList 时,我仍然在该数据集中实例化了 dataset.table2,即使它没有被使用

我也可以像这样实例化内部 classes:

table1 = Dataset().Table1()

只要我可以将它们添加到现有的数据集实例中

val dataset = Dataset()
dataset.Table1() = table1    //this bit doesn't work for me :(

总结一下:

1) 关于如何更好地构建数据集的任何想法 class?

2) 如果不是,如何在其外部 class 实例中设置内部 class 的属性?

您对 Table1 和 Table2 的定义只不过是 class 定义,所以是的,您需要参数来表示它们的实例。问题不仅在于它们没有被实例化,而且根本没有它们的属性。

您在需要其他 class 之一时实例化外部 class 副本的想法没有意义。编译器要求您这样做的唯一原因是您在那些 class 定义中使用了关键字 inner。由于它们与 Dataset 没有共享引用,因此它们不需要 inner.

inner的意思是class只能存在于外class的上下文中。 inner class 的好处是它可以直接引用外部 class 的属性,并且您始终知道内部 class 的任何实例都内在地链接到特定的外部 class 的实例。对于像这样的简单层次结构,您不需要任何这些内部 class 功能。

你需要这样的东西:

data class Table1 (var colA: String = "", 
                   var colB: String = "")

data class Table2 (var colX: String = "")

data class DataSet (var table1: Table1? = null,
                    var table2: Table2? = null)

由于您的表格是可选的,因此它们必须可以为空,并且空值表示它是空白的。

在 class 定义中使用 data 让 Kotlin 为您生成 toStringhashcodeequals

您的示例 XML 在数据集中显示了多个 Table1,因此您可能需要将 DataSet 的参数更改为集合,以便能够容纳每种类型的多个表:

data class DataSet (val table1s: MutableList<Table1> = mutableListOf(),
                    val table2s: MutableList<Table2> = mutableListOf())

编辑: 如果您确实需要这些是内部 classes,则必须具有内部 classes 实例的属性。并且您必须始终在实例的上下文中实例化它们 "own" 它。

// This works because the table was instantiated from the dataset that will reference it.
val dataset = DataSet()
dataset.table1 = dataset.Table1() 

// This doesn't work because you can't assign the new DataSet's table to some 
// other DataSet's property.
val dataset = DataSet()
dataset.table1 = DataSet().Table1()