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

PySpark解析嵌套XML仅识别首个item标签无法读取数据如何解决

PySpark解析多结构XML数据解决方案

问题核心原因

  • 你提供的原始XML存在语法错误:第二个<item>标签错误使用自闭合语法,导致后续<batters>节点不属于任何item,是无法读取第二个item完整内容的核心原因之一
  • 默认情况下Spark XML仅使用第一条记录推断Schema,若不同item结构不一致,仅采样第一条会遗漏后续item的独有字段

步骤1:修正XML语法

确保所有item节点包裹在根节点<items>内,修正后的标准XML示例:

<items>
    <item name="Cake" ppu="0.55">
        <venue place="Bangalore" day="Friday">
            <batters>
                <batter name="Regular"/>
                <batter name="Chocolate"/>
                <batter name="Blueberry"/>
            </batters>
            <topping id="5001">None</topping>
            <topping id="5002">Glazed</topping>
            <topping id="5005">Sugar</topping>
            <topping id="5006">Sprinkles</topping>
            <topping id="5003">Chocolate</topping>
            <topping id="5004">Maple</topping>
        </venue>
    </item>
    <item name="pizza" ppu="0.56">
        <batters>
            <batter place="Bangalore" name="Regular"/>
        </batters>
    </item>
</items>

步骤2:临时方案(自动推断全量Schema)

如果数据量小,可开启全量采样让Spark扫描所有记录推断Schema:

df = spark.read\
     .format("com.databricks.spark.xml")\
     .option("rowTag", "item")\
     .option("inferSchema", "true")\
     .option("samplingRatio", "1.0") # 采样所有记录推断Schema,避免遗漏字段
     .load("File.xml")

注意:samplingRatio设为1.0会扫描全量数据,大数据量场景下性能极低,仅适合小数据测试使用


步骤3:生产方案(自定义嵌套Schema)

手动定义Schema可兼容不同结构的item节点,同时提升读取性能,完整实现代码:

from pyspark.sql.types import *

# 定义最内层嵌套结构
batter_type = StructType([
    StructField("_name", StringType(), True),
    StructField("_place", StringType(), True)
])

batters_type = StructType([
    StructField("batter", ArrayType(batter_type), True)
])

topping_type = StructType([
    StructField("_id", StringType(), True),
    StructField("_VALUE", StringType(), True) # 标签内的文本值默认存储在_VALUE字段
])

venue_type = StructType([
    StructField("_place", StringType(), True),
    StructField("_day", StringType(), True),
    StructField("batters", batters_type, True),
    StructField("topping", ArrayType(topping_type), True)
])

# 定义完整的item结构,兼容两种不同嵌套形式的item
item_schema = StructType([
    StructField("_name", StringType(), True),
    StructField("_ppu", DoubleType(), True),
    StructField("venue", venue_type, True),
    StructField("batters", batters_type, True)
])

# 读取时指定自定义Schema
df = spark.read\
     .format("com.databricks.spark.xml")\
     .option("rowTag", "item")\
     .schema(item_schema)\
     .load("File.xml")

# 验证结果
df.show(truncate=False)
df.printSchema()

XML标签的属性会默认加_前缀作为字段名,符合Spark XML的默认解析规则。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 15:09:05