| MAP | SASAX ドキュメント > チュートリアル > SASAX による解析 > 要素の反復 | << | >> |
本節では、 SASAX を用いて、 反復される要素を解析する方法を説明します。
XML Schema によるスキーマおよび文書例を "文書構造" に示します。
XML Schema によるスキーマ:
<xs:schema
targetNamespace="http://www.lares.dti.ne.jp/~foozy/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:local="http://www.lares.dti.ne.jp/~foozy/">
<xs:simpleType name="int">
<xs:restriction base="xs:integer"/>
</xs:simpleType>
<xs:element name="list">
<xs:complexType>
<xs:sequence>
<xs:element name="int" type="local:int"
minOccurs="0" maxOccurs="unbounded"
form="qualified"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
例:
<foozy:list
xmlns:foozy="http://www.lares.dti.ne.jp/~foozy/">
<foozy:int>
12345678
</foozy:int>
<foozy:int>
23456789
</foozy:int>
<foozy:int>
34567890
</foozy:int>
<foozy:int>
45678901
</foozy:int>
</foozy:list>
対象文書が以下の特徴を持つことがわかります。
前述の文書を解析するためのオブジェクト群は、 "要素オブジェクト(群)の生成" に示すようにして生成されます。
String uri = "http://www.lares.dti.ne.jp/~foozy/"
CompositeElement listElement =
new CompositeElement(null, uri, "list");
ElementRepetition repetition =
new ElementRepetition(listElement);
// "repetition" を
// "listElement" 配下に登録する
listElement.addMustItem(repetition);
IntElement intElement =
new IntElement(repetition, uri, "int");
// "intElement" を
// "repetition" による反復対象に設定
repetition.setElement(intElement);
コンストラクタ引数を見れば、
"intElement" が "listElement" ではなく
"repetition" の子要素であることに気が付くでしょう。
"ElementRepetition" は、
オブジェクト構造上は中間要素であるかのように振舞いますが、
XML 文書構造上は透過的な要素となります。
反復される要素の解析であるにも関わらず、
IntElement
インスタンスが唯一つしか生成されていないことにも気が付くでしょう。
ElementRepetition は、
"setElement()"
されたインスタンスを各反復ごとに再利用するのです。
このことが中間オブジェクトの生成コストを低減させます。
備考:
ElementRepetition の利用で問題が発生する場合は、
(1)ElementRepetition#setElement(Element) 起動の有無と、
(2)反復対象要素の親要素指定を確認してください。
解析の際には、反復された整数値を格納したいと思うでしょう。
反復における確定毎に値を取得する方法の一つは、
"notifyDetermined(ParseContext)"
メソッドをオーバライドすることです。
final LinkedList list = new LinkedList();
String uri = "http://www.lares.dti.ne.jp/~foozy/"
CompositeElement listElement =
new CompositeElement(null, uri, "list");
ElementRepetition repetition =
new ElementRepetition(listElement);
IntElement intElement =
new IntElement(repetition, uri, "int"){
protected void notifyDetermined(ParseContext context){
list.add(getInteger(false));
}
};
// "intElement" を
// "repetition" による反復対象に設定
repetition.setElement(intElement);
getInteger() の引数に関する詳細は、
"固有要素" ないし
API ドキュメントを参照してください。
値の確定通知を受け取るもう一つの方法は、
"Notification" を使用するものです。
オーバライドによるアプローチの利用は十分単純で容易な選択肢ですが、
Notification の利用をお勧めします。
final LinkedList list = new LinkedList();
String uri = "http://www.lares.dti.ne.jp/~foozy/"
CompositeElement listElement =
new CompositeElement(null, uri, "list");
ElementRepetition repetition =
new ElementRepetition(listElement);
IntElement intElement =
new IntElement(repetition, uri, "int");
Notification notification = new Notification(){
public void elementStarted(Element element,
ParseContext context,
Attributes attributes)
throws SAXException
{
// NOP
}
public void elementEnded(Element element,
ParseContext context)
throws SAXException
{
list.add(((IntElement)element).getInteger(false));
}
};
intElement.addNotification(notification);
// "intElement" を
// "repetition" による反復対象に設定
repetition.setElement(intElement);
ちなみに、ElementRepetition は、
Notification の elementEnded() メソッドを
反復の終了時に起動します。ですので、
Notification の登録は、繰り返したい要素に対して行ってくだ
さい。
"文書の解析" に示すコードにより、 XML 文書を解析することが出来ます。
ElementDrivenHandler handler =
new ElementDrivenHandler(listElement);
handler.parse(reader);
ElementDrivenHandler#parse 起動後、
反復された "intElement" が格納した整数値を
list から得ることが出来ます。
チュートリアル本節におけるコードの完全なものは、
配布物の src/demo/sasax/src 配下にある
jp.ne.dti.lares.foozy.sasax.RepetitionDemo です。
このクラスはバイナリ配布版中の demo.jar に含まれています。
本節におけるクラス図を以下に示します。
本節におけるオブジェクト図を以下に示します。
ElementDrivenHandler、CompositeElement および Element 実装クラスにおける処理フローは以下のようになります。
加えてシーケンス図を以下に示します。
本チュートリアルでは、 クラスは全てクラス名のみで表記されています。 完全な名称は以下の通りです。
| 表記 | 完全名 |
|---|---|
| AbstractElement | jp.ne.dti.lares.foozy.sasax.AbstractElement |
| CompositeElement | jp.ne.dti.lares.foozy.sasax.CompositeElement |
| ElementDrivenHandler | jp.ne.dti.lares.foozy.sasax.ElementDrivenHandler |
| ElementRepetition | jp.ne.dti.lares.foozy.sasax.ElementRepetition |
| IntElement | jp.ne.dti.lares.foozy.sasax.IntElement |
| Notification | jp.ne.dti.lares.foozy.sasax.Notification |
| ParseContext | jp.ne.dti.lares.foozy.sasax.ParseContext |
| MAP | SASAX ドキュメント > チュートリアル > SASAX による解析 > 要素の反復 | << | >> |