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

固有の検証

本節では、 SASAX を用いて XML 文書中の値の検証プロセスをカスタマイズする方法について説明します。

値の検証

SASAX は XML Schema 定義における強制(constraint)のように、 検証をカスタマイズする機構を提供しています。

XML 文書解析において、 ValueElement (実際はその派生クラス)は、 要素の終了(= 自身の "endElement()" メソッドの起動)時に、 XML 文書中のテキストを基にして、 まずは対応する型の Java オブジェクトを生成します。 例えば、 IntElementjava.lang.Integer を、 DateElementjava.util.Date のオブジェクトを生成します。

次に、 ValueElement は 自身の addValidation() によって登録された "Validation" インスタンスに対して、 validate() メソッドを起動します。 Validation は、 固有の検証ストラテジを表現するためのインタフェースで、 以下のメソッドのみを宣言しています。


public Object validate(ParseContext context, Object value)
    throws SAXException;

validate() の宣言

ValueElementValidation に対して、 (1) 指定された値が固有検証の条件を満たすならば適切なオブジェクトを、 (2) それ以外の場合には例外を浮揚することを期待しています。

備考: Validation インタフェースの定義上は、 引数として指定されたものとは別のオブジェクトを返却したり、 不適切なクラス (例: IntElement 検証での java.util.Date ) のオブジェクトを返却するといった行為も (実行時に問題を発生させるでしょうが)可能です。

利用者の視点で見る場合、 他の人が開発した Validation 実装の使用には注意してください。

開発者の視点で見る場合、 validate() メソッド内部で新たに生成するのではなく、 極力指定されたオブジェクトそのものを返却するようにして下さい。

複数の Validation が登録されている場合、 ValueElement は直前の Validation が返却した値を用いて、 次の Validationvalidate() メソッドを起動します。 そのため、 複雑な検証を複数の Validation インスタンスの組み合わせで表現できるだけでなく、 固有の Validation を再利用することもできます。

固有検証の定義

例えば、 指定値の偶数性を検証する IntElement 用の Validation 実装コードは以下のようになります。


public Object validate(ParseContext context, 
                       Object value)
    throws SAXException
{
    int i = ((Integer)(value)).intValue();
    if(0 != (i % 2)){
        String message = value.toString();
        throw new SAXNotRecognizedException(message);
    }
    return value;
}

検証の実装

備考: 実のところ、 (1)'value' を 'java.lang.Number' にダウンキャストし、 (2)Number#longValue() で得られた 'long' 値により偶数性を検証し、 (3)'value' そのものを返却するようにすることで、 この検証実装を IntElement だけでなく他の NumberElement 派生クラスでも使用することができます。

XML Schema では、 偶数の末尾数字が 0, 2, 4, 6 ないし 8 のいずれかであることを利用して、 このような制約を "[02468]$" という "pattern" 強制(constraint)として記述することもできますが、 この種の(ロジックによる)制約を直接は提供していません。

文書の解析Parse

"文書の解析" に示すコードにより、 '偶数性制約' を持って XML 文書を解析することが出来ます。 "ValidationDemo" は Validation 実装クラスです。


String uri = "http://www.lares.dti.ne.jp/~foozy/";

IntElement intElement =
    new IntElement(null, uri, "int");

intElement.addValidation(new ValidationDemo());

ElementDrivenHandler handler =
    new ElementDrivenHandler(intElement);

handler.parse(reader);

文書の解析

この起動は、以下の条件を満たす XML 文書を受理します。

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


次節「値検証の制御」へ

詳細情報

クラス図

本節におけるクラス図を以下に示します。

クラス図
クラス図 (クリックで拡大表示)

色づけされているのが本節で定義するクラスで、 それ以外は SASAX において定義済みです。

クラス名

本チュートリアルでは、 クラスは全てクラス名のみで表記されています。 完全な名称は以下の通りです。

表記完全名
DateElement jp.ne.dti.lares.foozy.sasax.DateElement
ElementDrivenHandler jp.ne.dti.lares.foozy.sasax.ElementDrivenHandler
IntElement jp.ne.dti.lares.foozy.sasax.IntElement
NumberElement jp.ne.dti.lares.foozy.sasax.NumberElement
ParseContext jp.ne.dti.lares.foozy.sasax.ParseContext
Validation jp.ne.dti.lares.foozy.sasax.Validation
ValueElement jp.ne.dti.lares.foozy.sasax.ValueElement