2015-06-16 2 views
1

У меня есть один набор данных с различным списком атрибутов (около 15), как показано ниже.Как динамически генерировать цвет строк в XSL: FO без xsl: for-each

Примеры данных 1:

<cd> 
    <name>Tom</name> 
    <address>Madison Square</address> 
    <phone>000-000-0000</phone> 
</cd> 

Примеры данных 2:

<cd> 
    <name>Tom</name> 
    <city>New York</city> 
    <phone>000-000-0000</phone> 
</cd> 

Полный список атрибутов (подмножество):

<cd> 
    <name>xxx</name> 
    <address>xxxx</address> 
    <city>xxxx</city> 
    <phone>000-000-0000</phone> 
</cd> 

Я хочу построить ВОК: стол с альтернативные цвета строк для этой динамической таблицы. Я пробовал использовать xsl: for-each и position(), но это не работает. Есть ли способ получить свойства предыдущих строк, например, цвет? Какие-либо предложения.

Добавлен код для справки:

 <fo:table-row> 
      <fo:table-cell padding-left="3pt" padding-top="8pt"> 
       <fo:block> <xsl:value-of select="cd/name"/></fo:block>    
      </fo:table-cell> 
     </fo:table-row> 
     <xsl:if test="normalize-space(cd/address) !=''"> 
      <fo:table-row background-color="#EEF0F2" > 
      <fo:table-cell padding-left="3pt" padding-top="8pt"> 
       <fo:block> <xsl:value-of select="cd/address"/></fo:block>     
      </fo:table-cell> 
      </fo:table-row> 
     </xsl:if> 
     <xsl:if test="normalize-space(cd/city) !=''"> 
      <fo:table-row background-color="#EEF0F2" > 
      <fo:table-cell padding-left="3pt" padding-top="8pt"> 
       <fo:block> <xsl:value-of select="cd/city"/></fo:block>     
      </fo:table-cell> 
      </fo:table-row>    
     </xsl:if> 

ответ

1

Ваш пример кода не достаточно. Мы понятия не имеем о контексте. Что-то воспроизводимое (что-то, что мы могли бы запустить) было бы идеальным.

Вот общий ответ, который должен помочь.

Что вы можете сделать, это использовать xsl:apply-templates для обработки детей cd, которые не являются пустыми. Это изменяет набор узлов, который обрабатывается, и позволит position() работать правильно.

Примечание: вы также можете сделать это с помощью xsl:for-each. Однако, если вы трансформируете что-либо, кроме самого простого XML, в очень простой XSL-FO, вам лучше использовать подход push, а не подход pull. Это упростит работу и масштабирование вашего XSLT.

Затем вы можете использовать mod, чтобы узнать, делится ли позиция на 2. Если есть, добавьте фоновый цвет.

Пример:

XML-вход

<cd> 
    <name>xxx</name> 
    <address>xxxx</address> 
    <city>xxx</city> 
    <whatevs></whatevs> 
    <phone>000-000-0000</phone> 
</cd> 

XSLT-1,0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/"> 
     <fo:root> 
      <fo:layout-master-set> 
       <fo:simple-page-master master-name="my-page" page-width="8.5in" page-height="11in"> 
        <fo:region-body margin="1in" margin-top="1.5in" margin-bottom="1.5in"/> 
       </fo:simple-page-master> 
      </fo:layout-master-set> 
      <fo:page-sequence master-reference="my-page"> 
       <fo:flow flow-name="xsl-region-body"> 
        <fo:table> 
         <fo:table-body> 
          <xsl:apply-templates select="cd/*[string()]"/>        
         </fo:table-body> 
        </fo:table> 
       </fo:flow> 
      </fo:page-sequence> 
     </fo:root> 
    </xsl:template> 

    <xsl:template match="cd/*"> 
     <fo:table-row>    
      <xsl:if test="position() mod 2"> 
       <xsl:attribute name="background-color"> 
        <xsl:text>#EEF0F2</xsl:text> 
       </xsl:attribute> 
      </xsl:if> 
      <fo:table-cell padding-left="3pt" padding-top="8pt"> 
       <fo:block><xsl:value-of select="."/></fo:block>     
      </fo:table-cell> 
     </fo:table-row> 
    </xsl:template> 

</xsl:stylesheet> 

XSL-FO Выход

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> 
    <fo:layout-master-set> 
     <fo:simple-page-master master-name="my-page" page-width="8.5in" page-height="11in"> 
     <fo:region-body margin="1in" margin-top="1.5in" margin-bottom="1.5in"/> 
     </fo:simple-page-master> 
    </fo:layout-master-set> 
    <fo:page-sequence master-reference="my-page"> 
     <fo:flow flow-name="xsl-region-body"> 
     <fo:table> 
      <fo:table-body> 
       <fo:table-row background-color="#EEF0F2"> 
        <fo:table-cell padding-left="3pt" padding-top="8pt"> 
        <fo:block>xxx</fo:block> 
        </fo:table-cell> 
       </fo:table-row> 
       <fo:table-row> 
        <fo:table-cell padding-left="3pt" padding-top="8pt"> 
        <fo:block>xxxx</fo:block> 
        </fo:table-cell> 
       </fo:table-row> 
       <fo:table-row background-color="#EEF0F2"> 
        <fo:table-cell padding-left="3pt" padding-top="8pt"> 
        <fo:block>xxx</fo:block> 
        </fo:table-cell> 
       </fo:table-row> 
       <fo:table-row> 
        <fo:table-cell padding-left="3pt" padding-top="8pt"> 
        <fo:block>000-000-0000</fo:block> 
        </fo:table-cell> 
       </fo:table-row> 
      </fo:table-body> 
     </fo:table> 
     </fo:flow> 
    </fo:page-sequence> 
</fo:root> 

Вынесено PDF (используется ФОП 1,1)

enter image description here

+1

Этот вариант решил мою проблему! Сегодня я обновлю весь код –

0

Разместите код. Одной из стратегий в таких случаях было бы сначала создать таблицу в переменной, а затем скопировать ее на вывод, добавив цветной тег во время выполнения. Это может быть менее беспорядочно.

+0

Обновленный код. –