XSLT スタイルシートは(特にロジックなどを)書くのが結構大変。 以前から RELAX NG Compact Syntax のような簡略記法がないかなぁと思っていましたが、Groovy の Builder を使うとこの目的が達せられるかと思いチョット試してみました。
変換対象の XML データ
まずは変換対象の XML データ。 簡単のため、名前空間は使用しないことにしましょう:
<?xml version="1.0"?> <Groovy-Projects> <Groovy latest-version="1.7.2"> <url>http://groovy.codehaus.org/</url> <description>An agile dynamic language for the Java Platform</description> </Groovy> <Gant latest-version="1.9.2"> <url>http://gant.codehaus.org/</url> <description>A Groovy-based build system that uses Ant tasks, but no XML.</description> </Gant> <GMaven latest-version="1.2"> <url>http://docs.codehaus.org/display/GMAVEN/Home</url> <description>GMaven provides integration of Groovy into Maven.</description> </GMaven> <Griffon latest-version="0.3.1"> <url>http://griffon.codehaus.org/</url> <description>A Grails-like Rich Internet Framework</description> </Griffon> <Grails latest-version="1.3.1"> <url>http://grails.org/</url> <description>a Groovy-based web framework inspired by Ruby on Rails</description> </Grails> </Groovy-Projects>
Groovy の Builder を用いたスタイルシート
では肝心のスタイルシートを見ていきましょう。
まずは準備としての Builder のインスタンスを取得します。 ここでは結果のスタイルシートを XML を内容とする文字列として取得するために StringWriter のインスタンスを作成してそれを MarkupBuilder に渡します。
def writer = new StringWriter() def builder = new groovy.xml.MarkupBuilder(writer)
さて、次がスタイルシートを構築する Builder を使ったコードです:
builder.'xsl:stylesheet'( version:'1.0', xmlns:'http://www.w3.org/TR/xhtml1/strict', 'xmlns:xsl':'http://www.w3.org/1999/XSL/Transform'){ 'xsl:template'(match:'/'){ html{ head{ title('Hello, Groovy world !') } body{ table(border:'1'){ tr{ th('Project Name') th('Latest Version') th('Description') } 'xsl:apply-templates'(select:'*') } } } } 'xsl:template'(match:'/Groovy-Projects/*'){ tr{ th{ a{ 'xsl:attribute'(name:'href'){ 'xsl:value-of'(select:'url') } 'xsl:value-of'(select:'local-name()') } } td{'xsl:value-of'(select:'@latest-version')} td{'xsl:value-of'(select:'description')} } } }
- XML 形式で書くのに比べれば、書くのも読むのも楽だと思いませんか?
- チョット面倒なのは、名前空間接頭辞を使用するには名前にコロン (:) が必要なため、XSLT のタグを全てシングルクォート (') で囲む必要があるところでしょうか。 XSLT の名前空間をデフォルト名前空間にしても(接頭辞を使わないようにしても)、HTML タグの方に名前空間を使わないといけなくなるので、あまり簡単にはなりません。 そもそも、XSLT のタグにはハイフン (-) を含むものがいくつもあるので、結局はシングルクォートで囲む必要はありますが。
- if, choose などのロジックを書くときに簡潔さの有難味がもっとありそう。
- Groovy の Builder は混合内容モデル*1を使えませんが、xsl:text 要素を使えば問題ないでしょう。
スタイルシートが取得できれば、あとは javax.xml.transform パッケージ内のクラスを用いて XSL 変換を実行します(細かいコードは省略):
def reader = new StringReader(writer.toString()) def stylesheet = new StreamSource(reader) def trans = TransformerFactory.newInstance().newTransformer(stylesheet) // Transformer を用いた変換処理
- 「StreamSource」は javax.xml.transform.StreamSource
- 「TransformerFactory」は javax.xml.transform.TransformerFactory
変換結果の HTML ファイル
上記の変換を施すと、結果として以下の HTML が得られます(見やすさのため、適当に整形しています):
<?xml version="1.0" encoding="UTF-8"?> <html xmlns="http://www.w3.org/TR/xhtml1/strict"> <head> <title>Hello, Groovy world !</title> </head> <body> <table border="1"> <tr> <th>Project Name</th><th>Latest Version</th><th>Description</th> </tr> <tr> <th><a href="http://groovy.codehaus.org/">Groovy</a></th><td>1.7.2</td> <td>An agile dynamic language for the Java Platform</td> </tr> <tr> <th><a href="http://gant.codehaus.org/">Gant</a></th><td>1.9.2</td> <td>A Groovy-based build system that uses Ant tasks, but no XML.</td> </tr> <tr> <th><a href="http://docs.codehaus.org/display/GMAVEN/Home">GMaven</a></th> <td>1.2</td><td>GMaven provides integration of Groovy into Maven.</td> </tr> <tr> <th><a href="http://griffon.codehaus.org/">Griffon</a></th><td>0.3.1</td> <td>A Grails-like Rich Internet Framework</td> </tr> <tr> <th><a href="http://grails.org/">Grails</a></th><td>1.3.1</td> <td>a Groovy-based web framework inspired by Ruby on Rails</td> </tr> </table> </body> </html>
ブラウザで表示するとこんな感じ:
Project Name | Latest Version | Description |
---|---|---|
Groovy | 1.7.2 | An agile dynamic language for the Java Platform |
Gant | 1.9.2 | A Groovy-based build system that uses Ant tasks, but no XML. |
GMaven | 1.2 | GMaven provides integration of Groovy into Maven. |
Griffon | 0.3.1 | A Grails-like Rich Internet Framework |
Grails | 1.3.1 | a Groovy-based web framework inspired by Ruby on Rails |
どうでしょう?
- 作者: Dierk Konig,Andrew Glover,Paul King,Guillaume Laforge,Jon Skeet,杉浦孝,櫻井正樹,須江信洋,関谷和愛,佐野徹郎,寺沢尚史
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2008/09/27
- メディア: 単行本(ソフトカバー)
- 購入: 5人 クリック: 146回
- この商品を含むブログ (121件) を見る
XSLT: Mastering XML Transformations
- 作者: Doug Tidwell
- 出版社/メーカー: Oreilly & Associates Inc
- 発売日: 2008/06
- メディア: ペーパーバック
- クリック: 8回
- この商品を含むブログ (3件) を見る
*1:ある要素下に子テキストと子要素が混在しているもの。 正式には何て言うんですっけ?