将XSLT转换为输出纯文本表格

4
我正在制作一个XSL模板,将XHTML/hResume文档转换为纯文本,但我在表格布局方面遇到了麻烦(不是布局表格的问题)。目前我使用了优秀的Dave Pawson的填充模板,代码如下:padding template
<variable name="newline" select="'&#10;'"/>
<template match="xhtml:table">
    <variable name="maxWidth">
        <for-each select="xhtml:tr/xhtml:th | xhtml:tr/xhtml:td">
            <sort select="string-length(child::text()|child::node())" order="descending" data-type="number"/>
            <if test="position() = 1">
                <value-of select="string-length(child::text()|child::node())"/>
            </if>
        </for-each>
    </variable>
    <for-each select="xhtml:tr">
        <for-each select="xhtml:th|xhtml:td">
            <variable name="string">
                <for-each select="child::text()|child::node()">
                    <value-of select="."/>
                </for-each>
            </variable>
            <value-of select="$string"/>
            <call-template name="append-pad">
                <with-param name="length" select="$maxWidth - string-length($string)"/>
            </call-template>
            <text>&#32;</text>
        </for-each>
        <value-of select="$newline"/>
    </for-each>
    <value-of select="$newline"/>
</template>

这将产生等宽的列,但我想在以下几个方面进行改进:

  • 查找并使用每列的最大宽度。为此,需要存储灵活数量的值。在简单情况下,我可以更改maxWidth来实现这一点,但如何处理跨列?
  • 居中跨列的内容。

有没有类似于此的模板可以使用?

1个回答

4

使用一个“全局”(对于表中的每个单元格)$maxWith,您可以像这个样式表一样处理colspan(保留您自己的逻辑):

<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <output method="text"/>
    <variable name="newline" select="'&#10;'"/>
    <template match="xhtml:table">
        <variable name="maxWidth">
            <for-each select="xhtml:tr/xhtml:th | xhtml:tr/xhtml:td">
                <sort select="string-length(child::text()|child::node())" order="descending" data-type="number"/>
                <if test="position() = 1">
                    <value-of select="string-length(child::text()|child::node())"/>
                </if>
            </for-each>
        </variable>
        <for-each select="xhtml:tr">
            <for-each select="xhtml:th|xhtml:td">
                <variable name="string">
                    <for-each select="child::text()|child::node()">
                        <value-of select="."/>
                    </for-each>
                </variable>
                <variable name="padding">
                    <choose>
                        <when test="@colspan">
                            <value-of select="$maxWidth * @colspan + @colspan - 1 - string-length($string)"/>
                        </when>
                        <otherwise>
                            <value-of select="$maxWidth - string-length($string)"/>
                        </otherwise>
                    </choose>
                </variable>
                <value-of select="$string"/>
                <call-template name="append-pad">
                    <with-param name="length" select="$padding"/>
                </call-template>
                <text>&#32;</text>
            </for-each>
            <value-of select="$newline"/>
        </for-each>
        <value-of select="$newline"/>
    </template>
    <template name="append-pad">
        <param name="length" select="0"/>
        <if test="$length != 0">
            <value-of select="'&#32;'"/>
            <call-template name="append-pad">
                <with-param name="length" select="$length - 1"/>
            </call-template>
        </if>
    </template>
</stylesheet>

输入:

<table xmlns="http://www.w3.org/1999/xhtml">
    <tr>
        <th>First</th>
        <th>Second</th>
        <th>Third</th>
    </tr>
    <tr>
        <td>One</td>
        <td>Two</td>
        <td>Three</td>
    </tr>
    <tr>
        <td colspan="2">Uno</td>
        <td>Tres</td>
    </tr>
</table>

输出:

First  Second Third  
One    Two    Three  
Uno           Tres   

编辑:为了将跨列单元格居中,使用以下样式表(现在带有我的逻辑):

<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <output method="text"/>
    <variable name="newline" select="'&#10;'"/>
    <template match="xhtml:table">
        <apply-templates>
            <with-param name="maxWidth">
                <for-each select="xhtml:tr/xhtml:th | xhtml:tr/xhtml:td">
                    <sort select="string-length(.)" order="descending" data-type="number"/>
                    <if test="position() = 1">
                        <value-of select="string-length(.)"/>
                    </if>
                </for-each>
            </with-param>
        </apply-templates>
        <value-of select="$newline"/>
    </template>
    <template match="xhtml:tr">
        <param name="maxWidth"/>
        <apply-templates>
            <with-param name="maxWidth" select="$maxWidth"/>
        </apply-templates>
        <value-of select="$newline"/>
    </template>
    <template match="xhtml:th|xhtml:td">
        <param name="maxWidth"/>
        <variable name="string">
            <for-each select="child::text()|child::node()">
                <value-of select="."/>
            </for-each>
        </variable>
        <variable name="padding">
            <choose>
                <when test="@colspan">
                    <value-of select="($maxWidth * @colspan + @colspan - 1 - string-length($string)) div 2"/>
                </when>
                <otherwise>
                    <value-of select="$maxWidth - string-length($string)"/>
                </otherwise>
            </choose>
        </variable>
        <if test="@colspan">
            <call-template name="append-pad">
                <with-param name="length" select="floor($padding)"/>
            </call-template>
        </if>
        <value-of select="$string"/>
        <call-template name="append-pad">
            <with-param name="length" select="ceiling($padding)"/>
        </call-template>
        <text>&#32;</text>
    </template>
    <template name="append-pad">
        <param name="length" select="0"/>
        <if test="$length != 0">
            <value-of select="'&#32;'"/>
            <call-template name="append-pad">
                <with-param name="length" select="$length - 1"/>
            </call-template>
        </if>
    </template>
</stylesheet>

输出:

First  Second Third  
One    Two    Three  
     Uno      Tres   

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接