6 動的制約言語


Contents

この章は規範的である。

6.1 イントロダクション

多くのフォームでは複数のフィールドに作用する完全な制約を定義する。たとえば、ある注文の合計値は単価、数量、値引き、税金、送料などを計算して決定される。このような計算は、ここで規定されるシンタックスを用いて簡潔に表現される。この章では、XPathに基づくことで独自のスクリプト言語を用いることなくそれらの式を利用可能にする、XForms動的制約言語(DCL)について説明する。

動的制約は、フォームコントロールまたはサブフォームが他の値によって入力が必要になる状況を、宣言的に記述する場合にも便利である。さらなる利用としては、他の値に依存する場合に、そのフォームコントロールの利用できる選択肢を関数的に定義することがある。

編注: 簡潔にするために、この章は現在定義しているDCLをサブセットのないXPathに基づくものとしている。しかし、読者は注意すべきである。この問題はXFormsワーキンググループ内で十分にコンセンサスを得たものではないのである。思案中の個別の論点に関しては、この章を通して記述される。

以降の文法では、用語にないNCName[XML Names]で定義されており、またS[XML 1.0]で定義されている。

6.2 データ型

XForms動的制約はXFormsデータ型に設計を加えている:

string, Boolean, number 型は、それらのXPathで定義されている型に一致する。日付、時間、期間、金額の値などはstringのサブタイプとする。さらに、XPathデータ型node-setおよびnullがXForms動的制約言語で使用できる。

リソースの限られたXForms処理系では、実装におけるnode-setの最大サイズを限定定義しても良い。

[編集者のフィードバックリクエスト 6.2.移植: XPathは特定の型変換を定義している。XFormsワーキンググループではそれらをXForms動的制約に含めるべきか、排除すべきか思案中である。いずれにしても、異なる型を含む命令のための、整定義の(well-defined)セマンティクスが存在することになろう。関連団体(the community)からのコメントを歓迎する。]

もし命令が実行できなかった場合、例外が投げられる。例外はイベントとして扱われ、XMLまたはスクリプトで宣言されたイベントハンドラによってキャッチできる。

スタンドアロンのXFormsデータ型は有効なXForms動的制約と考えられている。

編注: ここで説明するものは、現在はXPathに見られるものを適切に参照したものでも拡張したものでもない。

[1] Digit    ::=    [0-9]  
[2] HexDigit    ::=    Digit
| ['a' - 'f']
| ['A' - 'F']
 
