微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从具有属性的多个嵌套 XML 文件转换以触发 Data Frame 数据

如何解决如何从具有属性的多个嵌套 XML 文件转换以触发 Data Frame 数据

如何将下面的值从多个 XML 文件转换为火花数据框:

  • 属性 Id0 来自 Level_0
  • Date/Value 来自 Level_4

所需输出

+----------------+-------------+---------+
|Id0             |Date         |Value    |
+----------------+-------------+---------+
|Id0_value_file_1|  2021-01-01 |   4_1   |
|Id0_value_file_1|  2021-01-02 |   4_2   |
|Id0_value_file_2|  2021-01-01 |   4_1   |
|Id0_value_file_2|  2021-01-02 |   4_2   |
+----------------+-------+---------------+

file_1.xml:

<Level_0 Id0="Id0_value_file1">
  <Level_1 Id1_1 ="Id3_value" Id_2="Id2_value">
    <Level_2_A>A</Level_2_A>
    <Level_2>
      <Level_3>
        <Level_4>
          <Date>2021-01-01</Date>
          <Value>4_1</Value>
        </Level_4>
        <Level_4>
          <Date>2021-01-02</Date>
          <Value>4_2</Value>
        </Level_4>
      </Level_3>
    </Level_2>
  </Level_1>
</Level_0>

file_2.xml:

<Level_0 Id0="Id0_value_file2">
  <Level_1 Id1_1 ="Id3_value" Id_2="Id2_value">
    <Level_2_A>A</Level_2_A>
    <Level_2>
      <Level_3>
        <Level_4>
          <Date>2021-01-01</Date>
          <Value>4_1</Value>
        </Level_4>
        <Level_4>
          <Date>2021-01-02</Date>
          <Value>4_2</Value>
        </Level_4>
      </Level_3>
    </Level_2>
  </Level_1>
</Level_0>

当前代码示例:

files_list = ["file_1.xml","file_2.xml"]
df = (spark.read.format('xml')
           .options(rowTag="Level_4")
           .load(','.join(files_list))

当前输出:(Id0 列缺少属性

+-------------+---------+
|Date         |Value    |
+-------------+---------+
|  2021-01-01 |     4_1 |
|  2021-01-02 |     4_2 |
|  2021-01-01 |     4_1 |
|  2021-01-02 |     4_2 |
+-------+---------------+

有一些例子,但没有一个解决问题: -我正在使用数据块 spark_xml - https://github.com/databricks/spark-xml - 有一个例子,但没有属性读取,Read XML in spark,Extracting tag attributes from xml using sparkxml .

编辑: 正如@mck 正确指出的那样,<Level_2>A</Level_2> 不是正确的 XML 格式。我的示例中有一个错误(现在 xml 文件已更正),它应该是 <Level_2_A>A</Level_2_A>。之后,建议的解决方案甚至适用于多个文件

注意:为了加速加载大量 xml 定义架构,如果没有定义架构,火花在创建数据帧时会读取每个文件以干扰架构... 更多信息:https://szczeles.github.io/Reading-JSON-CSV-and-XML-files-efficiently-in-Apache-Spark/

步骤 1):

 files_list = ["file_1.xml","file_2.xml"]
 # for schema seem NOTE above

 df = (spark.read.format('xml')
               .options(rowTag="Level_0")
               .load(','.join(files_list),schema=schema))
df.printSchema()

root
 |-- Level_1: struct (nullable = true)
 |    |-- Level_2: struct (nullable = true)
 |    |    |-- Level_3: struct (nullable = true)
 |    |    |    |-- Level_4: array (nullable = true)
 |    |    |    |    |-- element: struct (containsNull = true)
 |    |    |    |    |    |-- Date: string (nullable = true)
 |    |    |    |    |    |-- Value: string (nullable = true)
 |    |-- Level_2_A: string (nullable = true)
 |    |-- _Id1_1: string (nullable = true)
 |    |-- _Id_2: string (nullable = true)
 |-- _Id0: string (nullable = true

第 2 步)见下方@mck 解决方案:

解决方法

您可以使用 <FieldRef Name="Description" /> 作为 rowTag,并分解相关数组/结构:

<FieldRef Name="Body" />

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。