2012-01-03 6 views
3

ソースXML:XSLT:小計

<Root> 
    <Data> 
     <Code>A</Code> 
     <Value>10</Value> 
    </Data> 
    <Data> 
     <Code>A</Code> 
     <Value>10</Value> 
    </Data> 
    <Data> 
     <Code>B</Code> 
     <Value>10</Value> 
    </Data> 
    <Data> 
     <Code>A</Code> 
     <Value>2</Value> 
    </Data> 
    <Data> 
     <Code>C</Code> 
     <Value>10</Value> 
    </Data> 
    <Data> 
     <Code>A</Code> 
     <Value>5</Value> 
    </Data> 
    <Data> 
     <Code>B</Code> 
     <Value>4</Value> 
    </Data> 
    <Data> 
     <Code>A</Code> 
     <Value>10</Value> 
    </Data> 
    <Data> 
     <Code>C</Code> 
     <Value>10</Value> 
    </Data> 
    <Data> 
     <Code>B</Code> 
     <Value>10</Value> 
    </Data> 
    <Data> 
     <Code>A</Code> 
     <Value>10</Value> 
    </Data> 
    <Data> 
     <Code>C</Code> 
     <Value>5</Value> 
    </Data> 
.... 
</Root> 

XSL-FOコード:

マイコード(XSL-FO)は各列は 'A'、 'B' のコンテンツを含む3列が含まれ、各列は「B」の値を表示するための「C」

<fo:table-body> 
    <xfd:table-row-repeat xpath="Root/Data" font-family="Arial Narrow" font-size="10pt" padding-after="0.55cm"> 
     <xsl:if test="Code='A'"> 
     <fo:table-cell> 
     <fo:block height="12pt">Value 
     </fo:block> 
     </fo:table-cell> 
     <fo:table-cell> 
     <fo:block height="12pt" border="0.1pt solid black" text-align="center"> 
      <xsl:value-of select="Value" /> 
     </fo:block> 
     </fo:table-cell> 
     <fo:table-cell> 
     <fo:block height="12pt">Points</fo:block> 
     </fo:table-cell> 
     </xsl:if> 
    </xfd:table-row-repeat> 
</fo:table-body> 

同じコード&「C」 表フッタにおいてiが「B」、「C」、「A」のこれらの小計を取得するためにきました

<fo:table-body> 
    <xfd:table-row-repeat xpath="Root/Data" font-family="Arial Narrow" font-size="10pt" padding-after="0.55cm"> 
     <xsl:if test="Code='A'"> 
     <fo:table-cell> 
     <fo:block height="12pt">SubTotal 
     </fo:block> 
     </fo:table-cell> 
     <fo:table-cell> 
     <fo:block height="12pt" border="0.1pt solid black" text-align="center"> 
      <--Here Sum of first 15 A's. if the A's or B's or C's exceed by 15, then the table flows to 2nd Page. In that case, 1st Page table-footer shows individual subtotals of first 15 A's, 15 B's and C's. In 2nd Page, the subtotals should contain Subtotal of first 15 A's+ Succeeding A's, in the same way B's and C's --> 
     </fo:block> 
     </fo:table-cell> 
     <fo:table-cell> 
     <fo:block height="12pt">Points</fo:block> 
     </fo:table-cell> 
     </xsl:if> 
    </xfd:table-row-repeat> 
</fo:table-body> 

ここでXSL-FOコードは(ルート/データ/コード= 'A' の)1列のみのために示され、他の2列( 'B' & 'C')は、同じコードで構成されています。詳細に

条件:

Condition 1): when Root/Data/Code = 'A' or 'B' or 'C' 
    i need individual totals of 'A', 'B' and 'C' in Table-Footer individual Column. 

Condition 2): inturn if individual count(Root/Data/Code) of 'A', 'B' & 'C' crosses 15.   Then Page flows to 2nd Page then Table-Footer in 2nd Page needs to contains subtotal of first 15 A's + the sum of succeeding A's in the same way for B's And C's 

即ち、20 Aの、10のBの25人のC年代は、ソースXMLに存在する場合。 「A」、「B」と「C」の合計を評価するためのコードタグてグループ化することにより、キー:

In 1st Page, Table-Footer 

