データの処理

次の各項では、テンプレートでデータを処理する方法を説明します。

データのソート

グループは、そのグループ内の任意の要素順にソートできます。次の構文をグループ・タグ内に挿入します。

<?sort:要素名; 順序; データ・タイプ?>

説明

要素名は、グループをソートする要素の名前です。

順序は「昇順」または「降順」です。

データ・タイプは、要素のデータ・タイプです。有効な値は、「text」と「number」です。

順序を指定しなければ、デフォルトではソート順序は昇順です。データ型を指定しなければ、型はtextと想定されます。

たとえば、最高のサラリーが最初に表示されるように、SALARYという名前の要素でデータセットをソートするには、次を入力します。

<?sort:SALARY;'descending';'number'?>

for-eachグループ内でソートを実行している場合、for-each文の後にソート文を入力します。たとえば、この章の冒頭で示したPayables Invoice Registerを仕入先(VENDOR_NAME)順にソートするには、次のように入力します。

<?for-each:G_VENDOR_NAME?><?sort:VENDOR_NAME?>

複数のフィールドでグループをソートするには、追加のソート文を適切な順に入力するだけです。たとえば、サプライヤでソートしてから請求番号でソートするには、次を入力します。

<?sort:VENDOR_NAME?> <?sort:INVOICE_NUM;'ascending';'number'?>

NULL値の確認

XMLデータ内の要素の値に想定可能なシナリオは、次のように3つあります。

シナリオ:

  • XMLデータ内に要素が存在し、値を持つ場合

  • XMLデータ内に要素が存在するが、値を持たない場合。

  • XMLデータに要素がなく、したがって値もない場合。

レポート・レイアウトでは、要素とその値の有無に応じて異なる動作を指定することが必要な場合があります。次の例では、if文を使用してこれらの条件のそれぞれについてチェックする方法を示します。構文は、別の条件付き書式設定構造でも使用できます。

  • 要素が存在し、値がnullでない場合の動作を定義するには、次を使用します。

    <?if:element_name!=' '?> 希望する動作<?end if?>

  • 要素は存在するが、値がnullの場合の動作を定義するには、次を使用します。

    <?if:element_name and element_name="?> 希望する動作<?end if?>

  • 要素がない場合の動作を定義するには、次を使用します。

    <?if:not(element_name)?> 希望する動作 <?end if?>

XMLデータの再グループ化

RTFテンプレートでは、XSL 2.0のfor-each-group標準をサポートしているため、元のデータに存在しないXMLデータを階層に再グループ化できます。

この機能を使用すると、テンプレートでソースXMLファイルの階層に従う必要がなくなります。このため、データソースの構造による制約がなくなります。

XMLのサンプル

このXMLのサンプルは、for-each-group標準を使用するデータのセットを示しています。

for-each-group標準を示すため、CDカタログ一覧の次のXMLデータ・サンプルをテンプレートで再グループ化します。

<CATALOG>
   <CD>
      <TITLE>Empire Burlesque</TITLE>
      <ARTIST>Bob Dylan</ARTIST>
      <COUNTRY>USA</COUNTRY>
      <COMPANY>Columbia</COMPANY>
      <PRICE>10.90</PRICE>
      <YEAR>1985</YEAR>
   </CD>
   <CD>
      <TITLE>Hide Your Heart</TITLE>
      <ARTIST>Bonnie Tylor</ARTIST>
      <COUNTRY>UK</COUNTRY>
      <COMPANY>CBS Records</COMPANY>
      <PRICE>9.90</PRICE>
      <YEAR>1988</YEAR>
   </CD>
   <CD>
      <TITLE>Still got the blues</TITLE>
      <ARTIST>Gary More</ARTIST>
      <COUNTRY>UK</COUNTRY>
      <COMPANY>Virgin Records</COMPANY>
      <PRICE>10.20</PRICE>
      <YEAR>1990</YEAR>
   </CD>
   <CD>
      <TITLE>This is US</TITLE>
      <ARTIST>Gary Lee</ARTIST>
      <COUNTRY>UK</COUNTRY>
      <COMPANY>Virgin Records</COMPANY>
      <PRICE>12.20</PRICE>
      <YEAR>1990</YEAR>
   </CD>

