使用嵌套标记将XML读入Spark RDD,并转换为JSON

时间:2017-08-12 20:27:25

标签: xml scala apache-spark

我有以下xml结构:

<root>
  <items>
    <item>
      <property>1</property>
      <property2>2</property2> 
      <nested-property>
        <property>1</property>
      </nested-property>   
    </item>
  </items>
</root>

我在其Scala API中使用Spark 2.2,并且在本地文件系统(10GB)中有相当大的XML文件。

我的目标是阅读每个元素并进行一些转换并将其转换为 Json ,但结果应与我提供的XML类似。

  
      
  • 关键点是我需要迭代文件而不是逐行,但“按标签标记”,在这种情况下,从标签到下一个

  •   
  • 另一点是我需要读取嵌套的xml标签,因此我不确定this library是否可以帮助我。我的理解是这样的   不读取XML嵌套标签,也只是在使用它   DataFrames,我也更喜欢RDD。有没有办法实现   功能?

  •   

我尝试将其作为文本文件阅读并使用标记项作为分隔符,但它不起作用。它仍然认为断路器是分隔符:

  val spark = SparkSession
    .builder()
    .config("textinputformat.record.delimiter", "</item>")
    .master("local[*]")
    .getOrCreate()


  val documents = spark.sparkContext.textFile("/home/myuser/test-data/Records.xml")
  

如何处理嵌套的XML元素?我该如何访问它们?

     

我不想展平嵌套结构,   我希望将每个XML Row迭代转换为一个单独的JSON文件 - 具有相同的结构。

1 个答案:

答案 0 :(得分:1)

  

问题:如何处理嵌套的XML元素?我将如何访问   它们?

对于展平嵌套结构,您可以使用explode ...

示例:假设我想要每个标题(String type)/ authors(WrappedArray)组合,可以用[11, 12, 13] 实现它:


schema :

root
 |-- title: string (nullable = true)
 |-- author: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- initial: array (nullable = true)
 |    |    |    |-- element: string (containsNull = true)
 |    |    |-- lastName: string (nullable = true)
show()

+--------------------+--------------------+
|               title|              author|
+--------------------+--------------------+
|Proper Motions of...|[[WrappedArray(J,...|
|Catalogue of 2055...|[[WrappedArray(J,...|
|                null|                null|
|Katalog von 3356 ...|[[WrappedArray(J)...|
|Astrographic Cata...|[[WrappedArray(P)...|
|Astrographic Cata...|[[WrappedArray(P)...|
|Results of observ...|[[WrappedArray(H,...|
|      AGK3 Catalogue|[[WrappedArray(W)...|
|Perth 70: A Catal...|[[WrappedArray(E)...|


import org.apache.spark.sql.functions;
DataFrame exploded = src.select(src.col("title"),functions.explode(src.col("author")).as("auth"))
                    .select("title","auth.initial","auth.lastName");
exploded = exploded.select(exploded.col("initial"),
                        exploded.col("title").as("title"),
                        exploded.col("lastName"));

exploded.printSchema

exploded.show


root
 |-- initial: array (nullable = true)
 |    |-- element: string (containsNull = true)
 |-- title: string (nullable = true)
 |-- lastName: string (nullable = true)

+-------+--------------------+-------------+
|initial|               title|     lastName|
+-------+--------------------+-------------+
| [J, H]|Proper Motions of...|      Spencer|
|    [J]|Proper Motions of...|      Jackson|
| [J, H]|Catalogue of 2055...|      Spencer|

示例xml文件

explode