入力ストリームに対してXSLTを適用するフィルタストリームです。
Javaプログラム中で、RSS0.9/1.0/2.0/Atom0.3をRSS1.0に変換するXSLTをつかって、RSSを正規化するために作りましたが、もちろんXSLT変換一般に使えます。

FilterInputStream?について

FilterInputStream?は、フィルタ処理をするInputStream?の上位クラスとして用意されたクラスです。

 

Javaでは、

InputStream inp = new BufferedInputStream( new FileInputStream( "a.txt" ) );

a.txt ---> FileInputStream ---> BufferedInputStream ---> ユーザプログラム

などというように入力ストリームを多段に使う事がよく行われます。

 

FilterInputStream?は、
read() や close() など InputStream?が実装しなければいけないメソッドに関して、
in.read() 、 in.close() など、フィールド属性の

protected InputStream in;

を操作した結果を返すように実装されています。

 

そこで、フィルタ処理を行うInputStream?を作るときには、FilterInputStream?を継承して、コンストラクタのみをオーバーライドします。
コンストラクタで一旦全てのデータを受信してデータ変換を行い、
結果のbyte[]をByteArrayInputStream?にラップしてinにセットしてやれば、
簡単にフィルタ処理を行うInputStream?を作ることができます。
そして、大量の受信をするのでなければそれで十分。今回もその方式でいきます。

XML --(HTTP等)--> |XSLTFilterInputStream           |       
                  |  ↓XSLT適用                    |
                  |byte[]                          |
                  |  ↓ByteArrayInputStreamでwrap  |
                  |  in ---------------------------+--(InputStream)--> ユーザプログラム

javax.xml.transformについて、

JDK1.4から標準で入っています。
xml系の他のライブラリと同じように、TransformerFactoryからTransformerを作り、Transformerで変換します。
まぁ、実際にソースコード(getTranslatedXML())を見てみれば一目瞭然。

ソースコード

/**
 * 入力ストリームに対してXSLTを適用するフィルタストリーム.
 * <pre>
 * 入力ストリームに対してXSLTを適用するフィルタストリームです。
 * </pre>
 * @author kagyuu
 * @version $Id$
 */
public class XSLTFilterInputStream extends FilterInputStream {
 /**
  * コンストラクタ.
  * @param xsltFileName xsltのファイル名
  * @param xmlInput 変換対象のサイトURL
  * @throws IOException xsltファイルもしくはhtmlが読み込めなかった
  * @throws TransformerException XSLT変換エラー
  */
 public XSLTFilterInputStream(String xsltFileName, String xmlUrlString)
   throws IOException, TransformerException {
   super(null);

   // ファイルを開く
   InputStream xsltInput =
     new BufferedInputStream(new FileInputStream(xsltFileName));

   // URL接続を開く
   URL xmlUrl = new URL(xmlUrlString);
   HttpURLConnection httpConn = (HttpURLConnection) xmlUrl.openConnection();
   httpConn.setRequestMethod("GET");

   InputStream xmlInput = httpConn.getInputStream();

   // 変換結果をinフィールドに格納
   in = getTranslatedXML(xsltInput, xmlInput);
 }

 /**
  * コンストラクタ.
  * @param xsltInput xsltが得られるInputStream
  * @param xmlInput 変換対象のxmlが得られるInputStream
  * @throws TransformerException XSLT変換エラー
  */
 public XSLTFilterInputStream(InputStream xsltInput, InputStream xmlInput)
   throws TransformerException {
   // 上位クラスのコンストラクタ呼び出し
   // 基底となる入力ストリーム(this.in)は後で指定するのでここではnullを指定
   super(null);

   // 変換結果をinフィールドに格納
   in = getTranslatedXML(xsltInput, xmlInput);
 }

 /**
  * 上位クラスのコンストラクタを無効化します
  * @param arg0
  */
 private XSLTFilterInputStream(InputStream arg0) {
   super(arg0);
 }

 /**
  * XMLをXSLTで変換して、変換結果を取り出すInputStreamを返す.
  * <pre>
  * XMLをXSLTで変換して、変換結果をByteArrayInputStreamにwrapします。
  * </pre>
  * @param xsltInput xsltが得られるInputStream
  * @param xmlInput 変換対象のxmlが得られるInputStream
  * @return 結果を取り出すInputStream
  * @throws TransformerException XSLT変換エラー
  */
 private InputStream getTranslatedXML(
   InputStream xsltInput, InputStream xmlInput) throws TransformerException {
   // Transformerの作成 
   TransformerFactory trfactory = TransformerFactory.newInstance();
   Transformer t = trfactory.newTransformer(new StreamSource(xsltInput));

   // xmlInputに、XSLTを適用する
   ByteArrayOutputStream bufStream = new ByteArrayOutputStream();
   t.transform(new StreamSource(xmlInput), new StreamResult(bufStream));

   // 基底となる入力ストリーム
   return new ByteArrayInputStream(bufStream.toByteArray());
 }
}

Java


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS   sitemap
Last-modified: 2006-02-18 (土) 13:38:33 (6634d)
Short-URL: https://at-sushi.com:443/pukiwiki/index.php?cmd=s&k=18616139e0
ISBN10
ISBN13
9784061426061