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を指定するとコメントを削除する