获取嵌套XML模式的数据框

时间:2019-04-07 15:33:06

标签: xml scala apache-spark dataframe

我试图将具有自定义架构的XML读入数据框,但无法获取值。

我尝试调整rowTag和rootTag,但没有任何效果。

这是我正在使用的架构:

val input = StructType(
    Array(
      StructField("dnum", IntegerType, true),
      StructField("dtype", StringType, true),
      StructField("dname", StringType, true),
      StructField("dloc", StringType, true)))

  val bookschema = StructType(Array(
    StructField("cost", DoubleType, true),
    StructField("details", ArrayType(input, true),
      true),
    StructField("name", StringType, true),
    StructField("num", LongType, true)))

  val bookdataschema = StructType(Array(
    StructField("count", IntegerType, true),
    StructField("lang", StringType, true)))

  val schema = StructType(Array(
    StructField("bookdata", bookdataschema, true),
    StructField("book", bookschema, true)))

这是读取文件的方式:

sqc.read.format("com.databricks.spark.xml")
      .option("rootTag", "books")
      .schema(schema)
      .load(filePath)

示例xml:

<books>
    <bookdata>
        <count>4</count>
        <lang>English</lang>
    </bookdata>
    <book>
        <num>11</num>
        <name>A</name>
        <cost>200.00</cost>
        <details>
            <dnum>1</dnum>
            <dtype>X</dtype>
        </details>
        <details>
            <dnum>5</dnum>
            <dtype>A</dtype>
        </details>
    </book>
    <book>
        <num>12</num>
        <name>B</name>
        <cost>300.00</cost>
        <details>
            <dnum>2</dnum>
            <dtype>Y</dtype>

        </details>
    </book>
</books>

我必须着手将个别书的details标记内的一些其他列合并在一起。但是如何读取数据帧中的当前数据,使其具有条目的所有行。当我尝试使用“ books”作为rowTag读取它时,它仅在dataframe中返回1行,其中包含bookdata值和最后一个book值。

+-----------+------------------------------------------+
|bookdata   |book                                      |
+-----------+------------------------------------------+
|[4,English]|[300.0,WrappedArray([2,Y,null,null]),B,12]|
+-----------+------------------------------------------+

我现在只关心book标签的细节,因为我需要在细节中附加一些嵌套的标签,但是在将DF写入XML时,最终的输出文件也必须具有bookdata数据。我应该如何解决?

1 个答案:

答案 0 :(得分:0)

您可以加载2个数据框:一个包含if (input.indexOf("#") === 0 || input.indexOf(" #") >= 0) 数据,另一个包含book

bookdata