Scala字符串解析器

时间:2018-03-22 00:31:12

标签: xml scala apache-spark

我在S3中有一个XML文件包含我的表的Schema,名为sample:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<DATA  CHARSET="UTF8" DELIMITER="\t">
<COLUMNS>
<COLUMN DATA_PRECISION="10" DATA_SCALE="0" DATA_TYPE="NUMBER"  ID="APPLICATION_ID" />
<COLUMN DATA_LENGTH="40" DATA_TYPE="VARCHAR2" ID="DESCRIPTIVE_FLEXFIELD_NAME"/>
<COLUMN DATA_LENGTH="30" DATA_TYPE="VARCHAR2" ID="LANGUAGE"/>
<COLUMN DATA_PRECISION="15" DATA_SCALE="0" DATA_TYPE="NUMBER" ID="CREATED_BY" />
<COLUMN DATA_PRECISION="10" DATA_SCALE="0" DATA_TYPE="NUMBER" ID="LAST_UPDATE_LOGIN" />

</COLUMNS>
</DATA>

我已经将脚本编写为sample.filter( x => x.contains("DATA_TYPE") || x.contains("ID")),我需要获取(ID,DATA_TYPE)的每一对值,以便最终输出应该像

("APPLICATION_ID","NUMBER"),("DESCRIPTIVE_FLEXFIELD_NAME","VARCHAR2"),etc.

任何人都可以帮助我吗?

感谢!!!

2 个答案:

答案 0 :(得分:1)

您可以在spark中使用xml阅读器

val df = sqlContext.read
  .format("com.databricks.spark.xml")
  .option("rootTag", "DATA")
  .option("rowTag", "COLUMNS")
  .load("path to the xml file")

并应用内置函数,例如explodeselect

import org.apache.spark.sql.functions._
df.select(explode(col("COLUMN")))
  .select(col("col.*"))
  .filter(col("_DATA_TYPE").isNotNull || col("_ID").isNotNull)
  .select("_DATA_TYPE", "_ID")

应该给你

+----------+--------------------------+
|_DATA_TYPE|_ID                       |
+----------+--------------------------+
|NUMBER    |APPLICATION_ID            |
|VARCHAR2  |DESCRIPTIVE_FLEXFIELD_NAME|
|VARCHAR2  |LANGUAGE                  |
|NUMBER    |CREATED_BY                |
|NUMBER    |LAST_UPDATE_LOGIN         |
+----------+--------------------------+

现在您可以根据需要将其转换为rdd并进行解析,或将其保留为数据框并对其应用其他操作。

答案 1 :(得分:1)

虽然可以使用spark-xml以更简单,更健壮的方式完成此操作。您还可以使用scala.xml API来解析:

import scala.xml._

val rdd = sc.textFile("file.xml").filter( x => x.contains("DATA_TYPE") || x.contains("ID"))

rdd.map(XML.loadString(_) )
   .map(node => ( (node \\ "@ID").text , (node \\ "@DATA_TYPE").text  ) )
   .collect.foreach(println)

// (APPLICATION_ID,NUMBER)
// (DESCRIPTIVE_FLEXFIELD_NAME,VARCHAR2)
// (LANGUAGE,VARCHAR2)
// (CREATED_BY,NUMBER)
// (LAST_UPDATE_LOGIN,NUMBER)