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

Use recursive globbing to extract XML documents as strings in pyspark

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

我以为我找到了 Databrick's Spark Spark-XML library 的解决方案,因为它在读取文件时处理递归通配。这是惊人的。可以做这样的事情:

# 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 库以利用文件的递归 globbing 和 XPath 抓取,但跳过解析并保存整个 XML 记录作为字符串。

该库具有将数据帧序列化为 XML 的能力,但序列化与输入明显不同(这在某种程度上是意料之中的)。例如,元素文本值成为元素属性。鉴于以下原始XML:

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

读取然后用 Spark 序列化-XML returns:

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

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

如有任何见解,我们将不胜感激。

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

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">\n\n\n               <mods:titleInfo>\n\n\n                  <mods:title>Jessie</mods:title>\n\n\n...
...
...

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