2017-08-11 156 views
1

我有一个xml文档,如下所示。每个重复文档为PDF文件中的页面需要动态更改简单页面主文件的主名称

<AFPXMLFile> 
    <docs> 
     <regList> 
      <region>1</region> 
      <secList> 
       <col>1</col> 
       <lines></lines> 
      </secList> 
    </regList> 
    <regList> 
     <region>2</region> 
     <secList> 
       <col>2</col> 
       <lines> 
        <line>IBM BELGIUM xxx</line> 
        <line>xxxxxx</line> 
        <line>xxxx</line> 
       </lines> 
     </secList> 
    </regList> 
    <regList></regList> 
    <regList></regList> 
    </docs> 
    <docs></docs> 
</AFPXMLFile> 

我的XSL如下:

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

<xsl:template match="AFPXMLFile"> 
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> 
<fo:layout-master-set> 
<fo:simple-page-master page-width="21cm" page-height="29.7cm" margin-top="1.27cm" margin-bottom="1.27cm" margin-left="1.75cm" master-name="A4"> 
    <fo:region-body margin-top="1mm" margin-bottom="1mm"/> 
    <fo:region-before extent="0mm"/> 
    <fo:region-after extent="0mm"/> 
    <fo:region-start writing-mode="tb-rl" precedence="true" extent="10mm" /> 
</fo:simple-page-master> 
</fo:layout-master-set> 
<fo:page-sequence master-reference="A4" font-family="sans-serif"> 
<xsl:for-each select="docs"> 
    <xsl:for-each select="./regList"> 
     <xsl:choose> 
      <xsl:when test="region = 1"> 
       <fo:static-content flow-name="xsl-region-before"> 
        <xsl:for-each select="./secList/lines"> 
         <xsl:for-each select="node()"> 
          <fo:block font-size="8pt" color="purple"> 
           <xsl:value-of select="."/> 
          </fo:block>         
         </xsl:for-each> 
        </xsl:for-each> 
       </fo:static-content> 
      </xsl:when> 
      <xsl:when test="region = 2"> 
       <fo:static-content flow-name="xsl-region-start"> 
        <xsl:for-each select="./secList/lines"> 
         <xsl:for-each select="node()"> 
           <fo:block font-size="4pt" padding-before="4pt" text-align="left" color="green"> 
            <xsl:value-of select="."/> 
           </fo:block> 
         </xsl:for-each> 
        </xsl:for-each> 
       </fo:static-content>  
      </xsl:when> 
      <xsl:when test="region = 3"> 
       <fo:static-content flow-name="xsl-region-body"> 
        <xsl:for-each select="./secList/lines"> 
         <xsl:for-each select="node()"> 
          <fo:block font-size="8pt" color="blue"> 
           <xsl:value-of select="."/> 
          </fo:block> 
         </xsl:for-each> 
        </xsl:for-each> 
       </fo:static-content> 
      </xsl:when> 
      <xsl:when test="region = 4"> 
       <fo:flow flow-name="xsl-region-after"> 
        <xsl:for-each select="./secList"> 
         <xsl:for-each select="./lines"> 
          <xsl:for-each select="node()"> 
           <fo:block font-size="8pt" color="orange"> 
            <xsl:value-of select="."/> 
           </fo:block> 
          </xsl:for-each> 
         </xsl:for-each> 
        </xsl:for-each> 
       </fo:flow>  
      </xsl:when> 
     </xsl:choose>       
    </xsl:for-each> 
</xsl:for-each> 
</fo:page-sequence> 
</fo:root> 
</xsl:template> 
</xsl:stylesheet> 

当我运行转换我收到以下错误:

org.apache.fop.fo.ValidationException: For "fo:page-sequence", "fo:static-content" must be declared before "fo:flow"! (No context info available)

这我怀疑因为它正在为每个页面重复静态内容区域。所以我相信我需要为每个页面更改简单页面主页:主页名称,我需要帮助。

回答

1

按照XSL-FO recommendation,的“FO:页面序列”的内容是:

(title?,folio-prefix?,folio-suffix?,static-content*,flow+)

,这意味着所有的fo:static-content元素必须fo:flow元件。

样式表动态地创建任一fo:static-content(如果region是1,2或3)或fo:flow(如果region是4)。从您的问题中减少的输入文件中,无法查看regList元素是否总是正确排序,以便它们在顺序处理时生成有效输出。

