Java や Kotlin などの JDK 開発環境で、XML をパースする選択肢として StAX パーサーがあります。
要約
StAX Parser は XML ファイルを詳細に解析したいケースで便利です。
JDK 標準の StAX Parser よりも、StAX2 Woodstox を使用することをお勧めします。
XML Parser の選択肢
JDK 標準(外部ライブラリ不要で使える)の XML Paresr は以下のものがあります。
種類 | 特徴 | class |
---|---|---|
DOM (Document Object Model) | XML をツリー構造で処理する | org.w3c.dom.Document javax.xml.parsers.DocumentBuilder |
XPath (XML Path Language) | XPath 文字列で XML 要素にアクセスする | org.w3c.dom.Document javax.xml.parsers.DocumentBuilder javax.xml.xpath.XPath |
SAX (Simple API for XML Proccessing) | イベントベースで XML を解析する | javax.xml.parsers.SAXParser javax.xml.parsers.SAXParserFactory |
StAX (Streaming API for XML) | イベントベースで XML を解析する | javax.xml.stream.XMLInputFactory javax.xml.stream.XMLStreamReader javax.xml.stream.XMLEventReader |
それぞれの簡単な実装については以下の記事がわかりやすいです。
StAX Parser の実装の解説は以下も参考になります。
StAX Parser について
SAX Parser は XML のパース処理を開始したあとは org.xml.sax.helpers.DefaultHandler でイベントを待ち受ける Push 型のイベント駆動パーサーです。
それに対し、StAX Parser は XMLEventReader.hasNext() と XMLEventReader.next() で XML パース時のイベントを順番に取り出して処理をする Pull 型のイベント駆動パーサーです。
StAX Parser であれば、次のイベントを取ってくるタイミングを自由に制御できるため、SAX Parser よりも XML を細かく解析することができます。読み込み元の XML ファイルの先頭から末尾まで、すべてのデータを漏れなく処理したい場合に向いています。
JDK に含まれる StAX Parser は SJSXP
StAX Parser は JDK 6 から使えるようになりました。JDK 6 以上であれば依存関係を追加せずに javax.xml.stream
パッケージを利用できます。
JDK には StAX Parser として SJSXP (Sun Java Streaming XML Parser) com.sun.xml.stream
がバンドルされています。
StAX Parser は以下のように XMLEventReader を取得して解析を開始します。
val factory = XMLInputFactory.newInstance()
val reader = factory.createXMLEventReader(inputStream)
このとき、StAX Parser の実装は自動的に選択されます。ビルド時に StAX Parser ライブラリを一つも含めなければ、SJSXP が使用されます。
SJSXP は StAX を最低限実装しているだけで、パース時のオプションなども最低限であり、期待したいベントを取ってくれないことも多いです。
StAX で XML をパースするのであれば SJSXP よりも、次の Stax2 Woodstox ライブラリを使用することをお勧めします。
Stax2 Woodstox Parser
SJSXP 以外の StAX 実装もあります。
FasterXML により、StAX の拡張として Stax2 API が定義され、その実装として Aalto と Woodstox があります。
Woodstox は StAX の機能を実装し、SJSXP よりも詳細な動作オプションが指定可能であり柔軟です。FasterXML によりしっかりメンテナンスもされているようです。
StAX 仕様準拠の property はこちらに解説があります。
StAX2 および Woodstox がサポートする property はこちらに解説があります。
Stax2 Woodstox をプロジェクトに追加する
Gradle かつ Kotlin なプロジェクトの設定例です。依存関係を追加するだけで使えます。
ライブラリの依存解決リポジトリに mavenCentral()
が定義されていることを確認してください。
settings.gradle.kts
//...
dependencyResolutionManagement {
repositories {
//...
mavenCentral()
}
}
//...
依存関係を追加します。
build.gradle.kts
//...
dependencies {
//...
implementation("com.fasterxml.woodstox:woodstox-core:6.2.8")
//...
}
//...
XMLInputFactory から XMLEventReader を生成します。
Woodstox ライブラリの依存関係を追加していれば SJSXP ではなく Woodstox Parser のインスタンスが生成されます。
val factory = XMLInputFactory.newInstance() as XMLInputFactory2 // WstxInputFactory が生成される
val reader = factory.createXMLEventReader(inputStream) as WstxEventReader // WstxEventReader が生成される
// reader を使って StAX 解析すると、Woodstox 実装でパースされる