再グループ化構文を使用すると、CDデータを国別にグループ化し、さらに年度別にグループ化するレポートを作成できます。これにより、現在のデータ構造による制限を受けません。

再グループ化構文

適切な構文を使用して、データを再グループ化できます

データを再グループ化するには、次の構文を使用します。

<?for-each-group: BASE-GROUP;GROUPING-ELEMENT?>

たとえば、CD一覧をCOUNTRY別に再グループ化するには、テンプレートに次のように入力します。

<?for-each-group:CD;COUNTRY?>

COUNTRYと同じ階層レベルにあった要素はCOUNTRYの子要素になります。これで、グループの要素を参照して、必要な値を表示できます。

すでに定義済のグループ内にネストされたグループを作成するには、次の構文を使用します。

<?for-each:current-group(); GROUPING-ELEMENT?>

たとえば、CDをCOUNTRY別にグループ化するように宣言した後、COUNTRY内でさらにYEAR別にグループ化するには、次のように入力します。

<?for-each:current-group();YEAR?> 

実行時に、Publisherは新しいグループの出現箇所をループ処理して、テンプレートに定義されたフィールドを表示します。

ノート:

この構文は、単純なXSLのfor-each-group構文です。前述の簡略化された構文を使用しない場合は、後述するXSL構文を使用できます。XSL構文を使用できるのは、テンプレートのフォーム・フィールド内のみです。
<xsl:for-each-group
  select=expression
  group-by="string expression"
  group-adjacent="string expression"
  group-starting-with=pattern>
  <!--Content: (xsl:sort*, content-constructor) -->
</xsl:for-each-group>

テンプレートの例

この例では、テンプレートを拡張するために使用できるいくつかの機能を示します。

次の図に、CDをCountry別、Year別の順に表示して、各CDの詳細をリストするテンプレートを示します。

次の表に、前述の図に示されたテンプレートのフォーム・フィールドへのPublisher構文の入力を示します。

デフォルト・テキスト入力 フォーム・フィールドのヘルプ・テキスト入力 説明

Group by Country

<?for-each-group:CD;COUNTRY?>

<?for-each-group:CD;COUNTRY?>タグは、新規グループを宣言します。これによって、既存のCDグループがCOUNTRY要素別に再グループ化されます。

USA

<?COUNTRY?>

COUNTRYタグのデータ値を表示するプレースホルダ。

Group by Year

<?for-each-group:current-group();YEAR?>

<?for-each-group:current-group();YEAR?>タグは、現行グループ(COUNTRY)をYEAR要素別に再グループ化します。

2000

<?YEAR?>

YEARタグのデータ値を表示するプレースホルダ。

Group: Details

<?for-each:current-group()?>

データをCOUNTRY別、YEAR別の順にグループ化した後、<?for-each:current-group()?>コマンドを使用して現行グループ(YEAR)の要素をループし、表内のデータ値 (TITLE、ARTISTおよびPRICE)をレンダリングします。

My CD

<?TITLE?>

TITLEタグのデータ値を表示するプレースホルダ。

John Doe

<?ARTIST?>

ARTISTタグのデータ値を表示するプレースホルダ。

1.00

<?PRICE?>

PRICEタグのデータ値を表示するプレースホルダ。

End Group

<?end for-each?>

<?for-each:current-group()?>タグを終了します。

End Group by Year

<?end for-each-group?>

<?for-each-group:current-group();YEAR?>タグを終了します。

End Group by Country

<?end for-each-group?>

<?for-each-group:CD;COUNTRY?>タグを終了します。

このテンプレートをXMLファイルとマージすると、次の図に示すレポートが生成されます。

式による再グループ化

