我有一个XML文件,如下所示:
<report>
<instance name="XYZ" number ="1">
<key value="ABC"/>
<key value="ABCD"/>
</instance>
<instance name="PQR" number ="2">
<key value="ABCDE"/>
<key value="ABCDF"/>
</instance>
</report>
我想创建以下时尚的SparkSQL表
name number value
XYZ 1 ABC
XYZ 1 ABCD
PQR 2 ABCDE
PQR 2 ABCDF
技术上可行吗?
我正在使用pySpark,这就是我到目前为止所做的事情:
df = sqlContext.read.format("com.databricks.spark.xml").option("rowTag", "report").load("//path//to//file.xml")
df.registerTempTable("XMLtable");
我得到了架构:
root
|-- instance: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- @name: string (nullable = true)
| | |-- @number: long (nullable = true)
| | |-- key: array (nullable = true)
| | | |-- element: struct (containsNull = true)
| | | | |-- @value: string (nullable = true)
我执行了以下查询:
sqlContext.sql("select * from XMLtable").show();
+-------------+
| INSTANCE|
+-------------+
|[[null,XYZ...|
+-------------+
This query correctly points me to the right data.
sqlContext.sql("select instance[1].key[1]['@value'] as value from XMLtable").show();
+--------+
| value |
+--------+
|(1)ABCDF|
+--------+
据我所知,该表未按预期正确加载。如何使用属性加载表,而不是加载值的一般方法。
有人能指出我正确的方向吗?我已经检查过没有属性值,并且效果很好。我需要的是创建一个如上所述的表,其中填充了属性值,这将有助于为解析的XML数据编写查询。我还打算稍后将其转换为pandas数据帧,以对数据进行更多的统计分析。
答案 0 :(得分:1)
是的,这是可能的。首先,在加载xml期间为instance
选项指定report
而不是rowTag
,并为valueTag
添加指定自定义值(以避免与value
属性冲突),例如:
df = sqlContext.read.format("com.databricks.spark.xml").option("rowTag", "instance") \
.option("valueTag", "some_value").load("data.xml")
然后,您可以使用以下方法轻松地将数据帧设置为请求的格式:
>>> df.withColumn('values', explode('key')).select(
col('_name').alias('name'),
col('_number').alias('number'),
col('values._value').alias('value')
).show()
+----+------+-----+
|name|number|value|
+----+------+-----+
| XYZ| 1| ABC|
| XYZ| 1| ABCD|
| PQR| 2|ABCDE|
| PQR| 2|ABCDF|
+----+------+-----+
最后,将此数据框注册为临时表,它的行为与您预期的一样。