2012-01-03 2 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) содержит 3 колонки, где каждый столбец содержит содержание 'A', '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> 

же код для каждой колонки, чтобы отобразить значения «B» & «C» в таблице-футовой я получить эти промежуточные итоги в «A», «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> 

Вот код XSL-FO показан только один колонке (для корневых/данных/Код = 'А'), остальные 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 А, в 10-х и B 25 C о наличии в источнике XML.

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: ключ, группируя через -тэг для оценки суммы «A», «B» и «C». Поскольку я новичок в 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']) 

Большей трудность заключается, чтобы показать другие table 'footer' на каждой странице. Верхние и нижние колонтитулы повторяются на страницах автоматически, но содержимое одинаково для всех страниц, на которые распространяется таблица. Единственное решение, которое я вижу, - сломать таблицу самостоятельно, каждый раз добавляя другой столбец.

Самым простым способом является просто фиксированное количество элементов данных за раз и отображение их в отдельной таблице. Вы можете циклически перемещаться по типам A, B и C по одному для каждого, предоставляя каждому значению отдельную строку. Таким образом, таблица всегда имеет одинаковое количество строк. Вы можете поэкспериментировать с номером, который вы можете включить, чтобы определить, сколько поместится на одной странице.

Следующий код возвращает таблицу с первыми 10 значениями данных. Значения A, B и C расположены прямо друг под другом, но вы можете поместить их влево, в середине и вправо соответственно, если хотите. В нижней части таблицы добавляется три строки с подытог для 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.Похоже, вы работаете с XF Designer от Ecrion. Я не очень хорошо знаком с этим. Вышеприведенный код является простым решением XSLT 1.0. Не уверен, что это работает в XF Designer, пожалуйста, дайте мне знать ..

+0

@BVS Глупый, я полностью забываю fo: marker. Должно быть возможно поставить fo: marker в каждой ячейке таблицы, содержащей текущее общее количество A, B и C (отдельное имя класса маркера). Вы должны использовать fo: retrieve-table-marker, чтобы вывести последнее значение маркера текущей страницы в нижний колонтитул. Я попытался изменить свой пример, но FOP, похоже, не поддерживает это. Так что стоит попробовать, но вы можете узнать, что ваш процессор не поддерживает его. НТН! – grtjn

+0

fo: marker помог мне много. Спасибо тонны парням – BVS

 Смежные вопросы

  • Нет связанных вопросов^_^