我正在努力将解析逻辑解码为数据框架,其中JSON对象中有XML数据。我已经成功读取JSON对象并存储在如下所示的数据框中,它包含一个col Guest_data,它是XML:
Country | Guest_data | 罗马尼亚 | xml 1 | 匈牙利
---|---|
xml 2 | |
3 | xml |
假设所有访问者始终具有XML属性(id=
,age=
和sex=
),您可以使用Spark SQL的xpath
。这可以用一个数据框架来完成,不需要创建单独的数据框架。
完整的示例:
from pyspark.sql import functions as F
df = spark.createDataFrame(
[('Romania', '<?xml version="1.0" encoding="utf-8"?> <visitors> <visitor id="AA11" age="68" sex="F" /> <visitor id="BB22" age="34" sex="M" /> <visitor id="CC33" age="23" sex="M" /> </visitors>'),
('Hungary', '<?xml version="1.0" encoding="utf-8"?> <visitors> <visitor id="FF77" age="27" sex="F" /> <visitor id="YY99" age="32" sex="M" /> </visitors>'),
('Ukraine', '<?xml version="1.0" encoding="utf-8"?> <visitors> <visitor id="DD55" age="68" sex="F" /> <visitor id="LL99" age="34" sex="M" /> <visitor id="SS77" age="47" sex="M" /> <visitor id="TT00" age="30" sex="M" /> </visitors>')],
['Country', 'Guest_data']
)
id = F.expr('xpath(Guest_data, "//@id")')
sex = F.expr('xpath(Guest_data, "//@sex")')
age = F.expr('xpath(Guest_data, "//@age")')
df = df.withColumn('exploded', F.explode(F.arrays_zip(id, sex, age)))
df = df.select(
'Country',
F.col('exploded.0').alias('id'),
F.col('exploded.1').alias('sex'),
F.col('exploded.2').alias('age'),
)
df.show()
# +-------+----+---+---+
# |Country| id|sex|age|
# +-------+----+---+---+
# |Romania|AA11| F| 68|
# |Romania|BB22| M| 34|
# |Romania|CC33| M| 23|
# |Hungary|FF77| F| 27|
# |Hungary|YY99| M| 32|
# |Ukraine|DD55| F| 68|
# |Ukraine|LL99| M| 34|
# |Ukraine|SS77| M| 47|
# |Ukraine|TT00| M| 30|
# +-------+----+---+---+
如果你的任何访问者没有任何属性(例如一些访问者没有告诉他的年龄),你将不会得到任何错误,结果将是不正确的(移位),所以你应该采取额外的措施来确保属性将始终存在。