| MAP | SASAX ドキュメント > チュートリアル > SASAX による解析 > 要素の選択 | << | >> |
本節では、 SASAX を用いて、 実行時に確定する要素を含む XML 文書を解析する方法について説明します。
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:simpleType name="string">
<xs:restriction base="xs:token"/>
</xs:simpleType>
<xs:element name="envelope">
<xs:complexType>
<xs:choice>
<xs:element name="int" type="local:int"
form="qualified"/>
<xs:element name="string" type="local:string"
form="qualified"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
例 - "int" の場合:
<foozy:envelope
xmlns:foozy="http://www.lares.dti.ne.jp/~foozy/">
<foozy:int>
12245678
</foozy:int>
</foozy:envelope>
例 - "string" の場合:
<foozy:envelope
xmlns:foozy="http://www.lares.dti.ne.jp/~foozy/">
<foozy:string>
text message
</foozy:string>
</foozy:envelope>
対象文書が以下の特徴を持つことがわかります。
実行時に利用が選択される要素(群)を扱うためには、 それらの要素のために、 "ファクトリクラスの定義" に示すようなファクトリクラスを定義する必要があります。
public class IntElementFactory
implements ElementFactory //
{
final static private String URI =
"http://www.lares.dti.ne.jp/~foozy/";
final static private String NAME = "int";
final static private NameChecker CHECKER =
new NameChecker(URI, NAME);
////////////////////////////////////////
// Implementation of interface ElementFactory
public boolean accepts(ParseContext context,
String uri,
String lName)
{
return CHECKER.accepts(uri, lName);
}
public Element create(Element parent){
return new IntElement(parent, URI, NAME);
}
}
"IntElementFactory" は、
("accepts()" メソッドにおいて)
指定された名前が受理可能か否かを検証します。
"NameChecker" は、
名前の同一性を検証するためのユーティリティクラスです。
それに加えて、
ファクトリクラスは
("create()" メソッドにおいて)
指定された親の配下に要素オブジェクトを生成します。
"string" 要素のためのファクトリは、
IntElementFactory と同様に定義されます。
前述の文書を解析するためのオブジェクト群は、 "要素オブジェクト(群)の生成" に示すようにして生成されます。
CompositeElement envelopeElement =
new CompositeElement(null, uri, "envelope");
ElementChoice choice =
new ElementChoice(envelopeElement);
envelopeElement.addMustItem(choice);
ですが、ElementChoice 単独では用を成しません。
"ファクトリの登録" に示すようにしてファクトリを登録しなければなりません。
choice.add(new IntElementFactory()); choice.add(new StringElementFactory());
これで、 指定された要素は候補要素のファクトリとして登録されました。
"文書の解析" に示すコードにより、 XML 文書を解析することができます。
ElementDrivenHandler handler =
new ElementDrivenHandler(envelopeElement);
handler.parse(reader);
Element determined = choice.getDetermined();
XML 文書の解析後、
"ElementChoice" クラスの
"getDetermined()" メソッドにより、
確定した要素を取得することが出来ます。
確定した要素がどの要素であるかは、
得られた要素に対して
accepts() メソッドを起動することでも、
"instanceof" 試験をすることでも、判定することができます。
しかし、性能的な面から、
accepts() メソッドを利用する方をお勧めします。
チュートリアル本節におけるコードの完全なものは、
配布物の src/demo/sasax/src 配下にある
jp.ne.dti.lares.foozy.sasax.ChoiceDemo です。
このクラスはバイナリ配布版中の demo.jar に含まれています。
本節におけるクラス図を以下に示します。
本節におけるオブジェクト図を以下に示します。
ElementDrivenHandler、ElementChoice、ElementFactory 実装クラスおよび ElementFactory により生成された Element における処理フローは以下のようになります。
加えてシーケンス図を以下に示します。
本チュートリアルでは、 クラスは全てクラス名のみで表記されています。 完全な名称は以下の通りです。
| 表記 | 完全名 |
|---|---|
| CompositeElement | jp.ne.dti.lares.foozy.sasax.CompositeElement |
| Element | jp.ne.dti.lares.foozy.sasax.Element |
| ElementChoice | jp.ne.dti.lares.foozy.sasax.ElementChoice |
| ElementDrivenHandler | jp.ne.dti.lares.foozy.sasax.ElementDrivenHandler |
| ElementFactory | jp.ne.dti.lares.foozy.sasax.ElementFactory |
| NameChecker | jp.ne.dti.lares.foozy.sasax.NameChecker |
| ParseContext | jp.ne.dti.lares.foozy.sasax.ParseContext |
| IntElement | jp.ne.dti.lares.foozy.sasax.IntElement |
| MAP | SASAX ドキュメント > チュートリアル > SASAX による解析 > 要素の選択 | << | >> |