Spark读取XML时空字符串被转为0,如何改为Null?
问题:Spark读取XML时空字符串被转为0,如何改为Null?
模拟XML文件
<?xml version="1.0" encoding="utf-8"?> <Report xsi:schemaLocation="foo" Name="foo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="foo"> <stuff> <list> <Details key="abdce" Code=""/> <Details key="12346" Code="10"/> </list> </stuff> </Report>
问题场景
使用Spark读取上述XML文件时,Code列被识别为Long类型(符合预期),但XML中的空字符串""被自动替换为0。执行以下Spark代码:
val df= spark.read.format("xml").option("RootTag","Report").option("rowTag","Report").option("nullValue", "").load(source_file) df.withColumn("row", explode($"stuff.list.Details")).select($"row._Code",$"row._key").show
得到结果:
+-----+----------+ |_Code| _key| +-----+----------+ | 0| abdce| | 10| 12346| +-----+----------+
需要实现第一行的_Code值为Null而非0。
解决方法
方法一:先按字符串读取,再转换类型并替换空值
关闭自动推断Schema,先将所有列按字符串类型读取,避免空字符串被自动转为0,之后再将目标列转为Long类型,同时把空字符串替换为Null。
// 读取XML时关闭Schema自动推断 val df = spark.read.format("xml") .option("RootTag", "Report") .option("rowTag", "Report") .option("inferSchema", false) .load(source_file) import org.apache.spark.sql.functions._ import org.apache.spark.sql.types.LongType // 处理空字符串并转换类型 df.withColumn("row", explode($"stuff.list.Details")) .select( // 空字符串转为Null,非空则转为Long类型 when($"row._Code" === "", null).otherwise($"row._Code".cast(LongType)).alias("_Code"), $"row._key" ).show
执行后结果:
+-----+----------+ |_Code| _key| +-----+----------+ | null| abdce| | 10| 12346| +-----+----------+
方法二:使用treatEmptyValuesAsNulls参数(适用于Databricks的spark-xml库)
如果使用的是Databricks维护的spark-xml库(Maven坐标:com.databricks:spark-xml_2.12:x.x.x),可以直接开启treatEmptyValuesAsNulls选项,该参数会将XML中的空字符串直接解析为Null,配合nullValue参数使用效果更佳。
val df = spark.read.format("xml") .option("RootTag", "Report") .option("rowTag", "Report") .option("treatEmptyValuesAsNulls", true) // 开启空字符串转Null .option("nullValue", "") .load(source_file) df.withColumn("row", explode($"stuff.list.Details")) .select($"row._Code", $"row._key") .show
执行后同样会得到_Code为Null的结果。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

