Spark读取嵌套XML必须使用Databricks的spark-xml包,原生不支持;需正确配置rowTag、valueTag、attributePrefix等参数解析嵌套结构、属性和混合内容,大文件应分片处理避免OOM。

Spark读取嵌套XML必须用spark-xml第三方包
Spark原生不支持XML,spark.read.format("xml")会直接报错java.lang.ClassNotFoundException: Failed to find data source: xml。必须显式引入Databricks维护的com.databricks:spark-xml_2.12(注意Scala版本要匹配)。Maven坐标不能漏掉_2.12或_2.13后缀,否则运行时找不到类。
嵌套结构需靠rowTag和valueTag准确定位
XML嵌套层级深时,rowTag决定哪一层作为DataFrame的行记录;若不设,默认只解析顶层标签,所有子节点被塞进一个_VALUE字段里,失去结构。遇到含这种结构,必须设rowTag="item"。如果某字段值本身是文本(如),还要加valueTag="title",否则内容会变成空或null。
-
rowTag必须是唯一可枚举的“记录级”标签名,不能是root或data这类泛化名 - 多个同名嵌套标签(如
)会自动展开为多行,无需额外flatten- ...
- ...
- 若XML有命名空间(
xmlns="http://example.com/ns"),spark-xml默认不识别,得先用XSLT预处理或改用XmlInputFormat+ RDD方式
复杂类型(数组、属性、混合内容)要主动配置解析策略
默认情况下,XML属性(如)不会自动转成列,必须设attributePrefix="@@";而混合内容(文本+子标签共存)容易导致字段丢失,需配合valueTag和ignoreSurroundingSpaces=true清理空白。
df = spark.read.format("xml") \
.option("rowTag", "book") \
.option("attributePrefix", "@@") \
.option("valueTag", "_VALUE") \
.option("ignoreSurroundingSpaces", "true") \
.load("books.xml")
这样才会生成三列:@@id、title、_VALUE。漏掉valueTag,Intro就没了。
超大XML文件慎用wholeFile=True,优先分片+流式解析
spark-xml底层依赖javax.xml.parsers.SAXParser,单文件超过2GB极易OOM。不要设wholeFile=True(这是为小文件设计的),而是把XML按rowTag切分成多个小文件,或用spark.read.text()逐行扫描+正则提取关键段落再组装。另外,compression="gzip"仅支持已压缩的单文件,不解压流式读取——意味着必须先解压到磁盘再读,无法节省IO。
真正难啃的是跨文件的嵌套逻辑(比如分散在多个XML中),这时候Spark已不是最优解,该换Flink或专用XML流处理器。










