Board logo

标题: HTML 至格式化对象(FO)转换指南(9)命名锚点引用 [打印本页]

作者: look_w    时间: 2018-7-15 08:37     标题: HTML 至格式化对象(FO)转换指南(9)命名锚点引用

<sup> 上标文本正如下标文本一样,可使用 XSL-FO                 vertical-align 属性来处理上标文本。以下是一个 HTML 样本:            
1
2
<p>Einstein's famous e=mc<sup>2</sup>
  is an equation that changed the world. </p>




以下是我们的 XSLT 模板:
1
2
3
4
5
6
7
8
<xsl:template match="sup">
  <fo:inline
         
        vertical-align="super"
        font-size="75%">
    <xsl:apply-templates select="*|text()"/>
  </fo:inline>
</xsl:template>




<table> 表标记要处理 HTML                 <table> 元素,最大的难题是确定 XSL-FO 表应该有多少列,以及这些列的宽度。FOP 要求为表中的每一列提供一个                 <fo:table-column> 元素。一旦处理完这些列,就只需调用表中所有元素的 XSLT 模板。这一 XSLT 模板处理类似于这样的                 cols :            
1
<table cols="200 100pt" border="1">




需要将                 cols 属性转换成以下标记:            
1
2
<fo:table-column column-width="200pt"/>
<fo:table-column column-width="100pt"/>




要实现这一转换,需要使用常用的被称为                尾递归(tail recursion)的 XSLT 技术。创建这样一个指定的模板:它使用属性值的首个单词,将其转换成                 <fo:table-column> 元素,然后调用自身以处理属性值的余下部分。最终,处理整个属性。下面来看这个 XSLT 模板是如何处理                 <table> 元素的:            
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<xsl:template match="table">
  <fo:table
         
        table-layout="fixed">
    <xsl:choose>
      
         
        <xsl:when test="@cols">
        <xsl:call-template name="build-columns">
          <xsl:with-param name="cols"
            select="concat(@cols, ' ')"/>
        </xsl:call-template>
      </xsl:when>
      <xsltherwise>
        <fo:table-column column-width="200pt"/>
      </xsltherwise>
    </xsl:choose>
    <fo:table-body>
      <xsl:apply-templates select="*"/>
    </fo:table-body>
  </fo:table>
</xsl:template>




如果有                 cols 属性,则处理器调用                 build-columns 模板;否则它创建一个                 <fo:table-column> 元素。另请注意:                 <fo:table> 元素有属性                 table-layout="fixed" ;目前,如果没有该属性,FOP 会发出一条警告消息。            
让我们研究一下                 build-columns 模板:            
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<xsl:template
         
        name="build-columns">
  <xsl:param name="cols"/>
   
  <xsl:if test="string-length(normalize-space($cols))">
    <xsl:variable name="next-col">
      <xsl:value-of select="substring-before($cols, ' ')"/>
    </xsl:variable>
    <xsl:variable name="remaining-cols">
      <xsl:value-of select="substring-after($cols, ' ')"/>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="contains($next-col, 'pt')">
        <fo:table-column column-width="{$next-col}"/>
      </xsl:when>
      <xsl:when test="number($next-col) > 0">
        <fo:table-column column-width="{concat($next-col, 'pt')}"/>
      </xsl:when>
      <xsltherwise>
        <fo:table-column column-width="50pt"/>
      </xsltherwise>
    </xsl:choose>
     
    <xsl:call-template name="build-columns">
      <xsl:with-param name="cols" select="concat($remaining-cols, ' ')"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>




首先,模板在除去所有首尾处的空白(这是 XSLT                 normalize-space() 函数所做的工作)之后检查                 $cols 参数的长度。接下来,它将                 $cols 值分为两部分:第一个空格                之前的子串,和                之后的所有内容。(注:当处理器从                 <table> 元素的模板调用该模板时,它将一个空格添加到值的末尾,因此始终至少有一个空格。)            
既然                 $cols 参数被分为两部分,则首先处理第一部分:            
在处理器处理完                 $cols 参数的第一部分之后,这个指定的模板用                 $cols 参数的最后部分调用自己,并在值的末尾添加一个空格以确保存在空格。









欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0