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

Databricks用PySpark解析Stack Exchange PostHistory.xml为DataFrame遇空表

问题原因及解决办法

一、Databricks使用spark-xml读取全为null的问题

错误核心原因

  • 多数版本的spark-xml库默认会给XML节点的属性添加_前缀作为解析后的字段名,你自定义Schema里的字段名是ContentLicense,但实际解析出来的字段是_ContentLicense,字段名完全不匹配导致所有值被识别为null。
  • 可选次要原因:你配置的字符集参数UTF8书写不规范,应该为UTF-8;部分属性前后的空格未被自动忽略也可能导致解析异常。

解决步骤

  1. 先执行无Schema的推断读取,确认实际解析的字段名:
test_df = spark.read.format("com.databricks.spark.xml") \
 .option("rowTag", "row") \
 .option("charset", "UTF-8") \
 .load("/FileStore/tables/PostHistory.xml")
test_df.printSchema()
  1. 如果输出字段名带_前缀,两种方案二选一即可:
    • 方案一:添加配置关闭属性前缀,匹配你现有Schema
    PostHistoryDF = spark.read.format("com.databricks.spark.xml") \
     .option("rowTag", "row") \
     .option("charset", "UTF-8") \
     .option("attributePrefix", "") \ # 关闭属性前缀
     .option("ignoreLeadingWhitespace", True) \
     .option("ignoreTrailingWhitespace", True) \
     .schema(schema_posthistory) \
     .option("treatEmptyValuesAsNulls", "true") \
     .load("/FileStore/tables/PostHistory.xml")
    
    • 方案二:修改Schema字段名,添加对应_前缀即可
  2. 额外检查:如果原始XML文件属性值存在未转义的双引号、尖括号,需要先预处理转义为XML标准转义字符(双引号转&quot;,<转&lt;,>转&gt;),否则也会导致解析失败。
  • 注:你Schema里的UserDisplayName、Comment属于可选字段,样例数据中不存在,解析后为null属于正常情况。

二、Jupyter自定义解析逻辑报错、列数不足的问题

错误核心原因

  • DataFrame.replace()方法不支持正则表达式,你写的df.replace("[^a-zA-Z0-9]", " ")完全无效,Text字段内的特殊字符、分隔符|未被处理,写入CSV时会把单个字段拆分为多列,导致列偏移。
  • 写入CSV时未设置引号、转义配置,Text字段内的空格、特殊符号会触发CSV自动拆列,最终读取时只有7列。
  • spark.createDataFrame从字典生成DataFrame时,列顺序不固定,你手动按固定顺序指定Schema读取会出现列错位。

解决步骤

  1. 用regexp_replace处理特殊字符,避免列拆分:
from pyspark.sql.functions import regexp_replace, col
# 仅替换会影响CSV解析的换行、分隔符即可,不需要清洗所有非字母数字字符,避免丢失数据
df = df.withColumn("Text", regexp_replace(col("Text"), "[\\n\\r|]", " "))
  1. 写入CSV时添加引号、转义、表头配置:
df.write.csv(
    linkcsv + ".csv", 
    sep="|", 
    quote='"', 
    escape='"', 
    header=True, 
    mode="overwrite"
)
  1. 读取CSV时开启表头自动识别,不需要手动固定顺序写Schema:
PostHistory_df = spark.read.format("csv") \
  .option("header", "true") \
  .option("sep", "|") \
  .option("quote", '"') \
  .load("LiteratureCSV/PostHistory.csv")
# 读取完成后再手动转换对应字段的类型即可

内容的提问来源于stack exchange,提问作者MoOn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 12:36:04