Главная » XSLT » Вывод текста в области заданной ширины с заданным выравниванием

0

Задача

Требуется вывести многострочный текст, присутствующий в XML-докумен- те, в области фиксированной ширины. При этом перенос строк должен произво­диться по границам слов.

Решение

Вот решение, в котором перенос и выравнивание достигаются за счет повтор­ного использования шаблона text:justify из рецепта 7.3. Для пущей гибкости ширину области выравнивания можно задавать независимо от ширины области переноса, считая, что по умолчанию они совпадают.

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform" id="text.wrap" xmlns:str="http://www.ora.com/XSLTCookbook/namespaces/strings"

xmlns:text="http://www.ora.com/XSLTCookbook/namespaces/text" exclude-result-prefixes="text">

<xsl:include href="../strings/str.find-last.xslt"/> <xsl:include href="text.justify.xslt"/>

<xsl:template match="node() | @*" mode="text:wrap" name="text:wrap"> <xsl:param name="input" select="normalize-space()"/> <xsl:param name="width" select="7 0"/> <xsl:param name="align-width" select="$width"/> <xsl:param name="align" select=" ‘left’ "/>

<xsl:if test="$input">

<xsl:variable name="line"> <xsl:choose>

<xsl:when test="string-length($input) > $width">

<xsl:call-template name="str:substring-before-last" <xsl:with-param name="input"

select="substring($input,1,$width)"/> <xsl:with-param name="substr" select=" ‘ ‘ "/> </xsl:call-template> </xsl:when> <xsl:otherwise>

<xsl:value-of select="$input"/> </xsl:otherwise> </xsl:choose> </xsl:variable>

<xsl:if test="$line">

<xsl:call-template name="text:justify">

<xsl:with-param name="value" select="$line"/>

<xsl:with-param name="width" select="$align-width"/> <xsl:with-param name="align" select="$align"/> </xsl:call-template> <xsl:text>&#xa;</xsl:text> </xsl:if>

<xsl:call-template name="text:wrap"> <xsl:with-param name="input"

select="substring($input, string-length($line) + 2)"/> <xsl:with-param name="width" select="$width"/> <xsl:with-param name="align-width" select="$align-width"/> <xsl:with-param name="align" select="$align"/> </xsl:call-template>

</xsl:if> </xsl:template>

В этом решении используется шаблон str:substring-before-last из рецепта 2.4. Основная идея заключается в том, чтобы извлечь строку длиной не более $width символов или меньше, если в конце окажется не пробел. Остаток строки далее обрабатывает рекурсивно. Нетривиальная часть – сделать так, что­бы слово, содержащее не менее $width символов, разбивалось на части.

Ниже показан результат применения этого рецепта к конкретному тексту. Для демонстрации ширина выравнивания и ширина переноса выбраны раз­личными:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:text="http://www.ora.com/XSLTCookbook/namespaces/text">

<xsl:include href="text.wrap.xslt"/>

<xsl:strip-space elements="*"/> <xsl:output method="text"/>

<xsl:template match="p">

<xsl:apply-templates select="." mode="text:wrap"> <xsl:with-param name="width" select="40"/> <xsl:with-param name="align" select=" ‘center’ "/> <xsl:with-param name="align-width" select="60"/> </xsl:apply-templates> <xsl:text>&#xa;</xsl:text> </xsl:template>

</xsl:stylesheet>

Входной документ: <doc>

<p>In the age of the internet, formats such HTML, XHTML and PDF clearly dominate the application of XSL and XSLT. However, plain old text will never become obsolete because it is the lowest common denominator in both human and machine-readable formats. XML is often converted to text to be imported into another application that does not know how to read XML or does not interpret it the way you would prefer. Text output is also used when the result will be sent to a terminal or post processed in a Unix pipeline.</p>

<p>Many recipes in this section place stress on XSLT techniques that create very generic XML to text converters. Here generic means that the transformation can easily be customized to work on many different XML inputs or produce a variety of outputs or both. The techniques employed in these recipes have application beyond specifics of a given recipe and often beyond the domain of text processing. In particular, you may want to

look at recipes 7.2 through 7.5 even if they do not address a present need. </p>

</doc> Результат:

In the age of the internet, formats

such HTML, XHTML and PDF clearly dominate the application of XSL and XSLT. However, plain old text will never become obsolete because it is the lowest common denominator in both human and machine-readable formats. XML is often converted to text to be imported into another application that does not

know how to read XML or does not interpret it the way you would prefer. Text output is also used when the result will be sent to a terminal or post processed in a Unix pipeline.

Many recipes in this section place stress on XSLT techniques that create very generic XML to text converters. Here generic means that the transformation can easily be customized to work on many different XML inputs or produce a variety of outputs or both. The techniques employed in these recipes have application beyond specifics of a given recipe and often beyond the domain of text processing. In particular, you may want to look at recipes 7.2 through 7.5 even if they do not address a present need.

Обсуждение

Во многих задачах преобразования текста выходное устройство не поддержива­ет строки произвольной длины. Например, терминал переносит строки, которые шире экрана. В результате вывод получается некрасивым. В этом рецепте показано, как можно выполнять форматирование в области фиксированной ширины более осмысленно.

Преобразование XML в XML – Введение

Одно из достоинств XML заключается в том, что если какой-то документ вам не нравится, его можно изменить. Поскольку всем понравиться невозможно, то задача преобразования XML в XML возникает очень часто. Однако преоб­разовывать XML-документы приходится не только для того, чтобы исправить плохо продуманную структуру. Иногда нужно объединить несколько разно­родных документов в один. А иногда разбить большой документ на несколько частей. Бывает так, что из документа необходимо выделить интересующую информацию, не меняя его структуры, а затем отправить результат на даль­нейшую обработку.

Простой, но весьма важный инструмент, встречающийся во многих преобра­зованиях XML в XML, – это тождественное преобразование. Так называется таб­лица стилей, которая копирует входной документ в выходной без изменения. Воз­можно, вам кажется, что эта задача больше подходит для утилиты копирования операционной системы, но, как будет ясно из следующих примеров, такую табли­цу стилей можно импортировать в другие таблицы, чтобы реализовать распрост­раненные преобразования без дополнительных усилий.

В примере 1 приведена тождественная таблица стилей. Лично мне больше нравится называть ее копирующей таблицей, а технику ее использования я назы­ваю идиомой переопределяемого копирования.

Пример 8.1. copy.xslt

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="node() | @*"> <xsl:copy>

<xsl:apply-templates select="@* | node()"/> </xsl:copy>

</xsl:template>

Мангано Сэл  XSLT. Сборник рецептов. – М.: ДМК Пресс, СПБ.: БХВ-Петербург, 2008. – 864 с.: ил.

По теме:

  • Комментарии