倭マン's BLOG

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

単純化(18) : 要素

単純化の第18段階は、<grammar> 要素の処理です。

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

トップレベル要素を <grammar> にする

対象ノード
/*
操作
でラップする

サンプル

<element>
  <name ns="">ELEMENT</name>
  パターン
</element>

<grammar>
  <start>
    <element>
      <name ns="">ELEMENT</name>
      ...
    </element>
  </start>
</grammar>

<define> 要素の名前を変更する

対象ノード
//rng:define
操作
スキーマ文書内に同名(@name 属性の値が同じ)の <define> 要素があれば、その <define> 要素の @name 属性の値と、その <define> 要素を参照している <ref>, <parentRef> 要素*1の @name 属性の値を変更する。

サンプル

「DEFINE1」の名前を「Define1」に変えるとしましょう。

<grammar>
  <define name="DEFINE1">
    ...
  </define>

  <define name="DEFINE2">
    <ref name="DEFINE1"/>
  </define>

  <grammar>
    <define name="DEFINE3">
      <parentRef name="DEFINE1">
    </define>
  </grammar>
</grammar>

<grammar>
  <define name="Define1">
    ...
  </define>

  <define name="DEFINE2">
    <ref name="Define1"/>
  </define>

  <grammar>
    <define name="DEFINE3">
      <parentRef name="Define1">
    </define>
  </grammar>
</grammar>

<define> 要素の移動

対象ノード
//rng:define
操作
トップレベル <grammar> 要素の子要素にする。

サンプル

<grammar>
  <grammar>
    <start>...</start>

    <define name="DEFINE1">
      ...
    </define>

    <define name="DEFINE2">
      <element>
        <name ns="">ELEMENT</name>
        <grammar>
          <start>
            <ref name="DEFINE3"/>
          </start>

          <define name="DEFINE3">
            ...
          </define>
        </grammar>
    </define>
  </grammar>
</grammar>

<grammar>
  <grammar>
    <start>...</start>
  </grammar>

  <define name="DEFINE1">
    ...
  </define>

  <define name="DEFINE2">
    <element>
      <name ns="">ELEMENT</name>
      <grammar>
        <start>
          <ref name="DEFINE3"/>
        </start>
      </grammar>
  </define>

  <define name="DEFINE3">
    ...
  </define>
</grammar>

<grammar> 要素の置き換え

対象ノード
/rng:grammar/descendant::rng:grammar
操作
子 <start> 要素の子要素で置き換える。

サンプル

<element>
  <name ns="">ELEMENT</name>
  <grammar>
    <start>
      <ref name="DEFINE"/>
    </start>
  </grammar>
</element>

<element>
  <name ns="">ELEMENT</name>
  <ref name="DEFINE"/>
</element>

<parentRef> 要素を <ref> 要素に変更

対象ノード
//rng:parentRef
操作
<parentRef> 要素を <ref> 要素に変更する。

サンプル

<grammar>
  <start>
    <parentRef name="DEFINE"/>
  </start>

  <define name="DEFINE">
    ...
  </define>
</grammar>

<grammar>
  <start>
    <ref name="DEFINE"/>
  </start>

  <define name="DEFINE">
    ...
  </define>
</grammar>

事後条件

  • トップレベル要素が <grammar> 要素になっている。
  • トップレベル要素以外に <grammar> 要素がない。
  • <parentRef> 要素がない。

*1:「参照している」とは、<ref> 要素の場合、直近の祖先 <grammar> 要素下にある同名の <define> 要素、<parentRef> 要素の場合、2番目に近い祖先 <grammar> 要素下にある同名の <define> 要素です。