自己投資としてチャレンジしている内容を Blog で公開しています。
今回は Apache Spark の環境で利用できる pyspark や spark-shell を使います。XML ファイルのデータを読み取り、必要なデータを抽出する方法を紹介します。
▼1. XML ファイルのデータの読み取り
Apache Spark 3 の環境で XML ファイルのデータを読み取るには、以下の spark-xml のライブラリーが必要です。
例) com.databricks:spark-xml_2.12:0.14.0 の場合、2022年 5 月の時点で最新の version は 2.12 の 0.14.0 となります。
com.databricks : spark-xml_2.12 – Maven Central Repository Search
▼2. 事前準備
2-1. Apache Spark クラスターを作成します。詳細は以前 blog で紹介した下記サイトを参照ください。
Apache Spark インストール – 3 ノード No.29 – 2021/07 – 【挑戦する人を応援するサイト】Kumoman Blog
2-2. Databricks の spark-xml の jar をダウンロードします。
spark-xml_2.12-0.14.0.jar の場合 com.databricks : spark-xml_2.12 : 0.14.0 – Maven Central Repository Search
例) wget https://repo1.maven.org/maven2/com/databricks/spark-xml_2.12/0.14.0/spark-xml_2.12-0.14.0.jar2-3. XML document と Java Object をマッピングする JAXB の jar をダウンロードします。
jaxb-core-3.0.0-M2.jar の場合 https://repo1.maven.org/maven2/com/sun/xml/bind/jaxb-core/3.0.0-M2/
例) wget https://repo1.maven.org/maven2/com/sun/xml/bind/jaxb-core/3.0.0-M2/jaxb-core-3.0.0-M2.jar2-4. サンプルの books.xml ファイルをダウンロードします。
(例) wget https://github.com/databricks/spark-xml/raw/master/src/test/resources/books.xml2-5. ダウンロードした books.xml を、事前に作成しておいた HDFS のディレクトリー appbox に置きます。
hdfs dfs -put ./books.xml appbox▼3. pyspark (python) を使い、XML ファイルのデータの一部抽出し別のファイルに保存
以下の順に進めます。
- spark-xml の jar ファイル及び、XML document と Java Object をマッピングする JAXB の jar を指定して pyspark を起動します。
- DataFrame を作成するために pyspark.sql.SparkSession をインポートし、SparkSession を作成します。
- books.xml ファイルからデータ部分読み取り DataFrame に入れます。
- さらに _id および author の情報のみ抽出し、新しい xml ファイル “newbooks43.xml” に保存し、中身を確認します。
- 読み込んだデータを parquet ファイルに保存します。保存後、hdfs dfs -ls のコマンドで保存した parquet ファイルを確認します。
- Spark UI で Spark Job の実行履歴を確認します。
3-1. spark-xml の jar ファイル及び、XML document と Java Object をマッピングする JAXB の jar を指定して pyspark を起動します。
$ pyspark --jars spark-xml_2.12-0.14.0.jar,jaxb-core-3.0.0-M2.jar
Python 3.8.10 (default, Sep 28 2021, 16:10:42)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
2021-10-19 22:26:57,756 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/__ / .__/\_,_/_/ /_/\_\ version 3.1.2
/_/
Using Python version 3.8.10 (default, Sep 28 2021 16:10:42)
Spark context Web UI available at http://xxxxx:4040
Spark context available as 'sc' (master = local[*], app id = local-1634650023016).
SparkSession available as 'spark'.
>>> 3-2. DataFrame を作成するために pyspark.sql.SparkSession をインポートし、SparkSession を作成します。
>>> from pyspark.sql import SparkSession
>>> spark = SparkSession.builder.getOrCreate()3-3. books.xml ファイルからデータを読み取り DataFrame に入れます。
>>> df = spark.read.format('xml').options(rowTag='book').load('appbox/books.xml')
>>> df.show()
+-----+--------------------+--------------------+---------------+-----+------------+--------------------+
| _id| author| description| genre|price|publish_date| title|
+-----+--------------------+--------------------+---------------+-----+------------+--------------------+
|bk101|Gambardella, Matthew| An in...| Computer|44.95| 2000-10-01|XML Developer's G...|
|bk102| Ralls, Kim|A former architec...| Fantasy| 5.95| 2000-12-16| Midnight Rain|
xxx (省略) xxxx
|bk111| O'Brien, Tim|The Microsoft MSX...| Computer|36.95| 2000-12-01|MSXML3: A Compreh...|
|bk112| Galos, Mike|Microsoft Visual ...| Computer|49.95| 2001-04-16|Visual Studio 7: ...|
+-----+--------------------+--------------------+---------------+-----+------------+--------------------+3-4. さらに _id および author の情報のみ抽出し、新しい xml ファイル “newbooks43.xml” に保存し、中身を確認します。
>>> df.select("author", "_id").write.format('xml').options(rowTag='book', rootTag='books').save('appbox/newbooks43.xml')
>>> df43 = spark.read.format('xml').options(rowTag='book').load('appbox/newbooks43.xml')
>>> df43.show()
+-----+--------------------+
| _id| author|
+-----+--------------------+
|bk101|Gambardella, Matthew|
|bk102| Ralls, Kim|
xxx (省略) xxxx
|bk111| O'Brien, Tim|
|bk112| Galos, Mike|
+-----+--------------------+3-5. 最後に、Spark UI で Spark のジョブ実行履歴を確認します。

