我正在使用样式表来转换类似于IETF(即xhtml)表的表,但是面向列的表转换为xsl-fo。
最初的步骤之一是转换< col />标签到< fo:table-column />标签。 不幸的是,出于某种原因,XSL 1.1规范的作者没有提供一种从< fo:table-column />自动传输所有属性的方法。在相应列中的表格单元格中,属性(宽度除外)也不会自动应用(在我看来,真的是愚蠢的设计决策 - here is one of the Antenna House developers complaining about the same thing in 2001!)。继承不适用于< fo:table-column />没有孩子。
这使我的任务是找出为每列设置的格式化属性,并手动将它们应用到适当的表格单元格。但是如何最好地做到这一点?我有一个想法是放置所有< fo:table-column />将节点转换为变量,但那我将如何使用xpath处理这些节点?另一个想法是必须有一种方法来使用临时结果树来做到这一点,但从来没有使用过这样的东西,并且对于这是否可行是无能为力的,如果是,那么如何使用临时结果树。我是用标签XSLT 1.0和XSLT 2.0发布这个问题,只是为了看是的答案,但我真的不得不使用XSLT 1.0解决这个问题。
编辑:有人请求了一个具体的例子。源文档片段可能如下所示:
<table>
<col width="33%" font-weight="bold" border="1pt solid black"/>
<col width="34%" span="2" color="red" background-color="gray"/>
<col font-style="italic" align="center" background-color="yellow"/>
<tr><td>A</td><td>B</td><td>C</td><td>D</td></tr>
<tr><td>dog</td><td>cat</td><td>mouse</td><td>elephant</td></tr>
...
</table>
即。一个标准的xhtml表,除了一些通常使用style属性表示的属性。
然后自然翻译
<table> --> <fo:table>
<col/> --> <fo:table-column/>
<tr> --> <fo:table-row>
<td> --> <fo:table-cell>
然而,这有一个问题,即&lt; table-column /&gt;中没有任何属性。自动应用于相应列中的表格单元格,除非您明确要求使用 from-table-colum()函数调用它们( 的宽度除外) >自动应用)。因此,例如,对于表格 3rd 列中的表格单元格,我需要像这样输出fo:
<fo:table-cell color="from-table-column()" background-color="from-table-column()>
对于 4th 列中的表格单元格,我需要输出
<fo:table-cell font-style="from-table-column()" align="from-table-column()" background-color="from-table-column()>
问题是你如何知道在特定列中寻找表格单元的属性?
答案 0 :(得分:1)
对于XSLT 1.0,包含结果节点的变量是一个结果树片段,要将其转换为应用于应用XPath的节点集,或者进一步处理节点,您将使用exsl:node-set
或类似的例如
<xsl:variable name="v1-rtf">
<fo:table-column>...</fo:table:column>
</xsl:variable>
<xsl:variable name="v1-ns" xmlns:exsl="http://exslt.org/common" select="exsl:node-set($v1-rtf)"/>
<xsl:apply-templates select="$v1-ns/fo:table-column"/>
XSLT 2.0的唯一区别在于您不需要exsl:node-set
函数及其转换操作,您可以直接使用任何带有临时树的变量,例如。
<xsl:variable name="v1">
<fo:table-column>...</fo:table:column>
</xsl:variable>
<xsl:apply-templates select="$v1/fo:table-column"/>
答案 1 :(得分:1)
警告 :我对XSL-FO一无所知;这只是你用作起点的东西。
我理解你的问题的方式,你希望每个表格单元格与源文档中相应的col
具有相同的属性列表。通过查看当前处理的td
的位置并使用它在相同的相对位置查找col
,这很容易实现。但是,由于某些col
元素具有span
属性,因此这并不容易。
我建议的解决方案是从“枚举”col
元素开始,这样就有与列一样多的元素。有了这个,我们就可以按计划进行。
以下样式表:
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"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="columns">
<xsl:for-each select="/table/col">
<xsl:call-template name="replicate">
<xsl:with-param name="n">
<xsl:choose>
<xsl:when test="@span">
<xsl:value-of select="@span"/>
</xsl:when>
<xsl:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/table">
<fo:table>
<xsl:apply-templates/>
</fo:table>
</xsl:template>
<xsl:template match="tr">
<fo:table-row>
<xsl:apply-templates select="td"/>
</fo:table-row>
</xsl:template>
<xsl:template match="td">
<xsl:variable name="i" select="position()" />
<fo:table-cell>
<xsl:for-each select="exsl:node-set($columns)/col[$i]/@*[not(name()='width' or name()='span')]">
<xsl:attribute name="{name()}">from-table-column()</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</fo:table-cell>
</xsl:template>
<xsl:template name="replicate">
<xsl:param name="n"/>
<xsl:if test="$n">
<xsl:copy-of select="."/>
<xsl:call-template name="replicate">
<xsl:with-param name="n" select="$n - 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例时,将生成以下结果:
<?xml version="1.0" encoding="utf-8"?>
<fo:table xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:table-row>
<fo:table-cell font-weight="from-table-column()" border="from-table-column()">A</fo:table-cell>
<fo:table-cell color="from-table-column()" background-color="from-table-column()">B</fo:table-cell>
<fo:table-cell color="from-table-column()" background-color="from-table-column()">C</fo:table-cell>
<fo:table-cell font-style="from-table-column()" align="from-table-column()" background-color="from-table-column()">D</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell font-weight="from-table-column()" border="from-table-column()">dog</fo:table-cell>
<fo:table-cell color="from-table-column()" background-color="from-table-column()">cat</fo:table-cell>
<fo:table-cell color="from-table-column()" background-color="from-table-column()">mouse</fo:table-cell>
<fo:table-cell font-style="from-table-column()" align="from-table-column()" background-color="from-table-column()">elephant</fo:table-cell>
</fo:table-row>
</fo:table>
这假设表格单元本身没有跨度;否则这会变得复杂得多。