使用递归通配符将 XML 文档提取为 pyspark 中的字符串
Use recursive globbing to extract XML documents as strings in pyspark
目标是在给定 XPath
表达式的情况下,从一组文本文件中提取 XML 文档作为字符串。困难在于文本文件可能采用的形式的差异。可能是:
- 单个 zip / tar 文件,包含 100 个文件,每个文件 1 XML 个文档
- 一个文件,包含 100 个 XML 文档(聚合文档)
- 一个 zip / tar 文件,具有不同级别的目录,单个 XML 记录作为文件和聚合 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 的维护者,他们提供了一个很棒的库和对问题的关注。
目标是在给定 XPath
表达式的情况下,从一组文本文件中提取 XML 文档作为字符串。困难在于文本文件可能采用的形式的差异。可能是:
- 单个 zip / tar 文件,包含 100 个文件,每个文件 1 XML 个文档
- 一个文件,包含 100 个 XML 文档(聚合文档)
- 一个 zip / tar 文件,具有不同级别的目录,单个 XML 记录作为文件和聚合 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 的维护者,他们提供了一个很棒的库和对问题的关注。