Home of: [工房 "藤車"] > [SourceForge.net における 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 における処理フローは以下のようになります。

  1. ElementDrivenHandler が ElementChoice の "startElement" を起動
  2. ElementChoice が ElementFactory(現状は IntElementFactory) の "create" を起動
  3. IntElementFactory は生成した Element(現状は IntElement) を返却
  4. ElementChoice は返却された Element(現状は IntElement) に "startElement" を委譲
  5. IntElement は次のイベント受領者として自身を返却
  6. ElementDrivenHandler は "intElement" を次のイベント受領者として保持
  7. ElementDrivenHandler は "intElement" のメソッドを起動
  8. .....
  9. ElementDrivenHandler は IntElement の "endElement" を起動
  10. IntElement は生成時に指定された 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