如何更改fo:*元素中的属性

时间:2018-09-11 06:43:12

标签: xml xslt xsl-fo

我想将xml文件转换为xsl-fo以生成pdf文件。我的问题是某些属性将从输入xml中获取,例如:

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

,我想在其中加入with和height属性:      代替页面宽度和页面高度属性值。我使用xsl变量尝试了一些失败的方法:

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

或xsl:value-of

<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 :(得分:2)

您可以使用以下示例的代码来完成此操作:

    <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>

答案 1 :(得分:2)

您可以使用属性值模板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">

答案 2 :(得分:0)

在没有看到更多代码的情况下(到目前为止,您已经编写了示例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>

现在,由于其他原因,您实际上可能需要width和height的值,也许在其他模板之外需要此模板。假设您只有一个<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>