|
このページではXalanをクラスライブラリとして使い、
JavaアプリケーションでXML文書とXSLスタイルシートからHTML文書を生成するサンプルを紹介します。
まず最初はコマンドラインのJavaアプリケーション、
ついでXSLT変換をWebサーバ上で行うサーブレット(!!)です。
なんかすさまじそうですが実際のコード例はそれほど難解でもないと思います。
ここのコードはXalan-2.2に入っているサンプルプログラムを参考に作りました。
まず、XML文書ファイルのパスを引数で指定するコマンドラインアプリケーションのサンプルです。
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerConfigurationException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Xalan1 {
public static void main(String[] args)
throws TransformerException, TransformerConfigurationException {
String media= null, title = null, charset = null;
if(args.length != 1){
System.err.println("usage: Xalan1 in.xml > out.html");
return;
}
String xmlFileName = args[0];
try {
TransformerFactory factory = TransformerFactory.newInstance();
// XML文書に記述されているXSLスタイルシート(.xsl)を取得します。
// 実際のXSLスタイルシートのパスの解決は、XML文書のパスからの
// 相対パスになります。(JavaVMの実行時のカレントディレクトリは
// 無関係です)
Source stylesheet = factory.getAssociatedStylesheet
(new StreamSource(xmlFileName), media, title, charset);
Transformer transformer = factory.newTransformer(stylesheet);
// 標準出力に出力したいとき
transformer.transform(new StreamSource(xmlFileName),
new StreamResult(System.out));
// ファイルに出力したいとき
//transformer.transform(new StreamSource("fooX.xml"),
// new StreamResult(new java.io.FileOutputStream("foo.out")));
} catch (Exception e) { e.printStackTrace(); }
}
}
|
今度は、
XML文書ファイル、XSLスタイルシートのパスを、
両方とも引数で指定するコマンドラインアプリケーションのサンプルです。
こちらの方が少しだけ処理は短くなります。
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerConfigurationException;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Xalan2 {
public static void main(String[] args)
throws TransformerException, TransformerConfigurationException,
FileNotFoundException, IOException {
String xmlFileName, xslFileName;
if(args.length != 2){
System.err.println("usage: Xalan2 in.xsl in.xml > out.html");
return;
}
xslFileName = args[0];
xmlFileName = args[1];
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(xslFileName));
transformer.transform(new StreamSource(xmlFileName), new StreamResult(System.out));
}
}
|
上記の例を統合して、
- XSL文書のパスをコマンドラインオプション(-xsl)で指定する場合
- XSL文書のパスをXML文書の記述の中から取得する場合
の両方に対応した、簡単なコマンドラインツールを作ってみました。
XalanTool.java
そして、WebブラウザからXML文書が要求されたときに呼ばれ、
その文書にXSLT変換をかけてHTML文書で送信するサーブレットのソースプログラムです。
package oppadmin;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.net.URL;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
public class SimpleXSLTServlet extends HttpServlet {
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
protected static URL getDocumentPath(HttpServletRequest request,
ServletContext sc) throws IOException {
URL url = null;
try{
url = sc.getResource(request.getServletPath());
} catch(Throwable e){ e.printStackTrace(); }
if(url == null){
String pathTranslated = request.getPathTranslated();
if(pathTranslated != null) {
File f = new File(pathTranslated);
if(f.isFile()){
String path = f.getCanonicalPath();
path = path.replace(File.separatorChar, '/');
url = new URL("file", null, path);
}
}
}
return url;
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
//response.setContentType("text/html; charset=UTF-8");
response.setContentType("text/html; charset=Shift_JIS");
PrintWriter out = response.getWriter();
try {
//out.println("要求されたXML-URL:" + request.getRequestURI());
URL xmlURL = getDocumentPath(request, getServletContext());
if(xmlURL == null) {
response.sendError(response.SC_NOT_FOUND, request.getRequestURI());
return;
}
TransformerFactory factory = TransformerFactory.newInstance();
//Source xmlSource = new StreamSource(xmlURL.openStream());
Source xmlSource = new StreamSource(xmlURL.toExternalForm());
//Source xslSource = new StreamSource(new URL("file:abc.xsl").openStream());
String media = null, title = null, charset = null;
Source xslSource = factory.getAssociatedStylesheet(xmlSource, media, title, charset);
Transformer transformer = factory.newTransformer(xslSource);
transformer.transform(xmlSource, new StreamResult(out));
} catch (Exception e) {
out.write(e.getMessage());
e.printStackTrace(out);
}
out.close();
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
|
これをサーブレットとして動作させるための作業手順は次の通りです。
ここではWebアプリケーションサーバのホームディレクトリを
$TOMCAT_HOME で、アプリケーションのコンテキストパス名を app とします。
(動作確認はJakarta Tomcat 4.0.2で行っています。)
- ビルドしたクラスファイル SimpleXSLTServlet.class を、
$TOMCAT_HOME/app/WEB-INF/classes/oppadmin にコピーします。
/oppadmin の部分はソースコード中のパッケージ修飾と対応させる必要があります。
つまり、ここでは「package oppadmin;」なので、/oppadminになっています。
- $TOMCAT_HOME/app/WEB-INF/web.xml に次の記述を書き加えます。
これで、Webブラウザから *.xml というファイルが要求されたら、
このサーブレットがインボークされることことになります。
<servlet>
<servlet-name>XSL</servlet-name>
<servlet-class>oppadmin.SimpleXSLTServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>XSL</servlet-name>
<url-pattern>*.xml</url-pattern>
</servlet-mapping>
|
- Webアプリケーションサーバを再起動します。
- Webブラウザから、appコンテキスト内にある*.xmlファイルにアクセスしてみて、
HTML形式で出力されてくることを確認します。
(first uploaded 2002/04/21 last updated 2002/10/06, KQ Taura)
|