▼4. spark-shell (Scala) を使い、XML ファイルのデータの一部抽出し別のファイルに保存
pyspark 同様に spark-shell の scala でも同様の操作を行ってみます。以下の順に進めます。
- spark-xml の jar ファイルを指定して spark-shell を起動します。
- 上記 3 同様に books.xml ファイルからデータ部分読み取り、_id および author の情報のみ抽出します。
4-1. spark-xml の jar ファイルを指定して spark-shell を起動します。
$ $SPARK_HOME/bin/spark-shell --packages com.databricks:spark-xml_2.12:0.14.0
:: loading settings :: url = jar:file:/home/hadoop/spark/jars/ivy-2.4.0.jar!/org/apache/ivy/core/settings/ivysettings.xml
Ivy Default Cache set to: /home/hadoop/.ivy2/cache
The jars for the packages stored in: /home/hadoop/.ivy2/jars
com.databricks#spark-xml_2.12 added as a dependency
:: resolving dependencies :: org.apache.spark#spark-submit-parent-06044b31-f2eb-4b01-b819-f3ac50700450;1.0
confs: [default]
found com.databricks#spark-xml_2.12;0.14.0 in central
found commons-io#commons-io;2.8.0 in central
found org.glassfish.jaxb#txw2;2.3.4 in central
found org.apache.ws.xmlschema#xmlschema-core;2.2.5 in central
:: resolution report :: resolve 584ms :: artifacts dl 20ms
:: modules in use:
com.databricks#spark-xml_2.12;0.14.0 from central in [default]
commons-io#commons-io;2.8.0 from central in [default]
org.apache.ws.xmlschema#xmlschema-core;2.2.5 from central in [default]
org.glassfish.jaxb#txw2;2.3.4 from central in [default]
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 4 | 0 | 0 | 0 || 4 | 0 |
---------------------------------------------------------------------
:: retrieving :: org.apache.spark#spark-submit-parent-xx44b31-f2eb-4b01-b819-f3ac50700xxx
confs: [default]
0 artifacts copied, 4 already retrieved (0kB/24ms)
2022-05-15 21:24:33,501 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
Spark context Web UI available at http://xxxx:4040
Spark context available as 'sc' (master = local[*], app id = local-xx526174870xx).
Spark session available as 'spark'.
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/___/ .__/\_,_/_/ /_/\_\ version 3.1.2
/_/
Using Scala version 2.12.10 (OpenJDK 64-Bit Server VM, Java 1.8.0_292)
Type in expressions to have them evaluated.
Type :help for more information.
scala> 4-2. 上記 3 同様に books.xml ファイルからデータ部分読み取り、_id および author の情報のみ抽出します。
scala> import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.SparkSession
scala> import com.databricks.spark.xml._
import com.databricks.spark.xml._
scala> val spark=SparkSession.builder().getOrCreate()
spark: org.apache.spark.sql.SparkSession = org.apache.spark.sql.SparkSession@56cd8903
scala> val df=spark.read.option("rowTag","book").xml("appbox/books.xml")
df: org.apache.spark.sql.DataFrame = [_id: string, author: string ... 5 more fields]
scala> val selectedData = df.select("author","_id")
selectedData: org.apache.spark.sql.DataFrame = [author: string, _id: string]
scala> selectedData.show()
+--------------------+-----+
| author| _id|
+--------------------+-----+
|Gambardella, Matthew|bk101|
| Ralls, Kim|bk102|
xxx (省略) xxxx
| O'Brien, Tim|bk111|
| Galos, Mike|bk112|
+--------------------+-----+▼5. 参考情報
(1) databricks/spark-xml: XML data source for Spark SQL and DataFrames (github.com)
(2) JAXB (javaee.github.io)
(3) pyspark.sql.SparkSession — PySpark 3.2.1 documentation (apache.org)
以上です。参考になりましたら幸いです。