JAXPを使ってXSLTを実行
JAXPのAPIを使ってXSLTを実行する方法は前編とほとんど変わりません。リスト4がMeigara.xslからshop.xmlへ変換するためのコードです。
001:private static final String XSLT_PATH = "file:///Users/tomoharu/Documents/XSLSample/XSLTSample02.xsl"; 002:private static final String SOURCE_PATH = "file:///Users/tomoharu/Documents/XMLSample/Meigara.xml"; 003:private static final String RESULT_PATH = "file:///Users/tomoharu/Documents/XMLSample/shop.xml"; 004: 005:protected void processRequest(HttpServletRequest request, HttpServletResponse response) 006:throws ServletException, IOException { 007: 008: response.setContentType("text/html; charset=UTF-8"); 009: 010: try { 011: TransformerFactory transformerFactory = TransformerFactory.newInstance(); 012: Transformer transformer = transformerFactory.newTransformer(new StreamSource(XSLT_PATH)); 013: StreamSource ss = new StreamSource(SOURCE_PATH); 014: StreamResult sr = new StreamResult(RESULT_PATH); 015: // Meigara.xmlからshop.xmlへ変換 016: transformer.transform(ss, sr); 017: // 結果OK画面に遷移する 018: RequestDispatcher rd = request.getRequestDispatcher("/success.jsp"); 019: rd.forward(request, response); 020: } catch (TransformerConfigurationException tce) { 021: tce.printStackTrace(); 022: } catch (TransformerException te) { 023: te.printStackTrace(); 024: } catch (Exception e) { 025: e.printStackTrace(); 026: } 027: 028:}
前編と違う点は、出力がXML文書のため3行目で出力ファイルのパスの変数を定義しているところです。そのパスの変数を14行目でStreamResultコンストラクタの引数に設定しています。生成されたStreamResultを16行目のTransformerのtransformメソッドの第2引数に渡します。第1引数はMeigara.xmlをStreamSourceオブジェクトにしたものを渡しています。shop.xmlは空の文書ですが、16行目の変換により最初に紹介したshop.xml文書が作成されます。リスト5が実際に変換されたshop.xmlです。xsl:outputでインデントを行うよう指定しましたが、XSLTプロセッサはインデントを行っていません。
001:<?xml version="1.0" encoding="UTF-8"?> 002:<SHOP> 003:<GREETING OWNER="tomoharu">店主の好みの芋焼酎を厳選しました。</GREETING> 004:<MEIGARAS> 005: <MEIGARA> 006:<NAME KANA="">がんご焼酎屋</NAME> 007:<ABV UNIT="%">25</ABV> 008:<VOLUME UNIT="ml">1800</VOLUME> 009:<PRICE UNIT="">2630</PRICE> 010:<MANUFACTURER/> 011:</MEIGARA> 012: <MEIGARA> 013:<NAME KANA="">一壺春</NAME> 014:<ABV UNIT="%">25</ABV> 015:<VOLUME UNIT="ml">720</VOLUME> 016:<PRICE UNIT="">1360</PRICE> 017:<MANUFACTURER/> 018:</MEIGARA> 019: <MEIGARA> 020:<NAME KANA="">杜氏潤平紅芋原酒</NAME> 021:<ABV UNIT="%">38</ABV> 022:<VOLUME UNIT="ml">500</VOLUME> 023:<PRICE UNIT="">2050</PRICE> 024:<MANUFACTURER/> 025:</MEIGARA> 026:</MEIGARAS> 027:</SHOP>
まとめ
前編ではXPathとXSLTを体験してもらうことが目的でした。今回の後編で、XPathとXSLTについてさらに掘り下げて説明しました。
- ツリーとノードを整理しました。
- ロケーションパスを説明しました。ロケーションパスは、軸とノードテストと述語によって構成されます。
- 上記2つを理解したのち実際にXSLTスタイルシートを作成しました。
- XSLTスタイルシートの詳しい説明を行いました。
今回は簡単な変換の例を示しましたが、変換したshop.xmlをもっと複雑にして読者の皆さん自らXSLTスタイルシートを作成していただけたらと思います。具体的にはMEIGARA要素を増やし、MEIGARA要素の子要素であるMANUFACTURER要素をMEIGARAの親要素にしたり、NAME要素のKANA属性をNAME要素の兄弟要素に変換することなどで、理解が深まることと思います。
サンプルコード
当記事のプロジェクトのフォルダ構成は図3のとおりです。また、サンプルコードはページトップにあります。ダウンロードしてご使用ください。Meigara.xmlはフォルダ構成上には見えませんが、サンプルコードに含めています。shop.xmlは最初は空のファイルを作成するだけなので、格納していません。
![図3.プロジェクトフォルダ構成](http://cz-cdn.shoeisha.jp/static/images/article/5155/3s.gif)