#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|
----- -------
*/