[3] NullExp    ::=    'null'  
[4] BoolExp    ::=    'true' | 'false'  
[5] NumberExp    ::=    0x[HexDigit]+
| [['-']Digit+['.' Digit*] [('e' | 'E')['+' | '-']Digit+]
 
[6] StringExp    ::=    '"' NCName? '"' | "'" NCName? "'"  
[7] ArrayExp    ::=    '[]' | [Expr [',' Expr]*]  

6.3 バインディング式

XPathのように、XForms DCLはXMLドキュメントを、ノードのツリーのモデルとして扱う。ノードには、エレメントノード、アトリビュートノード、テキストノードと、異なる種類がある。XPathでは'/'をロケーションステップ区切り子として用いる。XMLでは、紛らわしいので'/'文字をエレメントあるいはアトリビュートの名前として許容しない。

XPathはさらにシーケンスにおけるn番目のエレメントを表す、配列インデックスの表記法を許す。たとえばこの、注文におけるitemのラインである。

<purchaseOrder orderDate="1999-10-20">
  <item partNum="872-AA">
      ...
  </item>
  <item partNum="926-AA">
      ...
  </item>
</purchaseOrder>

注文の2つ目のアイテムは次のようにアドレスを表すことができる:

XPath同様、配列の添字は0でなく1から始まる。作成者はこのことを考慮すべきである。特にスクリプティングとXFormsを組み合わせるアプリケーションを作成するときなどである。

XPathは属性をアドレスで表すこともできる。たとえば、このpurchaseOrderエレメントにおけるorderDate属性は、次のようにアドレスを表すことができる:

2番目のitemのpartNum属性のアドレスを表すときは、次のように書けば良い:

XPathとして、全てのアドレッシングはコンテキストノードの概念に基づいている。多くの状況では、コンテキストノードを用いることで、より短い識別が可能になる。例として、前出の2番目のitemエレメントがコンテキストノードとして選択されている場合、そのpartNum属性は次のようにアドレスを表すことができる:

識別子は左から右に評価される。識別子の値は上記の型のいずれか1つに解釈されなければならない。識別子のシンタックスはXPathに基づいており、そのセマンティクスに従っている。もし識別子がエレメント名で始まった場合、その名前はカレントコンテキスト(のスコープ)中または祖先のコンテキスト中になければならない。もし識別子が解釈不可能であれば、無効な識別子の例外が投げられる。

[編集者のフィードバックリクエスト 6.3.ns: どのような範囲でバインディング式はそれら自身をネームスペース付きで認識する必要があるか?(説明を簡単にするために、この仕様案では今のところネームスペース無考慮の形でバインディング式を扱っていることに注意)]

[8] Identifier    ::=    (('/'
| '../'
| element-name) ['[' Expr ']'])+
 
[9] PathExp    ::=    identifier ['@' attribute-name]
| '@' attribute-name
 

6.3.1 ルートとコンテキストノード

バインディング式はしばしば 特定のインスタンスデータアイテムを指すように用いられる。 その役割で用いられた場合、どのようにデータが選択されるかは、以下のルールで決定される:

  1. バインディング式のルートノードは、仮想的なインスタンスデータ である <instance> エレメントを参照する。たとえば:
  2. アドレッシングについては、全てのインスタンスデータ はあたかもローカルリソースであるかのように扱われる。
  3. もしあるバインディング式 が単一ノードのみが要求されるところでコンテキストノードからある1つのnode-setを選択した場合、デフォルトではそのnode-setの最初のノードのみが使用される。
  4. 最も外側のバインディングエレメント(XForms UIエレメントなど)のコンテキストノードは、上で定義した仮想的なインスタンスデータ のルートである。 「バインディング エレメント」とは、明示的にxform:ref 属性を持つことが許されている任意のエレメントである。 XFormsエレメントは、そのXPath式ancestor::*バインディング エレメントノードを含まないとき、「もっとも外側にある」。
  5. バインディング エレメント(XForms UIエレメントなど)で最も外側ではないもののコンテキストノードは、それを直接に囲んでいるエレメントのバインディング式を評価して決定される。エレメントは、それがXPath式ancestor::*で最初の バインディング エレメントノードであるときに「直接に囲んでいる」。これは「スコープのある解決(scoped resolution)」とも呼ばれている。

例:

スコープのあるバインディング式
<someGroupingWidget ref="element1/foo/bar">
  <anotherWidget ref="element2"/>
  <anotherWidget ref="@attr"/>
</someGroupingWidget>

この例では、someGroupingWidgetelement1/foo/barバインディング式 をもつ。 上記のルールによれば、この最も外側のエレメントは、<instance> エレメントである/をコンテキストノードにもつ。 そして、anotherWidgetのどちらも、コンテキストノードを親から継承し、コンテキストノードは/element1/foo/barとなる。 これに基づいて、anotherWidget バインディング式はそれぞれ /element1/foo/bar/element2/element1/foo/bar/@attrを評価する。 マッチするインスタンスデータ は次の通り:

サンプルインスタンスデータ
<instance xmlns="http://www.w3.org/2001/02/xforms">
  <element1 xmlns="...">
    <foo>
      <bar attr="xyz">
        <element2>xyz</element2>
      </bar>
    </foo>
  </element1>
</instance>

これは上記のUIマークアップに適合するサンプルインスタンスデータ である。 "xyz" はサンプルデータを示す。

場合によっては、バインディング式XForms モデルをアドレッシングする。 たとえば動的制約や計算(calculation)を選択する場合である。これは上記と同様に処理する。

編注: 将来のリビジョンでは、これをより詳細に、例を含めて説明するであろう。

6.3.2 厳格なバインディング式

XPathを用いるため、同一のロケーションを示すようなバインディング式を、多様に設計することができる。 とはいえ、厳格なバインディング式と呼ばれる、スタンダードでコンパクトな表現でバインディング式 を表すのが便利である。

厳格な バインディング式[XPath]で定義されるAbsoluteLocationPathとして表される。さらに、厳格なバインディング式はデフォルトの基準点(axis)指示子(エレメントを表す)か、あるいは '@' 表記(属性を表す)のみを用いる。例:

6.4 命令

編注: まだ多少の作業が、命令の優先順位、相関関係、そして例外時の投げられるイベント名について必要である。

XPath は'/'をロケーションステップの区切り子として予約し、またこのシンボルを除算としても使うことを非実用的なものとする。動的制約言語では、命令に英語に一致した名前を利用する。エラーが生じる可能性を最小化し、シンボルの文字エンティティ参照の使用を回避することを意図しているためである。

not演算子はBooleanに評価できるオペランドにのみ用いられる。もしオペランドがtrueであれば、not命令はfalseと評価する。オペランドがfalseであれば、not命令はtrueと評価する。

if cond then expr1 else expr2 の構造は、condtrueあるいはfalseとして評価できるものであることを要求する。もしcondtrueであれば、この構造の値はexpr1を評価した結果となり、そうでなければ、expr2を評価して得られたものとなる。

is命令は2つの値を比較し、Booleanの結果を返す。

expr is within(expr1, expr2) の構造は、もしexprを評価した結果がexpr1expr2で定義された範囲に含まれていればtrueと評価する。もし範囲外になれば、この構造はfalseと評価する。オペランドは同じ型でなければならず、number、string、date、time、あるいは同じ通貨コードの金額に限られる。文字列比較はUnicodeスタンダードで定義されている。

expr is not within(expr1, expr2) の構造は、もしexprを評価した結果がexpr1expr2で定義された範囲に含まれていればtrueと評価する。もし範囲外になれば、この構造はfalseと評価する。オペランドは同じ型でなければならず、number、string、date、time、あるいは同じ通貨コードの金額に限られる。文字列比較はUnicodeスタンダードで定義されている。以下はtrueステートメントを返すいくつかの例である:

is beforeおよび関連命令は、is withinに類似する比較命令を提供する。オペランドは同じ型でなければならず、number、string、date、time、あるいは同じ通貨コードの金額に限られる。文字列比較はUnicodeスタンダードで定義されている。beforeおよびbelowはスカラーの範囲で早い方を表し、afterおよびaboveはスカラーの範囲で遅い方を表す。例として、true ステートメントを返すいくつかの例を挙げる:

and, or および xor はBooleanのオペランドを必要とし、該当する論理演算を行う。たとえば、以下の例は全てtrueとなる:

plus, minus, times および over 命令は数値オペランドを必要とし(例外について以下を参照)、該当する算術命令を処理する。 over命令は除算を行い、もし分母が0であればoverflow例外を投げる。 plus命令は文字列オペランドにも適用でき、文字列連結を行う。 以下の例は全てtrueとなる:

%命令は、オペランドを100で割る後置演算子である。

= 命令は代入を行う。 フォームコントロールバインディングするメカニズムは一般的に、各フォームコントロール は単一のモデルアイテムに結びついている、と推測する。 ボタンやイメージマップのようないくつかのXForms ユーザーインターフェースコントロールは、各種のモデルアイテムの値を、同じアクションの中でセットする必要があるかもしれない。これはセミコロンで区切られた1つ以上の代入文を用いて扱う、という提案がある:

以下は市と州をセットする簡単な例である:

[10] InfixOperator    ::=    'and'
| 'or'
| 'xor'
| 'plus'
| 'minus'
| 'times'
| 'over'
| 'is' [[PrefixOperator] ('above' | 'below' | 'before' | 'after')]
 
[11] InfixExp    ::=    Expr InfixOperator Expr  
[12] PrefixOperator    ::=    'not'  
[13] PrefixExp    ::=    PrefixOperator Expr  
[14] PostfixOperator    ::=    '%'  
[15] PostfixExp    ::=    Expr PostfixOperator  
[16] SpecialOperator    ::=    'is' ['not'] 'within'  
[17] SpecialExp    ::=    Expr SpecialOperator '(' Expr ',' Expr ')'  
[18] IfThenElseExp    ::=    'if' Expr 'then' Expr ['else' Expr]  
[19] Assignment    ::=    [Lexpr '=' ]+ Expr [ ';' Assignment ]* [ ';' ]  
[20] Lexpr    ::=    Identifier |
Function |
(Lexpr)
 

6.5 XForms コア関数ライブラリ

このセクションでは、XFormsに有用な必須関数のセットを定義する。関数のシンタックスはXPathに基づいている:

[21] Arg    ::=    Expr  
[22] FunctionExp    ::=    function-name '('[arg [',' arg]*] ')'  

6.5.1 XPath コア関数ライブラリ

XForms コア関数ライブラリには、node-set、string、number、booleanに対する命令を含む、完全な[XPath] コア関数ライブラリが含まれる。

完全なXPathコア関数ライブラリを実装するためには、リソースに制約されたデバイスの能力について、さらなる入力が必須となる。

6.5.2 Number メソッド

編注: 次のものは[XPath]で定義されている - number(), sum(), floor(), ceiling(), round()

関数: number average(node-set)

average関数は、引数node-set中の各ノードについて、その文字列値を数値に変換した結果の、数学的な平均値を返す。数値はplusで加算され、その後over で、指定されたノードセットのcount()で割られる。

関数: number min(node-set)

min関数は、引数node-set中の各ノードについて、その文字列値を数値に変換した結果の最小値を返す。数値はis belowで比較される。

関数: number max(node-set)

The max関数は、引数node-set中の各ノードについて、その文字列値を数値に変換した結果の最小値を返す。数値はis belowで比較される。

6.5.3 String メソッド

備考: 次のものが[XPath]で定義されている - string(), concat(), starts-with(), contains(), substring-before(), substring-after(), substring(), string-length(), normalize-space(), translate().

6.5.4 Date/Time メソッド

関数: string now()

now関数は、現在のシステム時刻をXForms仕様で定義されている厳格なフォーマットの文字列値として返す。もしローカルタイムゾーン情報が利用できるなら、この文字列に含める。

6.5.5 その他のメソッド

関数: null submit()

submit関数は、式を含むノードに結びつけられたインスタンスデータを直ちに送信する。

関数: null reset()

reset関数は、式を含むノードに結びつけられたインスタンスデータを直ちにリセットする。

6.6 字句構造

トークン化の際には。有効なトークンで最も長いものが常に返される。

以下の例外を除けば、空白がトークンの間で利用可能である:

連続する英数字トークンの間では、空白が必要になる。たとえば命令"not"と関数名の間では空白が必要になる。名前は、XML NAMEトークンの字句規則に従う。ただし、関数名に-あるいは.を含めることは、外部定義の関数との互換性の問題があるため、許されない。

グループ化のために括弧を用いることはできるが、それ以上に動的制約としての意味はもたない。この文法は、null, boolean, number, stringのリテラルだけでまかなおうとするものである。

[23] Expr    ::=    NullExp
| BoolExp
| NumberExp
| StringExp
| ArrayExp
| PathExp
| InfixExp
| PrefixExp
| PostfixExp
| SpecialExp
| IfThenElseExp
 

6.7 拡張性

このセクションは将来のリビジョンで拡張関数およびスクリプトからの呼び出しのメソッドで、拡張される予定である。