Как изменить атрибуты в элементах fo: * - PullRequest
0 голосов
/ 11 сентября 2018

Я хотел бы преобразовать xml-файл в xsl-fo для создания pdf-файла. Моя проблема заключается в том, что некоторые атрибуты должны быть взяты из входного XML, например:

 <page width="210mm" height="297mm" />

и я хотел бы добавить с атрибутами и height внутри: вместо значений атрибутов ширины страницы и высоты страницы. Я безуспешно пробовал несколько способов, используя переменную xsl:

<fo:simple-page-master master-name="pageMaster"
page-height="$height" page-width="$with" margin="2cm">

или xsl: значение-из

<fo:simple-page-master master-name="pageMaster"
page-height=<xsl:value-of select="$height"/>
page-width=<xsl:value-of select="$with"/> margin="2cm"> 

Ничего из вышеперечисленного не дает никакого результата, поскольку процесс преобразования останавливается с ошибкой, указывающей на какую-то синтаксическую ошибку. В чем дело? Как я могу это сделать?

Ответы [ 3 ]

0 голосов
/ 11 сентября 2018

Вы можете использовать шаблоны значений атрибутов https://www.w3.org/TR/xslt-30/#attribute-value-templates для вычисления значений литеральных элементов результата из выражений XPath (например, ссылки на переменную): <fo:simple-page-master master-name="pageMaster" page-height="{$height}" page-width="{$with}" margin="2cm">

0 голосов
/ 15 сентября 2018

Не видя больше кода (и пример XML, и XSL, который вы написали), догадаться нелегко. Вы не даете никакого контекста, в котором вы будете создавать мастера страниц.

Давайте предположим, что ваш корневой элемент <document>, а элемент <page> является дочерним для этого элемента, и у вас есть только один элемент <page>. Как это:

<document>
   <page width="210mm" height="297mm" />
   <!-- more things here -->
</document>

Тогда в вашем XSL вы можете получить это значение несколькими способами:

Вариант 1: просто используйте атрибут

<xsl:template match="document">
    <fo:root>
        <fo:layout-master-set>
            <fo:simple-page-master master-name="pageMaster" page-height="{page/@height}" page-width="{page/@width}">
                <fo:region-body />
            </fo:simple-page-master>
        </fo:layout-master-set>
        <fo:page-sequence master-reference="pageMaster">
            <fo:flow flow-name="xsl-region-body">
                <xsl:apply-templates/>
            </fo:flow>
        </fo:page-sequence>
    </fo:root>
</xsl:template>

Вариант 2: использовать переменные

<xsl:template match="document">
    <xsl:variable name="width" select="page/@width"/>
    <xsl:variable name="height" select="page/@height"/>
    <fo:root>
        <fo:layout-master-set>
            <fo:simple-page-master master-name="pageMaster" page-height="{$height}" page-width="{$width}">
                <fo:region-body />
            </fo:simple-page-master>
        </fo:layout-master-set>
        <fo:page-sequence master-reference="pageMaster">
            <fo:flow flow-name="xsl-region-body">
                <xsl:apply-templates/>
            </fo:flow>
        </fo:page-sequence>
    </fo:root>
</xsl:template>

Вариант 3: Использовать шаблон атрибута с атрибутом напрямую

<xsl:template match="document">
    <fo:root>
        <fo:layout-master-set>
            <fo:simple-page-master master-name="pageMaster">
                <xsl:attribute name="page-width">
                    <xsl:value-of select="page/@width"/>
                </xsl:attribute>
                <xsl:attribute name="page-height">
                    <xsl:value-of select="page/@height"/>
                </xsl:attribute>
                <fo:region-body />
            </fo:simple-page-master>
        </fo:layout-master-set>
        <fo:page-sequence master-reference="pageMaster">
            <fo:flow flow-name="xsl-region-body">
                <xsl:apply-templates/>
            </fo:flow>
        </fo:page-sequence>
    </fo:root>
</xsl:template>

Вариант 4. Использование шаблонов атрибутов с переменными

<xsl:template match="document">
    <xsl:variable name="width" select="page/@width"/>
    <xsl:variable name="height" select="page/@height"/>
    <fo:root>
        <fo:layout-master-set>
            <fo:simple-page-master master-name="pageMaster">
                <xsl:attribute name="page-width">
                    <xsl:value-of select="$width"/>
                </xsl:attribute>
                <xsl:attribute name="page-height">
                    <xsl:value-of select="$height"/>
                </xsl:attribute>
                <fo:region-body />
            </fo:simple-page-master>
        </fo:layout-master-set>
        <fo:page-sequence master-reference="pageMaster">
            <fo:flow flow-name="xsl-region-body">
                <xsl:apply-templates/>
            </fo:flow>
        </fo:page-sequence>
    </fo:root>
</xsl:template>

Теперь вам могут понадобиться значения ширины и высоты по другим причинам, возможно, за пределами этого шаблона в другом. Предполагая, что у вас есть только один элемент <page>, вы можете сделать это, когда переменные будут доступны во всем XSL, определив их в корне перед любыми шаблонами:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fo="http://www.w3.org/1999/XSL/Format" 
    version="2.0">
    <xsl:variable name="width" select="/document/page/@width"/>
    <xsl:variable name="height" select="/document/page/@height"/>

    <xsl:template match="document">
        <fo:root>
            <fo:layout-master-set>
                <fo:simple-page-master master-name="pageMaster" page-height="{$height}" page-width="{$width}">
                    <fo:region-body />
                </fo:simple-page-master>
            </fo:layout-master-set>
            <fo:page-sequence master-reference="pageMaster">
                <fo:flow flow-name="xsl-region-body">
                    <xsl:apply-templates/>
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>

</xsl:stylesheet>
0 голосов
/ 11 сентября 2018

Вы можете сделать это с помощью кода, как в следующем примере:

    <fo:simple-page-master master-name="pageMaster" margin="2cm">
      <xsl:attribute name="page-width">
        <xsl:value-of select="$width"/>
      </xsl:attribute>
      <xsl:attribute name="page-height">
        <xsl:value-of select="$height"/>
      </xsl:attribute>
    </fo:simple-page-master>
...