我在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.
任何人都可以帮助我吗?
感谢!!!
答案 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")
并应用内置函数,例如explode
和select
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)