式による再グループ化を使用すると、関数またはコマンドをデータ要素に適用し、戻された結果別にデータをグループ化できます。

この機能を使用するには、次のように、再グループ化構文内に式を記述する必要があります。

<?for-each:BASE-GROUP;GROUPING-EXPRESSION?>

この機能を説明するため、月別平均気温が含まれる簡略なXMLデータ・サンプルをテンプレートへの入力として使用して、気温が特定の範囲内にある月数を計算します。

次のXMLコードは、複数の<temp>グループで構成されています。各<temp>グループには、<month>要素と<degree>要素が含まれ、その月の平均気温が保持されています。

<temps>
  <temp>
    <month>Jan</month>
    <degree>11</degree>
  </temp> 
  <temp>
    <month>Feb</month>
    <degree>14</degree>
  </temp>  
  <temp>
    <month>Mar</month>
    <degree>16</degree>
  </temp> 
  <temp>
    <month>Apr</month>
    <degree>20</degree>
  </temp> 
  <temp>
    <month>May</month>
    <degree>31</degree>
  </temp>
  <temp>
    <month>Jun</month>
    <degree>34</degree>
  </temp> 
  <temp>
    <month>Jul</month>
    <degree>39</degree>
  </temp> 
  <temp>
    <month>Aug</month>
    <degree>38</degree>
  </temp>
  <temp>
    <month>Sep</month>
    <degree>24</degree>
  </temp>  
  <temp>
    <month>Oct</month>
    <degree>28</degree>
  </temp> 
  <temp>
    <month>Nov</month>
    <degree>18</degree>
  </temp> 
  <temp>
    <month>Dec</month>
    <degree>8</degree>
  </temp> 
</temps>         

このデータを、次の図に示すように、気温の範囲、および平均気温がその範囲内にある月の数を示す書式で表示します。

for-each-groupコマンドを使用すると、気温を10度ごとに増分してグループ化する式を<degree>要素に適用できます。これで、各グループのメンバーの件数、つまり、平均気温が各範囲内にある月の数を表示できます。

次の図に、前述の図に示されているレポートを作成するためのテンプレートを示します。

次の表は、前述の図に示されているテンプレートのフォーム・フィールドへの入力を示しています。

デフォルト・テキスト入力 フォーム・フィールドのヘルプ・テキスト入力

Group by TmpRng

<?for-each-group:temp;floor(degree div 10)?><?sort:floor(degree div 10)?>

Range

<?concat(floor(degree div 10)*10,' F to ',floor(degree div 10)*10+10, 'F')?>

Months

<?count(current-group())?>

End TmpRng

<?end for-each-group?>

フォーム・フィールド・タグについて次の点に注目してください。

  • <?for-each-group:temp;floor(degree div 10)?>は再グループ化タグです。このタグは、既存の<temp>グループに対して、floor(degree div 10)式を使用して要素を再グループ化するように指定します。floor関数はXSL関数の1つで、引数より小さい最大整数を戻します(たとえば、1.2の場合は1を、0.8の場合は0(ゼロ)を戻します)。

    この例では、<degree>要素の値を10で除算した値に対する関数の結果が戻されます。これにより、XMLデータから、1、1、1、2、3、3、3、3、2、2、1および0.という値が生成されます。

    これらの値をソートすると、0、1、2および3の4つのグループが作成されます。

  • <?concat(floor(degree div 10)*10,'F to ', floor(degree div 10)*10+10,'F'?>は、気温範囲を10度ごとに増分して行ヘッダーに表示します。この式によって、現行グループの値に10を乗算した値と、現行グループの値に10を乗算して10を加算した値が連結されます。

    したがって、最初のグループ0(ゼロ)の場合、行ヘッダーには「0 F to 10 F」(0から(0+10))と表示されます。

  • <?count(current-group())?>は、count関数を使用して現行グループのメンバー(範囲を満たす気温の数)をカウントします。

  • <?end for-each-group?>タグは、このグループを終了します。