如何利用Spark XML自定义Schema获取标签间的文本内容?
提取Spark XML中子元素间的文本内容
要解决这个问题,核心是让Spark XML库能捕获到元素之间的文本节点——默认情况下,Spark XML只会提取结构化的子元素,会忽略这些游离的文本内容。我们可以通过自定义Schema来实现需求,具体步骤如下:
1. 定义自定义Schema
我们需要把根元素<a>的内容定义为一个数组,数组中的每个元素要么是<b>子元素,要么是文本节点。对应的Schema结构如下:
import org.apache.spark.sql.types._ val customSchema = StructType(Seq( StructField("a", ArrayType(StructType(Seq( StructField("b", StringType, nullable = true), StructField("_VALUE", StringType, nullable = true) ))), nullable = true) ))
ArrayType用来容纳<a>下的所有子节点(包括<b>元素和文本节点)b字段对应<b>元素的内容_VALUE是Spark XML保留的特殊字段,专门用来存储文本节点的内容
2. 读取XML文件并应用Schema
注意修正rowTag参数(你的示例XML根元素是<a>,不是tagA),然后加载数据:
val df = spark.read .format("com.databricks.spark.xml") .option("rowTag", "a") // 匹配你的XML根元素 .schema(customSchema) .load("in/test.xml")
3. 过滤并提取目标文本
展开数组后,过滤出仅包含文本节点的项(即_VALUE非空且b为空的记录),最后清理掉多余空格:
import org.apache.spark.sql.functions._ df.select(explode(col("a")).alias("items")) .filter(col("items._VALUE").isNotNull && trim(col("items._VALUE")) =!= "") .select(trim(col("items._VALUE")).alias("extracted_text")) .show(false)
运行这段代码后,你会得到如下结果:
+---------------+ |extracted_text | +---------------+ |cannot be seen | |neither | +---------------+
关键说明
Spark XML在处理混合内容(子元素+文本节点)时,会把每个独立的节点(无论是元素还是文本)拆分为数组中的一个元素。文本节点的内容会被存入_VALUE字段,而子元素则对应到同名的字段中——通过这种方式,我们就能精准筛选出需要的文本内容。
内容的提问来源于stack exchange,提问作者APM
相关产品推荐
相关产品推荐

