首页 > 解决方案 > 在 Spark 中解析复杂的 xml

问题描述

从数据块中的 TSV/CSV 文件中提取 Xml 数据

我几乎不需要关于 Tsv 文件之间的 xml 数据的帮助。在几个 Databricks 问题论坛上看到了答案。我不确定是否可以直接实现和使用任何 UDF 类型的函数。如果可以在 pyspark 中完成任何事情或任何内置的 databricks 实用程序可以处理它,请请求您的输入。

需要 tsv id、status 其他列以及 XML 中的一些内部属性。请建议如何在 pyspark 或 spark sql 中实现逻辑。这里的文件不是 XML,文件中的一列有 XML 数据。

我试图像文本一样读取文件并将其转换为 dataframe 。我需要建议从数据框中提取 XML 内容。

文件示例如下所示,顶部有标题:

Id || UserId || UserSgid || ClientId || Version || WTVersion || Details || Status || DCT || DMD || Visible   


33144   
6587a872-23ce-4453-8c68-1209ac21352b    
ce9c6fcc-d20e-4f5f-8e64-e307849d1fda    
986b5314-7269-4bd3-abee-6f9b1b27b990    
1    
1   

<Workflow xmlns="http://schemas.datacontract.org/2004/07/SMT.WorkflowSteps" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><DateCompleted i:nil="true" />

<DateStarted>2017-05-19T02:50:25.647</DateStarted>
<Enabled>true</Enabled>
<Id>986b5314-7269-4bd3-abee-6f9b1b27b990</Id>
<Status>Started</Status>
<Visible>true</Visible>
<DateCreated>2019-08-22T21:47:24.8648778Z</DateCreated>
<ExecutionId>c2ea7b9d-cd6a-432f-8fd4-2e8cfae679e9</ExecutionId>
<Steps xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <a:anyType i:type="WorkflowPhase">
        <DateCompleted i:nil="true" />
        <DateStarted i:nil="true" />
        <Enabled>true</Enabled>
        <Id>8184775f-a5f2-4648-bb6b-cbc840f73a10</Id>
        <Status>NotStarted</Status>
        <Visible>true</Visible>
<Steps>
<a:anyType i:type="OldAccommodationRequestWorkflowStep">
    <DateCompleted i:nil="true" />
    <DateStarted i:nil="true">

1   
2016-05-18 17:19:37.9770000 
2019-08-22 21:47:36.3600000 
True

需要从具有 xml 内容的详细信息列中提取数据以及Id,UserId,UserSgid,ClientId,Version,WTVersion其他一些数据,例如等。ExecutionId ,Status

标签: xmlapache-sparkpysparkazure-databricks

解决方案


您可以使用已弃用的xmlRdd(这是唯一的解决方案,我现在可以看到)。假设您有以下 xml:

 public static void readFromString() {
    SparkConf sparkConf = new SparkConf().setAppName("Print Elements of RDD")
            .setMaster("local[2]").set("spark.executor.memory","2g");

    JavaSparkContext sc = new JavaSparkContext(sparkConf);

    String books = "<persons>\n" +
            "    <person id=\"1\">\n" +
            "        <firstname>James</firstname>\n" +
            "        <lastname>Smith</lastname>\n" +
            "        <middlename></middlename>\n" +
            "        <dob_year>1980</dob_year>\n" +
            "        <dob_month>1</dob_month>\n" +
            "        <gender>M</gender>\n" +
            "        <salary currency=\"Euro\">10000</salary>\n" +
            "    </person>\n" +
            "</persons>";

    List<String> booksList = Arrays.asList(books);

    RDD<String> booksRDD = sc.parallelize(booksList, 1).rdd();

    Dataset<Row> rowDataset = new XmlReader().withRowTag("person").xmlRdd(new SQLContext(sc), booksRDD);

    rowDataset.printSchema();

    rowDataset.select("person.*").show();

}

结果rowDataset.printSchema()

root
 |-- person: struct (nullable = true)
 |    |-- _id: long (nullable = true)
 |    |-- dob_month: long (nullable = true)
 |    |-- dob_year: long (nullable = true)
 |    |-- firstname: string (nullable = true)
 |    |-- gender: string (nullable = true)
 |    |-- lastname: string (nullable = true)
 |    |-- middlename: string (nullable = true)
 |    |-- salary: struct (nullable = true)
 |    |    |-- _VALUE: long (nullable = true)
 |    |    |-- _currency: string (nullable = true)

的结果rowDataset.select("person.*").show();

+---+---------+--------+---------+------+--------+----------+------------+
|_id|dob_month|dob_year|firstname|gender|lastname|middlename|      salary|
+---+---------+--------+---------+------+--------+----------+------------+
|  1|        1|    1980|    James|     M|   Smith|          |[10000,Euro]|
+---+---------+--------+---------+------+--------+----------+------------+

您可以将相同的逻辑应用于您的用例


推荐阅读