XSLT для вывода простой текстовой таблицы - PullRequest
4 голосов
/ 17 августа 2010

Я работаю над шаблоном XSL для преобразования документа XHTML / hResume в обычный текст, и у меня возникают проблемы с макетом таблицы (нет, не с таблицами макетов).На данный момент у меня есть следующее, используя превосходный шаблон заполнения Дейва Поусона :

<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 голосов
/ 18 августа 2010

С помощью "global" (для каждой ячейки таблицы) $maxWith вы можете обрабатывать colspans, как эта таблица стилей (сохраняя вашу собственную логику):

<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   

EDIT : чтобы центрировать ячейки с помощью 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">
        <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   
...