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

使用spark-xml的from_xml函数解析XML列仅返回null值问题求助

根因分析

你遇到的解析全返回null的核心问题是XSD生成的Schema结构和rowTag配置冲突:

  • 你用XSDToSchema.read读取XSD后生成的Schema结构本身就包含最外层的note节点,结构为:
    root
     |-- note: struct (nullable = false)
     |    |-- from: string (nullable = false)
     |    |-- to: string (nullable = false)
     |    |-- message: string (nullable = false)
    
  • 当你给from_xml传入rowTag = "note"参数时,spark-xml会优先从XML字符串中提取所有<note>标签的内部内容作为解析根,此时解析出来的内容只有from、to、message三个子字段,没有外层的note字段,和你传入的Schema结构完全不匹配,因此解析结果全部为null。
    另外你配置了mode = FAILFAST但没有抛出异常,也验证了不是XML格式错误,只是字段结构不匹配导致spark找不到对应字段返回了默认的null值。

解决方法

任选其一即可:

  1. 移除from_xml参数中的"rowTag" -> "note"配置,让解析根为整个XML字符串,直接匹配XSD生成的Schema结构,解析逻辑保持不变即可正常取出parsed.note.from等字段。
  2. 保留rowTag配置,调整传入from_xml的Schema,提取XSD生成Schema中note字段的子结构作为解析Schema:
    // 提取note节点的子结构作为解析Schema
    val schema = XSDToSchema.read("<the XSD as string>")
      .apply("note")
      .dataType
      .asInstanceOf[StructType]
    
    // 后续select时不用再嵌套取note,直接取parsed下的字段即可
    .select($"value",$"parsed.from", $"parsed.to", $"parsed.message")
    

补充排查思路

如果按上述方法修改后仍有问题,可以按以下步骤验证:

  • 先静态测试解析逻辑,排除流处理的干扰:
    val testXml = """<?xml version="1.0" encoding="UTF-8"?>
    <note>
        <from>Jani</from>
        <to>Tove</to>
        <message>Remember me this weekend</message>
    </note>"""
    val testDf = Seq(testXml).toDF("value")
    val parsedDf = testDf.withColumn("parsed", from_xml($"value", schema, Map(
      "mode" -> "FAILFAST",
      "nullValue"-> "",
      "ignoreSurroundingSpaces" -> "true"
    )))
    parsedDf.show(false)
    
    静态测试可以正常解析的话,再排查Kafka读取的内容是否有隐藏字符(比如BOM头、转义字符、多余的前后缀),可以先打印完整的value字段内容确认格式符合预期。
  • 确认spark-xml 0.12.0和Spark 3.1.1的兼容性,也可以尝试升级到spark-xml 0.13.0版本,该版本对Spark 3.1.x的适配更稳定。

内容的提问来源于stack exchange,提问作者Alejandro Arévalo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 18:15:02