こちらのリリースです。
Native XML file format support (Public Preview)
XMLファイルフォーマットのネイティブサポートがパブリックプレビューとなりました。XMLファイルフォーマットのサポートによって、バッチ処理やストリーミングにおけるXMLデータの取り込み、クエリー、パースが買おうとなります。スキーマやデータタイプの自動推定や進化が可能となり、
from_xml
のようなSQLエクスプレッションをサポートし、XMLドキュメントを生成します。外部のjarは不要であり、Auto Loader、read_files
、COPY INTO
、Delta Live Tablesとシームレスに動作します。詳細については、XMLファイルの読み取りと書き込みをご覧ください。
プレビュー
本機能はパブリックプレビューです。
これまでは、SparkでXMLを取り扱うためには、spark-xmlなどのライブラリが必要でした。ここではネイティブサポートをウォークスルーします。
要件
Databricksランタイム14.3以降が必要です。
XMLレコードのパース
XMLはツリー構造なので、いきなりテーブル形式にできないケースが多いです。なので、データフレームの行に対応するタグを指定するためのオプションが指定されています。それがrowTag
オプションです。このオプションでデータフレームの行に対応するタグを指定することができます。
最初にXMLファイルを作成します。以下の例ではbooks
タグの配下にbook
タグが並んでいるのがわかります。
val xmlString = """
<books>
<book id="bk103">
<author>Corets, Eva</author>
<title>Maeve Ascendant</title>
</book>
<book id="bk104">
<author>Corets, Eva</author>
<title>Oberon's Legacy</title>
</book>
</books>"""
val xmlPath = "dbfs:/tmp/books.xml"
dbutils.fs.put(xmlPath, xmlString)
ですので、オプションrowTag
にbooks
を指定します。
val df = spark.read.option("rowTag", "books").xml(xmlPath)
df.printSchema()
df.show(truncate=false)
動きました。
root
|-- book: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- _id: string (nullable = true)
| | |-- author: string (nullable = true)
| | |-- title: string (nullable = true)
+------------------------------------------------------------------------------+
|book |
+------------------------------------------------------------------------------+
|[{bk103, Corets, Eva, Maeve Ascendant}, {bk104, Corets, Eva, Oberon's Legacy}]|
+------------------------------------------------------------------------------+
df: org.apache.spark.sql.DataFrame = [book: array<struct<_id:string,author:string,title:string>>]
子要素のbook
をrowTag
に指定します。
val df = spark.read.option("rowTag", "book").xml(xmlPath)
display(df)
SQLのサンプル
DROP TABLE IF EXISTS books;
CREATE TABLE books
USING XML
OPTIONS (path "dbfs:/tmp/books.xml", rowTag "book");
SELECT * FROM books;
Pythonのサンプル
df = spark.read.format('xml').options(rowTag='book').load('dbfs:/tmp/books.xml')
(df.select("author", "_id").write
.options(rowTag='book', rootTag='books')
.xml('dbfs:/tmp/newbooks.xml')
)
new_df = spark.read.format('xml').options(rowTag='book').load('dbfs:/tmp/newbooks.xml')
display(new_df)