LixM Wiki

about

このwikiではLixMに関する情報をまとめます。

LixMとは?

javaに最適化された全く新しい先進的なXMLライブラリです。
このライブラリの能力を最大限引き出すにはJDK5.0以上が必要になります。その理由はコレクションフレームワークやジェネリックス及び、拡張for文を活用するからです。 これらを駆使することによってLixMではJavaプログラマにとって簡単で覚えやすい方法でXMLにアクセスすることが可能です。

このwikiの対象者

  • Java開発者である
  • コレクションフレームワークを使ったことがある
  • 5.0で導入されたジェネリックス、拡張for文を理解している
  • XMLを熟知している
  • XMLを扱う必要がある

あなたはXMLを扱うとき、煩雑なDOMや自由に制御できないSAXに困っていませんか? かといって新しいStAXや独自のパーサを理解するのは難しい・時間が無いといったことは無いでしょうか?

LixMはXMLをコレクションフレームワークと全く同じ方法で扱うことが可能です。拡張for文を回しながらXMLにアクセスする事もできます。 これはJDK5.0以降、Javaプログラミングでは自然かつ当たり前な方法となってきています。(古いVer.を使った開発は別として:-))

簡単なコードを以下に示しましょう。

  1. /* import文は簡略化のため省略 */
  2. XMLDocumentList<AbstractModel> list = new XMLDocumentListImpl<AbstractModel>();
  3. XMLModelizer modelizer = new XMLModelizerImpl();
  4. modelizer.setList(list);
  5. modelizer.modelize("http://www.foo.bar/baz.xml");
  6. for(AbstractModel model : list){
  7. System.out.println(model);
  8. }

このコードはhttp://www.foo.bar/baz.xmlというXML文章の全体を標準出力へ書き出すコード片です。 どうでしょうか? どこかで見覚えがありませんか? コレクションフレームワークを使ってリストを走査するコードに似ているのです。 もう少し詳しいことは次のイントロダクションを見てください。

イントロダクション

LixMはXMLをコンテナにフラットに格納し字面上の出現順に依存せずアクセスするインターフェイスを仕様化します。 XMLは文章をモデル化する役割を持ちますがLIXMはそのXMLをモデル化しXML構成要素に対して自由にアクセス可能にします。 LixMには二つの側面があります。一つはXMLへ直感的で自由にアクセス可能なインターフェイス。もう一つは、XML文書をストリームからメモリ内へ保持しておく基本的に不変な中間形式です。 LixMはシーケンシャルなアクセスもランダムなアクセスも可能です。

LixMの仕組みはこうです。まず、XMLをパースしXML宣言、開始タグ・終了タグ、テキスト、PI、CDATAセクション、コメントを字面上の出現順にリストに格納します。 これをモデライズといいます。そしてリストに入っている要素をモデルといいます。このモデルはリストの中で0...n個ほど格納されています。 このとき、リストの最大の長さはn+1となります。

そして、インデックス0には文章の開始のモデルが、nには文章の終了のモデルが格納されています。インデックス1にはXML宣言モデルが格納されます。
つまり、ルート要素の開始タグモデルはインデックス2に、ルート要素の終了タグモデルはn-1に格納されています。
任意のモデルを取得するにはXMLDocumentList<E extends AbstractModel>.get(int)を利用します。このメソッドの戻り値は型Eのモデルです。 このモデルを適切にキャストするにはAbstractModel.getXMLType()をswitch文で使います。

  1. //省略
  2. for(AbstractModel model : list){
  3. switch(AbstractModel.getXMLType()){
  4. case XMLType.START_TAG:
  5. StartTagModel startTag = (StartTagModel)model;
  6. //固有の処理
  7. break;
  8. case XMLType.END_TAG:
  9. EndTagModel endTag = (EndTagModel)model;
  10. //固有の処理
  11. break;
  12. case XMLType.CHARACTERS:
  13. CharactersModel endTag = (CharactersModel)model;
  14. //固有の処理
  15. break;
  16. }
  17. }

XMLTypeが特定のものに一致するか調べることもできます。

  1. AbstractModel model = list.get(0);
  2. if(model.matchTypes(XMLType.START_DOCUMENT)){
  3. System.out.println("XML文書が開始しました。");
  4. }

AbstractModel.matchTypes(int)はモデルが引数のXMLTypeと一致するか調べます。

単純なアクセス方法

簡単なアクセス方法には以下の3つがあります。

  • XMLDocumentList<E extends AbstractModel>.get(int)
  • XMLDocumentList<E extends AbstractModel>.getRootStartTag()
  • XMLDocumentList<E extends AbstractModel>.getRootEndTag()

get(int)は任意の位置のモデルにアクセスします。
getRootStartTag()はルート要素の開始タグへアクセスします。 getRootEndTag()はルート要素の終了タグへアクセスします。

詳細なアクセス制御

カーソルを使う

詳細なアクセス制御を行うにはカーソルを取得します。カーソルとは位置情報を内部に持ったアクセス制御用のオブジェクトです。
カーソルを取得するにはXMLDocumentList<E extends AbstractModel>.getCursor()を使います。 カーソルはあくまで位置情報しか持ちません。そのため、ほとんどのメソッドはXMLDocumentList<E extends AbstractModel>.get(int)に渡すためのint型を返します。 一部のメソッドはモデルを直接返します。

  1. //省略
  2. XMLCursor cur = list.getCursor();
  3. //XMLCursor.inc()は次のインデックスを返す。このとき位置情報が1加算される。
  4. AbstractModel model0 = list.get(cur.inc());
  5. //XMLCursor.next()は次のインデックスを返す。このとき位置情報は加算されない。
  6. AbstractModel model1 = list.get(cur.next());
  7. //XMLCursor.getIndex()は現在の位置を返す。
  8. AbstractModel model2 = list.get(cur.getIndex());
  9. //この出力は"false"を出力する。
  10. System.out.println(model1.matchTypes(model2.getType()));
  11. //この出力は"true"を出力する。
  12. System.out.println(model0.matchTypes(model2.getType()));

標準出力の部分がなぜこうなるかお分かりでしょうか?答えは簡単です。
XMLCursor.inc()は前置インクリメント、XMLCursor.next()は後置インクリメントを行うと覚えてください。

他にも前置デクリメントと語置デクリメントを行うメソッドもあります。

XML文章を行ったり来たりする

XMLCursor.setMark(int)で任意の位置をマークできます。これは現在位置(インデックス)とは別に保持されます。XMLCursor.getMark()でマークした位置を取得できます。
現在位置をマークし、任意の位置をインデックスに設定するメソッドもあります。 XMLCursor.seek(int)です。このメソッドがやっていることは現在位置をいったんマークし、引数の位置にインデックスを設定します。

以下のコードと同一です

  1. int jumpIndex = 47;
  2. cur.setMark(cur.getIndex());
  3. cur.setIndex(jumpIndex);

シーク後はXMLCursor.getMark()で以前に居たインデックスへ戻れます。

簡単な説明は以上です。


メニュー

AdSense is disabled. Please check setting.