SubtotalI(Value of 15 A's)= 
SubtotalII(Value 10 B's)= 
SubtotalIII(Value 15 C's)= 

In 2nd Page, Table-Footer 

SubtotalI(15 A's+ next 5 A's)= 
SubtotalII(Value 10 B's)= <!--No Change as count of B's is less than 15 --> 
SubtotalIII(15 C's + next 10 C's)= 

は、私は、XSLを使用して、このロジックをしようとしています。私はXSLTを初めて使っているので、xsl:keyを使ってこのロジックを解決することは難しいと思っています。誰でもこの論理を解決するのに役立つことができますか?

ありがとうございました

+0

これはXSLTで行うべきことではありません。 XSL変換は、ドキュメントの構造を変換するのに最適です。彼らはロジックと条件付き計算を適用するのにはあまり適していません。 – ColinE

+0

質問を再度お聞かせください。あなたが得ることを期待していることは不明です。 – Lloyd

+0

私は私の質問をはるかに明確にしました。今すぐチェックしてください – BVS

答えて

0

達成しようとするといくつかの困難があります。与えられた点での小計の計算は、実際には最も簡単です。あなたはそれを計算するために、前軸との和を必要とする:

sum(preceding::Value[../Code = 'A']) 

が同様に現在の値を含めるには、次のようにunion演算子を使用します。

sum(Value[../Code = 'A'] | preceding::Value[../Code = 'A']) 

大きな困難が異なるを示すことです各ページの 'footer'テーブル。ヘッダーとフッターはページ上で自動的に繰り返されますが、その内容は表が含まれるすべてのページで同じです。私が見る唯一の解決策は、毎回異なるテーブルフッタを追加して、テーブルを自分で分割することです。

一番簡単な方法は、一度に固定数のデータ要素を取り出し、それらを個別の表に表示することです。 A、B、Cの各タイプをfor-eachでループして、各値に別々の行を与えることができます。そのようにして、テーブルは常に同じ数の行を持ちます。 1ページに収まるかどうかを判断するために含めることができる番号を試すことができます。

次のコードは、最初の10個のデータ値を含む表を返します。 A、B、Cの値は互いにまっすぐに配置されていますが、好きな場合はそれぞれ左、中央、右に配置できます。テーブルの下部に3行は、あなたはまだへのいくつかの再帰呼び出しを行う、あなたが必要となるn個のデータ項目のどのように多くのテーブルを決定するために何かを必要とし、A、BおよびCの小計

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:fo="http://www.w3.org/1999/XSL/Format"> 

    <xsl:template match="/"> 
     <fo:root> 
      <fo:layout-master-set> 
       <fo:simple-page-master master-name="global"> 
        <fo:region-body/> 
       </fo:simple-page-master> 
      </fo:layout-master-set> 

      <fo:page-sequence master-reference="global"> 
       <fo:flow flow-name="xsl-region-body"> 

        <fo:block> 
         <fo:table table-layout="fixed" width="150mm" border-style="solid"> 
          <fo:table-column column-width="50mm"/> 
          <fo:table-column column-width="50mm"/> 
          <fo:table-column column-width="50mm"/> 

          <fo:table-body font-size="7pt"> 
           <xsl:for-each select="/Root/Data[10 >= position()]"> 
            <fo:table-row border-style="solid"> 
             <fo:table-cell> 
              <fo:block height="12pt"> 
               <xsl:value-of select="Code" /> 
              </fo:block> 
             </fo:table-cell> 
             <fo:table-cell> 
              <fo:block height="12pt" border="0.1pt solid black" text-align="center"> 
               <xsl:value-of select="Value" /> 
              </fo:block> 
             </fo:table-cell> 
             <fo:table-cell> 
              <fo:block height="12pt">Points</fo:block> 
             </fo:table-cell> 
            </fo:table-row> 

            <xsl:if test="position() = last()"> 
             <fo:table-row border-style="solid"> 
              <fo:table-cell> 
               <fo:block height="12pt">Subtotal A</fo:block> 
              </fo:table-cell> 
              <fo:table-cell> 
               <fo:block height="12pt" border="0.1pt solid black" text-align="center"> 
                <xsl:value-of select="sum(preceding::Value[../Code = 'A'] | Value[../Code = 'A'])" /> 
               </fo:block> 
              </fo:table-cell> 
              <fo:table-cell> 
               <fo:block height="12pt">Points</fo:block> 
              </fo:table-cell> 
             </fo:table-row> 
             <fo:table-row border-style="solid"> 
              <fo:table-cell> 
               <fo:block height="12pt">Subtotal B</fo:block> 
              </fo:table-cell> 
              <fo:table-cell> 
               <fo:block height="12pt" border="0.1pt solid black" text-align="center"> 
                <xsl:value-of select="sum(preceding::Value[../Code = 'B'] | Value[../Code = 'B'])" /> 
               </fo:block> 
              </fo:table-cell> 
              <fo:table-cell> 
               <fo:block height="12pt">Points</fo:block> 
              </fo:table-cell> 
             </fo:table-row> 
             <fo:table-row border-style="solid"> 
              <fo:table-cell> 
               <fo:block height="12pt">Subtotal C</fo:block> 
              </fo:table-cell> 
              <fo:table-cell> 
               <fo:block height="12pt" border="0.1pt solid black" text-align="center"> 
                <xsl:value-of select="sum(preceding::Value[../Code = 'C'] | Value[../Code = 'C'])" /> 
               </fo:block> 
              </fo:table-cell> 
              <fo:table-cell> 
               <fo:block height="12pt">Points</fo:block> 
              </fo:table-cell> 
             </fo:table-row> 
            </xsl:if> 
           </xsl:for-each> 
          </fo:table-body> 
         </fo:table> 
        </fo:block> 

       </fo:flow> 
      </fo:page-sequence> 

     </fo:root> 
    </xsl:template> 

</xsl:stylesheet> 

に追加されますそれらのすべてを出力します。これが瞬間あなたにもう一度行くのに十分であることを願っています!

PS:xfdプレフィックスを使用していることに気付きました。あなたはEcrionのXF Designerを使っているようです。私はそれに慣れていません。上記のコードは、単純なXSLT 1.0ソリューションです。 XF Designerで動作しているかわからない場合は、教えてください。

+0

@BVS愚かな私、私は完全にfo:markerを忘れています。 A、B、Cの合計(個別のマーカークラス名)を含む各表のセルにfo:markerを入れることが可能でなければなりません。 fo:retrieve-table-markerを使用して、現在のページの最後のマーカー値をテーブルフッターにプルする必要があります。私は私の例を変更しようとしましたが、FOPはこれをサポートしていないようです。試してみる価値はあるかもしれませんが、あなたのプロセッサがそれをサポートしていないことがわかります。 HTH! – grtjn

+0

fo:markerは私に多くの助けをしました.. thanks a ton guys – BVS