Home of: [工房 "藤車"] > [SourceForge.net における SASAX]

固有要素

本節では、SASX を用いて、 オブジェクトを XML 文書からアンマーシャリング(un-marshaling) するための固有要素の生成方法を説明します。

文書構造の定義

"文書構造" に示す 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="composite">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="int" type="local:int"
          form="qualified"/>
        <xs:element name="string" type="local:string"
          minOccurs="0"
          form="qualified"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

例:

<foozy:composite
 xmlns:foozy="http://www.lares.dti.ne.jp/~foozy/">
  <foozy:int>
    12245678
  </foozy:int>
  <foozy:string>
    optional text message
  </foozy:string>
</foozy:composite>

文書構造

要素オブジェクト(群)の生成

前述の文書を解析するためのクラスは、 "固有クラス" に示すように定義されます。


public class CustomElement
    extends CompositeElement
{
    final static private String URI =
        "http://www.lares.dti.ne.jp/~foozy/";

    final private IntElement int_ =
        new IntElement(this, URI, "int");

    final private StringElement string_ =
        new StringElement(this, URI, "string");

    ////////////////////////////////////////

    public CustomComposite(Element parent){
        super(parent, URI, "custom");

        addMustItem(int_);
        addOptionalItem(string_);
    }
}

固有クラス

上記の例は、 これまでの節の説明を元に理解することができるでしょう。

勿論、 外部からのアクセスのために、 "int_"(および "string_")を "public" として定義することも可能です。 "文書構造の構築"(= CustomElement の定義そのもの) を "解析における挙動の記述" (例: Notification の追加) から分離することが出来ますから、 "public" として定義するのは良いアイディアだと思います。

確定の保証

XML 文書の解析結果から、 固有コンテナのインスタンスを生成するメソッドの例を、 "CustomContainer の生成" に示します。


final public CustomContainer getValue(boolean ensure){
    if(ensure){ ensureDetermined(); }

    // 未だ確定していない場合
    if(!isDetermined()){ return null; }

    CustomContainer container = new CustomContainer();

    // int_ は必須項目として登録されているので、
    // int_#getInteger は常に非 null を返却するはず
    container.setInteger(int_.getInteger(false));

    // string_ は付加項目として登録されているので、
    // string_#getString は null を返却するかもしれない
    container.setString(string_.getString(false));

    return container;
}

CustomContainer の生成

要素における解析が完了したか否かに応じて、 isDetermined() メソッドは真値/偽値を返しますし、 ensureDetermined()IllegalStateException 例外を浮揚します。 getValue の振る舞いは以下のようになります。

値確定
(= isDetermined())
"ensure" 引数
false true
false null 返却 例外浮揚
true オブジェクト返却 オブジェクト返却

今回のチュートリアルのような状況の場合、 (1) 対象の確定性が既に保証済みであるか、 (2) null 返却を許す場合に限り、 ensure メソッドの引数に "false" を指定すべきです。

前述の int_ および string_ の両者に対して、 getInteger ないし getString メソッド起動における "ensure" 引数として "false" が指定されていますが、 両者の意味合いは同一ではありません。

int_.getInteger() 起動に "false" が指定されているのは、 int_ が必須項目として登録されているために、 CustomElement と同一の確定性を持ち、 且つその確定性は既に保証済みであるので、 確認処理を省略するためです。

string_.getString() 起動に "false" が指定されているのは、 (a) string_ が付加項目として登録されているために、 値の確定確認処理を省略する (省略しない場合、値が未確定の際に例外浮揚要因と成り得る)ためと、 (b) 確定していない場合に null 値を得るためです。

CustomContainer#setString() が null 引数を許さない場合には、 string_ の確定性を確認してから起動する必要があります。

文書の解析

"文書の解析" に示すコードにより、 XML 文書を解析することが出来ます。


CustomElement customElement = new CustomElement(null);

try{
    ElementDrivenHandler handler =
    new ElementDrivenHandler(customElement);

    handler.parse(reader);

    // この位置への到達自体が確定性を保証しているため、
    // "getValue" に "false" を指定しても安全です
    CustomContainer container = customElement.getValue(true);
    // container を用いた処理をここで行う ....
}
catch(Exception e){
    // 以下の記述は例外浮揚を起こし得ます
    customElement.getValue(true);
    // 以下の記述は null を返却し得ます
    customElement.getValue(false);
}

文書の解析

チュートリアル本節におけるコードの完全なものは、 配布物の src/demo/sasax/src 配下にある jp.ne.dti.lares.foozy.sasax.CustomDemo です。 このクラスはバイナリ配布版中の demo.jar に含まれています。


次節「要素の選択」へ

詳細情報

"複合要素" 節の "概要"をご覧下さい。