使用递归通配将 XML 文档提取为 pyspark 中的字符串



目标是从一组文本文件中提取XML文档,给定一个XPath表达式作为字符串。 困难在于文本文件可能采用的形式差异。 可能是:

  • 包含 100 个文件的单个 zip/tar 文件,每个文件 1 个 XML 文档
  • 一个文件,包含 100 个 XML 文档(聚合文档)
  • 一个 zip/tar 文件,具有不同级别的目录,将单个 XML 记录作为文件和聚合 XML 文件

我以为我已经找到了Databrick的Spark Spark-XML库的解决方案,因为它在读取文件时处理递归通配。 太神奇了。 可以做这样的事情:

# read directory of loose files
df = sqlContext.read.format('com.databricks.spark.xml').options(rowTag='mods:mods').load('file:///tmp/combine/qs/mods/*.xml')
# recursively discover and parse
df = sqlContext.read.format('com.databricks.spark.xml').options(rowTag='mods:mods').load('file:///tmp/combine/qs/**/*.xml')
# even read archive files without additional work
df = sqlContext.read.format('com.databricks.spark.xml').options(rowTag='mods:mods').load('file:///tmp/combine/mods_archive.tar')

问题是,这个库专注于将 XML 记录解析为 DataFrame 列,我的目标是仅检索 XML 文档作为字符串进行存储。

我的 scala 不够强大,无法轻松破解 Spark-XML 库来利用递归通配和 XPath 抓取文档,但跳过解析,而是将整个 XML 记录保存为字符串。

该库具有将数据帧序列化为 XML 的功能,但序列化与输入明显不同(在某种程度上是可以预期的)。 例如,元素文本值将成为元素属性。 给定以下原始 XML:

<mods:role>
<mods:roleTerm authority="marcrelator" type="text">creator</mods:roleTerm>
</mods:role>

读取然后序列化 Spark-XML 返回:

<mods:role>
<mods:roleTerm VALUE="creator" authority="marcrelator" type="text"></mods:roleTerm>
</mods:role>

但是,即使我可以将VALUE序列化为实际的元素值,我仍然没有实现我的最终目标,即将通过 Spark-XML 出色的通配和 XPath 选择发现和读取这些 XML 文档作为字符串。

任何见解将不胜感激。

从这个 Databricks Spark-XML 问题中找到了一个解决方案:

xml_rdd = sc.newAPIHadoopFile('file:///tmp/mods/*.xml','com.databricks.spark.xml.XmlInputFormat','org.apache.hadoop.io.LongWritable','org.apache.hadoop.io.Text',conf={'xmlinput.start':'<mods:mods>','xmlinput.end':'</mods:mods>','xmlinput.encoding': 'utf-8'})

期待 250 条记录,并得到 250 条记录。 将整个 XML 记录作为字符串的简单 RDD:

In [8]: xml_rdd.first()
Out[8]: 
(4994,
'<mods:mods xmlns:mets="http://www.loc.gov/METS/" xmlns:xl="http://www.w3.org/1999/xlink" xmlns:mods="http://www.loc.gov/mods/v3" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.openarchives.org/OAI/2.0/" version="3.0">nnn               <mods:titleInfo>nnn                  <mods:title>Jessie</mods:title>nnn...
...
...

感谢Spark-XML维护者提供了一个很棒的库,以及对问题的关注。

最新更新