Извлекать фрейм данных для вложенной схемы XML

#xml #scala #apache-spark #dataframe

#xml #scala #apache-spark #фрейм данных

Вопрос:

Я пытаюсь прочитать 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» в качестве тега строки, он возвращает только 1 строку в фрейме данных со значением bookdata и последним значением книги.

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

На данный момент меня просто интересуют детали тега book, потому что мне нужно добавить некоторые вложенные теги внутри деталей, но конечный выходной файл также должен содержать данные bookdata при записи DF в XML. Как я должен это решить?

Ответ №1:

Вы можете загрузить 2 фрейма данных: один, содержащий ваши book данные, и один ваш bookdata :

 val df = spark.read.format("com.databricks.spark.xml")
      .option("rootTag", "books")
      .option("rowTag", "book")
      .schema(bookschema)
      .load(filePath)

df.show()
/*
df has the books data:
 ----- -------------------- ---- --- 
| cost|             details|name|num|
 ----- -------------------- ---- --- 
|200.0|[[1, X,,], [5, A,,]]|   A| 11|
|300.0|          [[2, Y,,]]|   B| 12|
 ----- -------------------- ---- --- 
*/

val df2 = spark.read.format("com.databricks.spark.xml")
      .option("rootTag", "books")
      .option("rowTag", "bookdata")
      .schema(bookdataschema)
      .load(filePath)

df2.show()
/*
df2 has the bookdata data:
 ----- ------- 
|count|   lang|
 ----- ------- 
|    4|English|
 ----- ------- 
*/