用sp解析/加载巨大的XML文件

2024-09-30 14:33:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个具有以下设置的XML文件。在

<?xml version="1.0" encoding="utf-8"?>
<SomeRoottag>
 <row Id="47513849" PostTypeId="1" />
 <row Id="4751323" PostTypeId="4" />
 <row Id="475546" PostTypeId="1" />
 <row Id="47597" PostTypeId="2" />
</SomeRoottag>

我解析该文件并用以下代码将其保存为配置单元表。在

^{pr2}$

我的测试数据(10mb)一切正常,但当我加载大文件(大于50G)时,它就失败了。 spark JVM似乎试图加载整个文件,但失败了,因为它只有20G大。在

处理这样的文件最好的方法是什么?在

更新:

如果我执行以下操作,则不会收到任何数据:

df = (sqlContext.read.format('xml').option("rowTag", "row").load("/tmp/someXML.xml"))
df.printSchema()
df.show()

输出:

root

++
||
++
++

Tags: 文件代码iddfversionxmlutfencoding
1条回答
网友
1楼 · 发布于 2024-09-30 14:33:16

不要使用SomeRoottag作为rowTag。它指示Spark将整个文档用作一行。取而代之的是:

df = (sqlContext.read.format('xml')
    .option("rowTag", "row")
    .load("/tmp/xmlfile.xml"))

现在也不需要爆炸了:

^{pr2}$

编辑

考虑到您的编辑,您会受到已知错误的影响。请参见Self-closing tags are not supported as top-level rows #92。目前在解决这一问题上似乎没有任何进展,因此您可能必须:

  • 你自己来解决这个问题。在
  • 手动分析文件。如果元素总是单行的,则可以使用udf轻松完成。在

    from pyspark.sql.functions import col, udf
    from lxml import etree
    
    @udf("struct<id: string, postTypeId: string>")
    def parse(s):
        try:
            attrib = etree.fromstring(s).attrib
            return attrib.get("Id"), attrib.get("PostTypeId")
        except:
            pass
    
    (spark.read.text("/tmp/someXML.xml")
        .where(col("value").rlike("^\\s*<row "))
        .select(parse("value").alias("value"))
        .select("value.*")
        .show())
    
    # +    +     +
    # |      id|postTypeId|
    # +    +     +
    # |47513849|         1|
    # | 4751323|         4|
    # |  475546|         1|
    # |   47597|         2|
    # +    +     +
    

相关问题 更多 >