而且,因为每个docs元素代表了不同的页眉/页脚不同的文档,你必须创建不同的fo:page-sequence!而非单一的一个(否则你得到太多的静态内容,单个页面顺序流):

<xsl:for-each select="docs"> 
    <fo:page-sequence master-reference="A4" font-family="sans-serif"> 
     <xsl:for-each select="./regList"> 
      .... 
     </xsl:for-each> 
    </fo:page-sequence> 
</xsl:for-each> 

此外,还有一个奇怪的东西在样式表:你的fo:static-contentxsl-region-body区域,fo:flow映射到xsl-region-after地区,这是相当不寻常。如果“真实”的内容为身体区域是一个与region = 3,则必须处理region 1,2和4 第一,和然后区域3:

<xsl:for-each select="docs"> 
    <fo:page-sequence master-reference="A4" font-family="sans-serif"> 
     <!-- create static contents --> 
     <xsl:apply-templates select="./regList[region != '3']"/> 
     <!-- create flow --> 
     <xsl:apply-templates select="./regList[region = '3']"/> 
    </fo:page-sequence> 
</xsl:for-each> 

与另外的模板比赛reglist

<xsl:template match="regList"> 
    <xsl:choose> 
     <xsl:when test="region = '1'"> 
      <fo:static-content flow-name="xsl-region-before"> 
       <xsl:for-each select="./secList/lines"> 
        <xsl:for-each select="node()"> 
         <fo:block font-size="8pt" color="purple"> 
          <xsl:value-of select="."/> 
         </fo:block>         
        </xsl:for-each> 
       </xsl:for-each> 
      </fo:static-content> 
     </xsl:when> 
     <xsl:when test="region = '2'"> 
      <fo:static-content flow-name="xsl-region-start"> 
       <xsl:for-each select="./secList/lines"> 
        <xsl:for-each select="node()"> 
          <fo:block font-size="4pt" padding-before="4pt" text-align="left" color="green"> 
           <xsl:value-of select="."/> 
          </fo:block> 
        </xsl:for-each> 
       </xsl:for-each> 
      </fo:static-content>  
     </xsl:when> 
     <xsl:when test="region = '3'"> 
      <fo:flow flow-name="xsl-region-body"> 
       <xsl:for-each select="./secList/lines"> 
        <xsl:for-each select="node()"> 
         <fo:block font-size="8pt" color="blue"> 
          <xsl:value-of select="."/> 
         </fo:block> 
        </xsl:for-each> 
       </xsl:for-each> 
      </fo:flow> 
     </xsl:when> 
     <xsl:when test="region = '4'"> 
      <fo:static-content flow-name="xsl-region-after"> 
       <xsl:for-each select="./secList"> 
        <xsl:for-each select="./lines"> 
         <xsl:for-each select="node()"> 
          <fo:block font-size="8pt" color="orange"> 
           <xsl:value-of select="."/> 
          </fo:block> 
         </xsl:for-each> 
        </xsl:for-each> 
       </xsl:for-each> 
      </fo:static-content>  
     </xsl:when> 
    </xsl:choose> 
</xsl:template> 

或几个较小的模板:

<xsl:template match="reglist[region = '1']"> 
    <fo:static-content flow-name="xsl-region-before"> 
     <xsl:for-each select="./secList/lines"> 
      <xsl:for-each select="node()"> 
       <fo:block font-size="8pt" color="purple"> 
        <xsl:value-of select="."/> 
       </fo:block>         
      </xsl:for-each> 
     </xsl:for-each> 
    </fo:static-content> 
</xsl:template> 

<xsl:template match="reglist[region = '2']"> 
    ... 
</xsl:template> 

... 
+0

感谢您回复我的问题。我是新来的FOP。是的,regList总是在文档元素中按1,2,3和4排序。 XSL适用于PDF的第一页,当它再次遇到下一页的区域1时会失败。我有fo:为区域流动 - 之后的原因是当我添加的是在任何其他地区之前它给我错误说所有静态内容应该在流动之前。我不知道如何修改循环以避免重复。你能否给我提供一些指导。 – Madhu

+0

回复更新为解决您的意见。 – lfurini

+0

感谢您的更新。我用你的第一个解决方案,它正在工作。 – Madhu