倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

単純化(12) : 子要素の個数

単純化の第12段階では、各種要素の子要素の個数が適切になるように XML ツリーを修正します。

  • 対象ノードの箇所では接頭辞 "rng" は「RELAX NG 名前空間」に関連づけられているとします。
  • サンプルでは見やすさのために空白や改行を入れているところがありますが、実際には単純化の第2段階で除去されています。

<define>, <oneOrMore>, <zeroOrMore>, <optional>, <list>, <mixed> 要素の子要素を1個にする

対象ノード
//rng:define[count(*) >= 2]
//rng:oneOrMore[count(*) >= 2]
//rng:zeroOrMore[count(*) >= 2]
//rng:optional[count(*) >= 2]
//rng:list[count(*) >= 2]
//rng:mixed[count(*) >= 2]
操作
子要素を <group> 要素でラップする。

サンプル

<oneOrMore>
  [パターン1]
  [パターン2]
</oneOrMore>

<oneOrMore>
  <group>
    [パターン1]
    [パターン2]
  </group>
</oneOrMore>

<element> 要素の子要素を2個にする

対象ノード
//rng:element[count(*) >= 3]
操作
<name> 要素以外の子要素を <group> 要素でラップする。

サンプル

<element>
  <name ns="">root</name>
  [パターン1]
  [パターン2]
</element>

<element>
  <name ns="">root</name>
  <group>
    [パターン1]
    [パターン2]
  </group>
</element>

<except> 要素の子要素の1個にする

対象ノード
//rng:except[count(*) >= 2]
操作
子要素を <choice> 要素でラップする。

サンプル

<except>
  [パターン1]
  [パターン2]
</except>

<except>
  <choice>
    [パターン1]
    [パターン2]
  </choice>
</except>

<attribute> 要素の子要素を2個にする

対象ノード
//rng:attribute[count(*) = 1]
操作
子要素に <text> 要素を付加する。
<attribute>
  <name ns="">an-attribute</name>
</attribute>

<attribute>
  <name ns="">an-attribute</name>
  <text/>
</attribute>

<choice>, <group>, <interleave> 要素の子要素を2個にする

対象ノード
//rng:choice[count(*) >= 3]
//rng:group[count(*) >= 3]
//rng:interleave[count(*) >= 3]
操作
最初の2つの子要素を、対象要素と同名の要素でラップする。 各要素の子要素が2つになるまでこの操作を繰り返す。

サンプル1

子要素のパターンが3つの場合:

<choice>
  [パターン1]
  [パターン2]
  [パターン3]
</choice>

<choice>
  <choice>
    [パターン1]
    [パターン2]
  </choice>
  [パターン3]
</choice>

サンプル2

子要素のパターンが4つある場合も、同様の処理で全ての <choice> 要素が2つの子要素を持つようにします:

<choice>
  [パターン1]
  [パターン2]
  [パターン3]
  [パターン4]
</choice>

<choice>
  <choice>
    <choice>
      [パターン1]
      [パターン2]
    </choice>
    [パターン3]
  </choice>
  [パターン4]
</choice>

事後条件

  • <define>, <oneOrMore>, <zeroOrMore>, <optional>, <list>, <mixed> 要素の子要素は1個。
  • <element> 要素の子要素は2個(<name> 要素とパターン)。
  • <except> 要素の子要素は1個
  • <attribute> 要素の子要素は2個(<name> 要素とパターン)。
  • <choice>, <group>, <interleave> 要素の子要素は2個。