xml поле в JSON данных - PullRequest
       0

xml поле в JSON данных

1 голос
/ 24 февраля 2020

Я хотел бы знать, как читать и анализировать поле xml, которое является частью данных JSON.

root
 |-- fields: struct (nullable = true)
 |    |-- custid: string (nullable = true)
 |    |-- password: string (nullable = true)
 |    |-- role: string (nullable = true)
 |    |-- xml_data: string (nullable = true)

, и что в xml_data есть много столбцов. Допустим, эти поля внутри XML_data похожи на вложенные столбцы данных «FIELDS». Итак, как разобрать все столбцы "custid", "password", "role", "xml_data.refid", "xml_data.refname", все они в один фрейм данных.

Короткий вопрос, как проанализировать и прочитать xml данные, которые находятся внутри JSON файла в виде строкового содержимого.

1 Ответ

1 голос
/ 25 февраля 2020

Это немного хитро, но этого можно достичь в следующих простых шагах:

  • Разбор XML Строка в JSON Строка и добавление идентификатора к нему (в нижнем регистре: '')
  • Конвертировать весь массив данных в набор данных JSON String
  • Карта на наборе данных String, создайте действительный JSON, указав идентификатор, добавленный на шаге 1.
  • Преобразовать набор данных из Действительный JSON для Dataframe, вот и все !!

Вот и все !!

import spark.implicits._
import scala.xml.XML
import org.json4s.Xml.toJson
import org.json4s.jackson.JsonMethods.{compact, render}
import org.apache.spark.sql.functions.udf

val rdd = spark
  .sparkContext
  .parallelize(Seq("{\"fields\":{\"custid\":\"custid\",\"password\":\"password\",\"role\":\"role\",\"xml_data\":\"<person><refname>Test Person</refname><country>India</country></person>\"}}"))

val df = spark.read.json(rdd.toDS())

val xmlToJsonUDF = udf { xmlString: String =>
  val xml = XML.loadString(xmlString)
  s"''${compact(render(toJson(xml)))}''"
}

val xmlParsedDf = df.withColumn("xml_data", xmlToJsonUDF(col("fields.xml_data")))
val jsonDs = xmlParsedDf.toJSON

val validJsonDs = jsonDs.map(value => {
  val startIndex = value.indexOf("\"''")
  val endIndex = value.indexOf("''\"")
  val data = value.substring(startIndex, endIndex).replace("\\", "")
  val validJson = s"${value.substring(0, startIndex)}$data${value.substring(endIndex)}"
    .replace("\"''", "")
    .replace("''\"", "")
  validJson
})

val finalDf = spark.read.json(validJsonDs)
finalDf.show(10)
finalDf.printSchema()

finalDf
  .select("fields.custid", "fields.password", "fields.role", "fields.xml_data", "xml_data.person.refname", "xml_data.person.country")
  .show(10)

Вход и выход:

//Input
{"fields":{"custid":"custid","password":"password","role":"role","xml_data":"<person><refname>Test Person</refname><country>India</country></person>"}}

//Final Dataframe
+--------------------+--------------------+
|              fields|            xml_data|
+--------------------+--------------------+
|[custid, password...|[[India, Test Per...|
+--------------------+--------------------+

//Final Dataframe Schema
root
|-- fields: struct (nullable = true)
|    |-- custid: string (nullable = true)
|    |-- password: string (nullable = true)
|    |-- role: string (nullable = true)
|    |-- xml_data: string (nullable = true)
|-- xml_data: struct (nullable = true)
|    |-- person: struct (nullable = true)
|    |    |-- country: string (nullable = true)
|    |    |-- refname: string (nullable = true)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...