我有以下XML:
<sample>
<value1>This is one</value1>
<value2>Number two</value2>
<value4>Last value</value4>
</sample>
使用Apache FOP / XSL-FO我希望PDF看起来与此类似:
Value 1: This is one Value 2: Number two
Value 3: Value 4: Last value
注意“值3:”和“值4:”之间的间距/填充。
以下转换给出了我想要的结果。但它似乎过于复杂(对于具有许多值的真实PDF,可能效果不佳)。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="sample">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="page-layout">
<fo:region-body margin="10mm" region-name="body"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="page-layout">
<fo:flow flow-name="body">
<fo:block>
<xsl:variable name="pad">
<xsl:choose>
<xsl:when test="value1">5</xsl:when>
<xsl:otherwise>25</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<fo:inline padding-right="{$pad}mm">Value 1: <xsl:value-of select="value1"/></fo:inline>
Value 2: <xsl:value-of select="value2"/>
</fo:block>
<fo:block>
<xsl:variable name="pad">
<xsl:choose>
<xsl:when test="value3">5</xsl:when>
<xsl:otherwise>25</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<fo:inline padding-right="{$pad}mm">Value 3: <xsl:value-of select="value3"/></fo:inline>
Value 4: <xsl:value-of select="value4"/>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
是否有更简单/更好的方法来实现它?
更新
我将上述内容重构为模板“字段”:
<xsl:template name="field">
<xsl:param name="txt"/>
<xsl:param name="val"/>
<xsl:param name="pad"/>
<xsl:variable name="p">
<xsl:choose>
<xsl:when test="$val">5</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$pad"><xsl:value-of select="$pad"/></xsl:when>
<xsl:otherwise>25</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<fo:inline padding-right="{$p}mm"><xsl:value-of select="$txt"/>:</fo:inline>
<fo:inline keep-with-previous="always" padding-right="5mm" font-weight="bold"><xsl:value-of select="$val"/></fo:inline>
</xsl:template>
可以这样使用:
<xsl:call-template name="field">
<xsl:with-param name="txt">Value 1</xsl:with-param>
<xsl:with-param name="val"><xsl:value-of select="sample/value1"/></xsl:with-param>
</xsl:call-template>
模板采用第三个可选参数pad。如果指定,其值将用作填充。
David的模板(参见接受的答案)使用更简单的if-contruct,如果需要,覆盖padding-right属性。
答案 0 :(得分:2)
由于这可能不是在浏览器中执行,因此有任何理由不使用xslt2(这会使它更好)因为你使用java无论如何免费的saxon 9实现在这里都能正常工作。
但是这里有一个XSLT 1版本重构了一点。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="sample">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="page-layout">
<fo:region-body margin="10mm" region-name="body"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="page-layout">
<fo:flow flow-name="body">
<xsl:call-template name="twoval">
<xsl:with-param name="a" select="value1"/>
<xsl:with-param name="ahead" select="'Value 1'"/>
<xsl:with-param name="b" select="value2"/>
<xsl:with-param name="bhead" select="'Value 2'"/>
</xsl:call-template>
<xsl:call-template name="twoval">
<xsl:with-param name="a" select="value3"/>
<xsl:with-param name="ahead" select="'Value 3'"/>
<xsl:with-param name="b" select="value4"/>
<xsl:with-param name="bhead" select="'Value 4'"/>
</xsl:call-template>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template name="twoval">
<xsl:param name="a"/>
<xsl:param name="ahead"/>
<xsl:param name="b"/>
<xsl:param name="bhead"/>
<fo:block>
<fo:inline padding-right="25mm">
<xsl:if test="$a"><xsl:attribute name="padding-right">5mm</xsl:attribute></xsl:if>
<xsl:value-of select="$ahead"/><xsl:text>: </xsl:text>
<xsl:value-of select="$a"/>
</fo:inline>
<xsl:text> </xsl:text>
<xsl:value-of select="$bhead"/><xsl:text>: </xsl:text>
<xsl:value-of select="$b"/>
</fo:block>
</xsl:template>
</xsl:stylesheet>