在Scala中读取带有封闭标签和许多属性的xml文件

时间:2019-07-01 20:00:36

标签: xml scala apache-spark

我正在Scala中读取xml文件

<tag1>
  <tag2 id="0" attr1="abc" ... />
  ..
</tag1>

此问题已报告为问题,并已关闭。 https://github.com/databricks/spark-xml/pull/303

但是我无法解决此问题。

import org.apache.spark.sql.SparkSession
import com.databricks.spark.xml._
import org.apache.spark.sql.types.{StructType, StructField, DoubleType,StringType}
import org.apache.spark.sql.{Row, SaveMode}

object stack {
  def main(args: Array[String]) {
    val spark = SparkSession.builder.getOrCreate()

    val customSchema = StructType(Array(
      StructField("id", DoubleType, nullable = true),
      StructField("attr1", StringType, nullable = true),
      ...
      ...
    ))  
    val df = spark.read
        .option("rowTag", "tag2")
        .format("com.databricks.spark.xml")
        .schema(customSchema)
        .load("dummy.xml")

    import spark.sql
    import spark.implicits._

    df.createOrReplaceTempView("temp1")
    sql("SELECT * from temp1 limit 5").show()
  }
}

但是df.show(5)不显示任何行。

该决议讨论了我没有尝试过的XmlInputFormat的使用,如果有人可以指导的话,将很有帮助。

类似类型的解决方案适用于嵌套的xml文件。

<books>
  <book> .. </book>
  <name> abc </name>
</books>

我想查看包含要显示的值的数据框。然后我想读取许多xml文件并将它们加入sql查询中。

2 个答案:

答案 0 :(得分:1)

您需要为属性添加_前缀。

数据(dummy.xml):

<tag1>
    <tag2 id="0" attr1="abc"/>
    <tag2 id="1" attr1="abd" />
    <tag2 id="2" attr1="abd" />
</tag1>

解决方案:

package main

import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.types.{DoubleType, StringType, StructField, StructType}

object Main extends App {
  val spark = SparkSession.builder.config("spark.master", "local").getOrCreate()

  val customSchema = StructType(Array(
    StructField("_id", DoubleType, nullable = true),
    StructField("_attr1", StringType, nullable = true)
  ))
  val df = spark.read
    .option("rowTag", "tag2")
    .format("com.databricks.spark.xml")
    .schema(customSchema)
    .load("dummy.xml")
  import spark.sql

  df.createOrReplaceTempView("temp1")
  sql("SELECT * from temp1 limit 5").show()
}

结果:

+---+------+
|_id|_attr1|
+---+------+
|0.0|   abc|
|1.0|   abd|
|2.0|   abd|
+---+------+

我怎么知道的:

  1. 发现方案存在问题,因为它适用于子元素
  2. 删除(或注释)自定义架构(// .schema(customSchema)
  3. 可解决火花的打印架构(df.printSchema()
  4. 找到您需要的东西
  5. 创建新架构

另请参阅:Extracting tag attributes from xml using sparkxml

PS:对不起,我的英语

答案 1 :(得分:0)

感谢米哈伊尔提供指导,但是问题很小。很抱歉,由于问题出在属性中,因此没有更早提供实际的xml文件记录。

<users>
    <row Id="-1" Reputation="1" ..... />
</users>

属性以大写字母开头,当我将它们缩小时,我的解决方案开始工作(当然,按照Mikhail的建议,我在使用模式之前先打印了模式)