myGroup > myProject
 

開発の流れ

開発の流れの概要

(-- 現在の開発体制の陣容では --)

umsCodeGeneratorの実装は、ボトムアップで進める方が効果的です。 すなわち、最初からスタイルシートを作成し始めるのではなく、 まずは、mapping definition に従った入力データを処理するソースプログラム (umsCodeGeneratorのアウトプットのイメージ)を作成し、 両者を結び付けるためのスタイルシートを完成させていく、 というアプローチを取っています。 実装の流れを整理すると、次のようになります。

  1. 入力データの作成
  2. mapping definition の作成
  3. ソースプログラムの作成
  4. スタイルシートの作成
  5. 動作確認

この作業を、徐々に mapping definition の記述を(UMS文法仕様に従って)リッチにしながら、 イテレーティブに実施していきます。 これにより、仕様の漏れがないこと、かつ、正常に動作することを確認しながら作業を進めていくことができます。 また、この作業で作成した mapping definition と入力データとは、そのままテストデータとして利用します。

1. 入力データの作成

入力データの作成は、mapping definition の作成と同時並行的に行います。 下の例では、入力データを持たないUMSを定義しているため、入力データは不要になります。

2. mapping definition の作成

次に、mapping definition を作成します。 簡単のため、入力データを持たない次のような mapping definition を考えます。

<grammar xmlns="http://ums.isas.jaxa.jp/0.4">
  <start>
    <java:class scope="abstract" name="XmlSample" xmlns:java="http://ums.isas.jaxa.jp/0.4/java">
      <defineVariables>
        <java:var name="rec" class="Record"/>
      </defineVariables>
    </java:class>
  </start>
</grammar>
Note
この時、trang により、schema/*.rng のcompact syntax を作成しておくと便利です。 Emacs/nxml-mode を用いて、リアルタイムで mapping definition の validate を行うことができます。

3. ソースプログラムの作成

上で作成した入力データを decode/encode するためのソースプログラムを作成します。 このとき、mapping definition との関係を意識するため、mapping definition 上の要素名、属性名を コメントとして残しながら実装します。 これにより、XSLT 変換を意識しながら実装することができます。 データ変換に関するところは、datatypeLibraryの関数を呼び出すように記述します。

同時に、これを呼び出すための main 関数と、この中から呼び出されるユーザ関数を作成します。

スタイルシートの作成前に、実際にソースプログラムをコンパイル、実行し、 入力データを正しく処理できることを確認しておきます。 本章では、ソースプログラムの添付は省略します。

4. スタイルシートの作成

スタイルシートの作成の前に、上で作成した mapping definition のスキーマを考えます。 一般的な mapping definition の文法ではなく、今回作成するプロセッサが処理できる範囲に 限った文法とします。 これは、XSLT の作成をスムーズに行うためだけでなく、mapping definition を XSL 変換にかける前に、 処理系がこれを正しく処理できるかどうか、文法チェックを行うためのものとしても利用できます。

このようにして作成した RELAX NG の構造を保ったまま、以下のような置き換えを行い、 XSLT を完成させていきます。

<element name="a"/>
→ <xsl:foreach select="a"/>
※スキーマ上、a要素は複数出現することはできないが、XSLT はa要素を複数許容してしまうので注意。 事前にvaridationではじく方が良い。

<zeroOrMore>
 <element name="a"/>
</zeroOrMore>
→ <xsl:foreach select="a"/>

<optional>
 <attribute name="@a"/>
</optional>
→ <xsl:if test="@a">出力する文</xsl:if>

<choice/>
→ <xsl:choose/>

<define name="xxx"/> と <ref name="xxx"/> の組
→ <template name="xxx"/> と <call-template name="xxx"/> の組

<element name="a">
 <element name="b"/>
 <element name="c"/>
</element>
→ <xsl:for-each select="a"><xsl:for-each select="b"/></xsl:for-each>
→ <xsl:for-each select="a"><xsl:for-each select="c"/></xsl:for-each>

これにより、以下のような XSLT を作成します。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:ums="http://ums.isas.jaxa.jp/0.4" xmlns:java="http://ums.isas.jaxa.jp/0.4/java">
  <xsl:output method="text"/>
  <xsl:template match="/">
    <xsl:for-each select="ums:grammar">
      <xsl:for-each select="ums:start">
        <xsl:for-each select="java:class"><xsl:text></xsl:text>
          <xsl:if test="@scope">
            <xsl:value-of select="@scope"/>
            <xsl:text> </xsl:text>
          </xsl:if>class <xsl:value-of select="@name"/> {
          <xsl:for-each select="ums:defineVariables">
            <xsl:for-each select="java:var">
              <xsl:choose>
                <xsl:when test="@type">
                  <xsl:value-of select="@type"/>
                </xsl:when>
                <xsl:when test="@class">
                  <xsl:value-of select="@class"/>
                </xsl:when>
              </xsl:choose>
              <xsl:text> </xsl:text>
              <xsl:value-of select="@name"/>;
            </xsl:for-each>
          </xsl:for-each>
}
        </xsl:for-each>
      </xsl:for-each>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

5. 動作確認

作成した XSLT を使用して XSLT 変換を行い、mapping definition からソースコードを作成します。 生成されたソースプログラムをコンパイル、実行し、入力データを正しく処理できることを確認します。