Xalan-Javaプログラミング

 このページではXalanをクラスライブラリとして使い、 JavaアプリケーションでXML文書とXSLスタイルシートからHTML文書を生成するサンプルを紹介します。 まず最初はコマンドラインのJavaアプリケーション、 ついでXSLT変換をWebサーバ上で行うサーブレット(!!)です。 なんかすさまじそうですが実際のコード例はそれほど難解でもないと思います。 ここのコードはXalan-2.2に入っているサンプルプログラムを参考に作りました。


コマンドラインアプリケーション(1)

 まず、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(); }
  }
}


コマンドラインアプリケーション(2)

 今度は、 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


XSLサーブレット

 そして、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で行っています。)
  1. ビルドしたクラスファイル SimpleXSLTServlet.class を、 $TOMCAT_HOME/app/WEB-INF/classes/oppadmin にコピーします。 /oppadmin の部分はソースコード中のパッケージ修飾と対応させる必要があります。 つまり、ここでは「package oppadmin;」なので、/oppadminになっています。
  2. $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>
    

  3. Webアプリケーションサーバを再起動します。
  4. Webブラウザから、appコンテキスト内にある*.xmlファイルにアクセスしてみて、 HTML形式で出力されてくることを確認します。

XML Top

(first uploaded 2002/04/21 last updated 2002/10/06, KQ Taura)

楽天モバイル[UNLIMITが今なら1円] ECナビでポインと Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!


無料ホームページ 無料のクレジットカード 海外格安航空券 解約手数料0円【あしたでんき】 海外旅行保険が無料! 海外ホテル