2012-01-03 3 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 열을 포함, 'C'각 열이 나는 'A'의이 부분 합계를 얻을했습니다 테이블 바닥 글에 & 'C' 'B', 'B'의 값을 표시 할

<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'

(루트 데이터/코드 = 'A'/ 경우), 다른 2 열 ('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">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> 

15,여기에 XSL-FO 코드는 하나의 칼럼에 대해 도시된다. 세부

조건 :

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 

즉 A의 20, 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']) 

뿐만 아니라 현재 값을 포함하려면 다음과 같이 노동 조합 연산자를 사용 :

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

더 큰 어려움은 다른를 보여주는 것입니다 각 페이지에 'footer'테이블. 머리글과 바닥 글은 자동으로 페이지에서 반복되지만 내용은 테이블이 포함되는 모든 페이지에서 동일합니다. 내가 볼 수있는 유일한 해결책은 매번 다른 테이블 바닥 글을 추가하여 테이블을 직접 끊는 것입니다.

가장 쉬운 방법은 한 번에 고정 된 수의 데이터 요소를 가져 와서 별도의 테이블에 표시하는 것입니다. 각각 for-each에서 A, B 및 C 유형을 반복하여 각 값에 별도의 행을 제공 할 수 있습니다. 그런 식으로 테이블의 행 수가 항상 같습니다. 한 페이지에 맞는 수를 결정할 때 포함 할 수있는 숫자를 시험해 볼 수 있습니다.

다음 코드는 처음 10 개의 데이터 값이있는 테이블을 반환합니다. A, B 및 C 값은 서로 아래에 똑바로 배치되지만 원하는 경우 왼쪽, 가운데 및 오른쪽으로 각각 배치 할 수 있습니다. 테이블 아래에있는 세 개의 행이 A, B와 C

에 대한 소계에 추가됩니다 당신은 여전히 ​​몇 가지 재귀 호출을 당신이 필요로 얼마나 많은 N 개의 데이터 항목의 테이블을 결정하고 뭔가가 필요
<?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> 

모두 출력하십시오. 이 순간이 당신을 다시 만날 수 있기를 희망합니다!

추신 : xfd 접두사를 사용하고있는 것으로 나타났습니다.Ecrion의 XF 디자이너와 함께 작업하는 것처럼 보입니다. 나는 그것에 익숙하지 않다. 위의 코드는 일반 XSLT 1.0 솔루션입니다. XF Designer에서 작동하는지 확실하지 않으니 알려주세요.

+0

@BVS 어리석은 저, 나는 완전히 잊고 있습니다 : 마커. 누적 합계가 A, B 및 C 인 마커 클래스 이름을 포함하는 각 표 셀에 fo : 마커를 넣을 수 있어야합니다. fo : retrieve-table-marker를 사용하여 현재 페이지의 마지막 마커 값을 테이블 바닥 글로 가져올 수 있어야합니다. 내 예를 바꾸려고했지만 FOP가이 예제를 지원하지 않는 것 같습니다. 따라서 시도할만한 가치가있을 수 있지만 프로세서가 지원하지 않을 수도 있습니다. HTH! – grtjn

+0

fo : marker 도움을 주셔서 감사합니다. ton guy – BVS