You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 20:15:37