XSL: FO: повторение одной строки таблицы в цикле - PullRequest
0 голосов
/ 27 августа 2018

Я нахожусь на пути создания ярлыков через XSL: FO.На этикетках будет один и тот же текст.Таким образом, моя страница PDF состоит из таблицы с просто n-раз одинаковыми строками, пока страница не заканчивается:

<fo:table-row>
  <fo:table-cell>
   <fo:block>
    <xsl:value-of select = "foo"/>
   </fo:block>
  </fo:table-cell>
  <fo:table-cell>
   <fo:block>
    <xsl:value-of select = "bar"/>
   </fo:block>
  </fo:table-cell>
</fo:table-row>

Я не хочу копировать и вставлять код n-раз, чтобы заполнить страницу.Я попытался сделать что-то вроде цикла, который добавляет n-кратную строку.

Я нашел эту конструкцию:

<xsl:for-each select="1 to 20">..</xsl:for-each>

Не работает, но выдает ошибку.

Любой простой способ зацикливания в XSL: FO?

Заранее спасибо.

1 Ответ

0 голосов
/ 27 августа 2018

Как сказал @ martin-honnen несколько минут назад, но с кодом:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fo="http://www.w3.org/1999/XSL/Format"
    exclude-result-prefixes="xs" version="2.0">
    <xsl:variable name="root" select="/" />
    <xsl:template match="/">
        <xsl:for-each select="1 to 10">
            <xsl:for-each select="$root">
                <fo:table-row>
                    <fo:table-cell>
                        <fo:block>
                            <xsl:value-of select="foo" />
                        </fo:block>
                    </fo:table-cell>
                    <fo:table-cell>
                        <fo:block>
                            <xsl:value-of select="bar" />
                        </fo:block>
                    </fo:table-cell>
                </fo:table-row>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Внутри <xsl:for-each select="1 to 10"> контекст является текущим целочисленным значением 1 to 10, и вы не можете выбирать узлы относительно целого числа. Вам необходимо восстановить контекст, создав переменную для того, что было текущим узлом, и использовать эту переменную либо во внутренних xsl:for-each (как указано выше), либо в ваших select атрибутах. Что лучше, во многом зависит от личных предпочтений, которые могут сводиться к тому, сколько раз вам пришлось бы повторять ссылку на переменную в select атрибутах.


Если вы застряли с использованием XSLT 1.0, xsl:for-each должен иметь возможность выбрать достаточно узлов (из любого места, действительно), чтобы иметь возможность повторять нужное количество раз:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fo="http://www.w3.org/1999/XSL/Format"
    exclude-result-prefixes="xs" version="1.0">
    <xsl:variable name="document" select="/*" />
    <xsl:template match="/*">
        <xsl:for-each select="(//node())[position() &lt;= 10]">
            <xsl:for-each select="$document">
                <fo:table-row>
                    <fo:table-cell>
                        <fo:block>
                            <xsl:value-of select="foo" />
                        </fo:block>
                    </fo:table-cell>
                    <fo:table-cell>
                        <fo:block>
                            <xsl:value-of select="bar" />
                        </fo:block>
                    </fo:table-cell>
                </fo:table-row>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Однако, IMO, было бы лучше вместо этого забыть о xsl:for-each и т. Д. И сделать это рекурсивно:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fo="http://www.w3.org/1999/XSL/Format"
    exclude-result-prefixes="xs" version="1.0">
    <xsl:template match="/*" name="row">
        <xsl:param name="count" select="1" />
        <fo:table-row>
            <fo:table-cell>
                <fo:block>
                    <xsl:value-of select="foo" />
                </fo:block>
            </fo:table-cell>
            <fo:table-cell>
                <fo:block>
                    <xsl:value-of select="bar" />
                </fo:block>
            </fo:table-cell>
        </fo:table-row>
        <xsl:if test="$count &lt; 10">
            <xsl:call-template name="row">
                <xsl:with-param name="count" select="$count + 1" />
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>
...