myGroup > myProject
 

oneOrMore 要素

1回以上の繰り返しを定義する要素

  • 子要素に記述される一聯のパターンに関し、それらのパターンが1回以上繰り返して出現することを指示する要素です。
  • XML では、主に要素の中身の定義に対して用います。
  • attribute要素 の直截の親要素として用た場合、その属性は必須属性と見倣されます(attribute要素 を element要素 直下に記述した場合と同様)。ただし、複数の同名の属性を記述出来るわけではないので、注意してください。
  • attribute要素 の子孫要素としては用いることが出来ません。
  • grammar 要素の直下には置いてはなりません。
  • スキーマのルート要素に用いることが出来ます。ただし、そのスキーマは単独では用いることは出来ず、 externalRef 要素の参照先としてのみ利用できます。
  • 要素名に大文字が混じっていますので、記述には注意してください。

属性

lang:occurs 属性

名前空間 lang に属する属性です。繰り返し処理の回数を、事前に設定してください。

  • decode : 指定された回数だけ、繰り返し処理を実行します。
  • encode : 指定された回数だけ、繰り返し処理を実行します(encode 時は必須です)。

lang:occured 属性

名前空間 lang に属する属性です。oneOrMore の処理の後に設定されます。

  • decode : 繰り返し数の解析結果が、指定された変数に代入されます。
  • encode : 指定できません。

制約

  • optional、oneOrMore、zeroOrMore を入れ子にできる最大数は、「32」です。
  • ref 要素を中身にし、マクロを参照することが出来ます。 ただし、ソースコードの生成前に、define/ref が展開されている必要があります。
  • lang:occurs 属性と、lang:occured 属性を同時に指定することはできません。 どちらか一方を必ず指定してください。
  • lang:occurs 属性に 1 未満の値を指定することはできません。エラーとなります。

子ノード

  • 複数の コンテナ もしくは サブコンテナ を子要素に持つことが出来ます。
  • interleave要素, optional要素, zeroOrMore要素 などを子に持つことも可能です。

使用例

例 1: mapping の例 (XML-XML syntax)

mapping の例 (XML-XML syntax)

以下のパターンは、1 バイト以上のバイナリデータにマッチします。 変数 n に、バイト長を対応させています。

decode の例
<oneOrMore lang:occured="n">
  <dat:byte length="1">
    <lang:value-of select="i">
      <data type="int"/>
    </lang:value-of>
  </dat:byte>
  <callFunction expr="pushValue( i );"/>
</oneOrMore>
  
encode の例
<oneOrMore lang:occurs="n">
  <callFunction expr="i = popValue();"/>
  <dat:byte length="1">
    <lang:value-of select="i">
      <data type="int"/>
    </lang:value-of>
  </dat:byte>
</oneOrMore>
  

decode では、繰り返し数の解析結果が変数 n に代入されます。また、 encode では、変数 n で指定された回数分繰り返しが行われます。

例 2: mapping の例 (XML-language syntax)

mapping の例 (XML-language syntax)

例 1 は、以下のように書き直すことができます。 しかし、記述方法については、まだ決定していません。

decode の例
<oneOrMore>
  <dat:byte length="1">
    <callFunction expr="pushValue( <data type="int"/> );">
  </dat:byte>
  n =
</oneOrMore>;
  
encode の例
<oneOrMore>
  = n;
  <dat:byte length="1">
    <data type="int"/> = <callFunction expr="popValue();"/>
  </dat:byte>
</oneOrMore>
  

例 3: JAVA での mapping の例 (XML-language syntax)

JAVA での mapping の例 (XML-language syntax)

JAVA には Interator や Collection など集合を取り扱うのに 便利なクラスがそろっています。これらを使用することもできます。

Iterator を用いた encode
<oneOrMore>
  <lang:var class="Byte" name="b" interator="iterator">
    <dat:byte length="1">
      <data type="byte"/> = b.byteValue();
    </dat:byte>
  </lang:var>
</oneOrMore>
  
List を用いた encode
<oneOrMore>
  <lang:var class="Byte" name="b" collection="list">
    <dat:byte length="1">
      <data type="byte"/> = b.byteValue();
    </dat:byte>
  </lang:var>
</oneOrMore>
  
List を用いた decode
<oneOrMore>
  <dat:byte length="1">
    list.add( new Byte(<data type="byte"/>) );
  </dat:byte>
</oneOrMore>
  

が、美しい記法ではないですね。

考えてみよう!

その 1: 連続する oneOrMore要素

連続する <span class="codefrag">oneOrMore</span>要素

連続する oneOrMore要素 の中身を、一つの oneOrMore要素 の中身としてまとめることは出来ません。以下に、その例を示します。

例1
<oneOrMore>
  <ref name="a"/>
</oneOrMore>
<oneOrMore>
  <ref name="b"/>
</oneOrMore>
例2
<oneOrMore>
  <ref name="a"/>
  <ref name="b"/>
</oneOrMore>

例1では、「aが1回以上出現した後、bが1回以上出現するパターン (aa…bb…)」であるのに対し、例2では、「aとbが、この順番を保持したまま1回以上出現 (abab…)」となります。

その 2: 出現順番に関して

出現順番に関して
  • choice要素, interleave要素 の子要素でない場合、定義の出現順位は保持されます。
  • oneOrMore要素 の子要素の中で、choice要素, interleave要素 が存在しない部分は、定義の出現順位は保持されます。

参考文献