public class hiXMLreader extends Object
XMLの解析をシーケンシャルに行う機構です。
MIXED型のXML(<A>xxx<b>kokok</b>yyy</A>のように
テキスト内にタグ構造が混ざったもの)は取り扱いません。
シーケンシャルread()によるXML解析:
read()
を呼ぶたびに順次XMLのノード
hiXMLnode
が取得されます。
XMLのnodeとしてreadされるのは次の4つのいずれかです。
XMLデータはこの4つのnode型として順次取り込まれます。
例えば次のような形です。
<A> TAG:A <B> TAG:B <C>abc</C> TAG:C TEXT:abc END:C </B> END:B <B> TAG:B <C>def</C> TAG:C TEXT:def END:C </B> END:B <D>xyz</D> TAG:D TEXT:xyz END:D </A> END:A -- readで読み込まれる順 TAG:A TAG:B TAG:C TEXT:abc END:C END:B TAG:B TAG:C TEXT:def END:C END:B TAG:D TEXT:xyz END:D END:A
SAXを使う場合でも発生するイベントの順は同じですが、 SAXはイベント駆動ですので、例えばTEXTイベント(charcterイベント) が起る場合、それがどこのものであるのかは全く分からず、 アプリケーション側で管理する必要があります。
hiXMLreaderではイベント駆動ではなくアプリケーション側から能動的
にreadし、情報を取得します。
このため、Aを読んだら、Aの中の処理、その中でBを読んだらBの処理、
Dを読んだらDの処理という形のプログラムを書くことができます。
最初のnodeをread() if( TAG:A ){ // Aの構造を作る while( read()!=END ){ ※1※2 if( TAG:B ){ ※3 // Aの構造にBを入れる while( read()!=END ){ if( TAG:C ){ // AのBにCを入れる while( read()!=END ){ if( TEXT ){ ※4 // A-B-CにTEXTを入れる } } } } } else if( TAG:D ){ // Aの構造にDを入れる while( read()!=END ){ if( TEXT ){ // TEXT処理 } } } } } ※1 入力終了時はEODが返りますが、EODの後もう一度呼ぶとException が発生するため、万が一の場合でも無限ループにはなりません ※2 実コード while( reader.read(node)!=hiXMLnode.END ) ※3 実コード if( node.isTag("B") ) ※4 実コード while( reader.read(node)!=hiXMLnode.TEXT )
標準的手順:
次のような手順を踏みます。
import otsu.hiNote.*; public class Test { public static void main(String[] args_){ try{ hiXMLreader reader = new hiXMLreader();// インスタンス生成 reader.parseFile("data.xml"); // 入力指定 readXML(reader); // 階層呼び出し } catch(Exception e){ e.printStackTrace(hiU.err); System.exit(1); } } static void readXML(hiXMLreader reader){ hiXMLnode node = new hiXMLnode(); while( reader.read(node)!= hiXMLnode.EOD ){ if( node.type==hiXMLnode.END ) break; System.out.println(node); if( node.type==hiXMLnode.TAG ) readXML(reader); // 階層呼び出し } } }
内部ioスレッド:
ioは内部スレッドでSAXを用いて行われます。
アプリケーションで時間がかかる場合内部のQUEUEサイズ分先読みされます。
SAX部はアプリケーションより先に終了する可能性があります。
通常は意識する必要はありません。
コンストラクタと説明 |
---|
hiXMLreader() |
修飾子とタイプ | メソッドと説明 |
---|---|
static String |
formatXML(String xml_)
XML文字列をインデントバー付きでフォーマットする.
|
static String |
formatXML(String xml_,
long option_)
XML文字列をインデント付きでフォーマットする.
|
static String |
formatXML(String xml_,
String indent1_,
String indent2_)
XML文字列をインデント付きでフォーマットする.
|
static String |
formatXML(String xml_,
String indent1_,
String indent2_,
long option_)
XML文字列をインデント付きでフォーマットする.
|
String |
getSourceName()
ソース名を得る.
|
void |
parse_with_Reader(Reader is_)
指定Readerから読み込む
Readerを使った読み込みは文字コードの不一致が起る可能性
がありますので推奨されません
|
void |
parse(InputStream is_)
指定InputStreamから読み込む.
|
void |
parseFile(String fileName_)
指定ファイルを読み込む.
|
void |
parseString(String str_)
指定文字列をXMLとして読み込む.
|
void |
push(hiXMLnode node_)
nodeを書き戻す.
|
hiXMLnode |
read()
hiXMLnodeを読み込む.
|
int |
read(hiXMLnode node_)
引数の
hiXMLnode にノード情報を読み込む. |
void |
reset()
読み込みをリセットする
|
void |
setQueueSize(int size_)
内部でのXML読読み込み部(SAX)とAP部のQUEUEのサイズ指定.
|
void |
setSourceName(String name_)
ソース名をセットする.
|
int |
skip()
現状レベルのENDまでスキップする.
|
int |
skip(hiXMLnode node_)
現状レベルのENDまでスキップする.
|
public hiXMLnode read()
XMLノードを読み込みhiXMLnode
を返します。
Documentの終わりに達するか、なんらかの異常があると
EODが戻ります。
EODに一度達すると2度目のread()呼び出しはExceptionを
発生します。
最外郭のタグのENDを待つ構造を採る場合EODを待つ必要は
ありません。
public int read(hiXMLnode node_)
hiXMLnode
にノード情報を読み込む.
予め用意したノード構造体にデータを読み込みます。
戻り値はノードのtype情報であり、
emsp;while( reader.read(node)!=hiXMLnode.END ){...}
といった形の制御が可能です。
Documentの終わりに達するか、なんらかの異常があると
EODが戻ります。
EODに一度達すると2度目のread()呼び出しはExceptionを
発生します。
最外郭のタグのENDを待つ構造を採る場合EODを待つ必要は
ありません。
node_
- 読み取りに使うnode構造体public void push(hiXMLnode node_)
書き戻したnodeは次のreadで読み取られます。
複数回pushした場合はpushした最新のpushから順に
readされます。
node_
- 書き戻すnodepublic int skip(hiXMLnode node_)
現在のレベルのENDまでスキップする。
<A> <B> この段階でskipすると <C> <B> <D>..</D> </B> </C> <E>..</E> </B> <--ここまで読み飛ばされ、次に読み込むと</A>が来る </A>
最後に読み取ったnode(この例ではBのEND)が引数にセットされる
node_
- 読み取りに使うnode構造体public int skip()
現在のレベルのENDまでスキップする。
<A> <B> この段階でskipすると <C> <B> <D>..</D> </B> </C> <E>..</E> </B> <-- ここまで読み飛ばされ、次に読み込むと</A>が来る </A>
public void parseFile(String fileName_)
読み込むファイルを指定します。この呼び出しの後、readで情報が順次 読み取ることができます。
fileName_
- ファイル名public void parse(InputStream is_)
読み込む入力ストリームを指定します。この呼び出しの後、readで情報が順次 読み取ることができます。
is_
- 入力ストリームpublic void parseString(String str_)
解析するテキストを指定します。この呼び出しの後、readで情報が順次 読み取ることができます。
str_
- XMLテキストpublic void parse_with_Reader(Reader is_)
Readerを使った読み込みは文字コードの不一致が起る可能性 がありますので推奨されません
is_
- 入力リーダーpublic void reset()
public void setSourceName(String name_)
InputStreamやReaderを指定している時に、仮の名前を与えることができまえす。 エラー発生時にはこの名前がでます。
name_
- 名前public String getSourceName()
設定されているソース名を得ます。 ソース名はparseFile()あるいはsetSourceName()で与えたものです。
public void setQueueSize(int size_)
XMLの読み込み部とAP部は別スレッドで動作させています。
2つのスレッドではQUEUE(hiSyncQue<T>
クラス)を介して
データを移動しています。
parse関数(parseFile(String)
など)の呼び出し前にこの
関数でQUEUEサイズを指定できます。
0は可能な限りQUEUEに入れます。デフォルトは30です。
size_
- サイズpublic static String formatXML(String xml_)
XML文字列をインデントバー付きにフォーマットします。
改行には改行コード"\n"が用いられます。
インデントは"| "バー付きで、5段目毎に"! "となります。
コメント%lt;!-- comment -->がある場合正確な動作は保証しません。
String xml="<a><b><c>CCC</c><d>DDD</d></b><e>EEE</e></a>"; System.out.println(hiXMLreader.formatXML(xml)); ---- <a> | <b> | | <c>CCC</c> | | <d>DDD</d> | </b> | <e>EEE</e> </a>
バー文字列を指定することも出来ます。" "を指定すれば通常のXMLになります。
println(hiXMLreader.formatXML(xml," "," "); --- <a> <b> <c>CCC</c> <d>DDD</d> </b> <e>EEE</e> </a>
xml_
- フォーマットされてないXMLpublic static String formatXML(String xml_, long option_)
formatXML(String xml_)
のオプションを指定する版です。
xml_
- フォーマットされていないXMLoption_
- hiU.NO_COMMENTを指定するとコメントを削除するpublic static String formatXML(String xml_, String indent1_, String indent2_)
formatXML(String xml_)
のバーを指定する版です。
xml_
- フォーマットされていないXMLindent1_
- 基本的なインデント文字列indent2_
- 5段目毎のインデント文字列public static String formatXML(String xml_, String indent1_, String indent2_, long option_)
formatXML(String xml_)
のバーとオプションを指定する版です。
xml_
- フォーマットされていないXMLindent1_
- 基本的なインデント文字列indent2_
- 5段目毎のインデント文字列option_
- hiU.NO_COMMENTを指定するとコメントを削除する